Format QML files

This commit is contained in:
Alexandre Jörgensen 2026-03-10 12:32:35 +01:00
parent ae75e5eff9
commit c73eea248f
180 changed files with 16325 additions and 16134 deletions

View file

@ -9,10 +9,10 @@ Button {
id: mainItem
textSize: Typography.b1.pixelSize
textWeight: Typography.b1.weight
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(11)
bottomPadding: Utils.getSizeWithScreenRatio(11)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(11)
bottomPadding: Utils.getSizeWithScreenRatio(11)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
}

View file

@ -5,39 +5,33 @@ import QtQuick.Layouts
import QtQml
import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.Button {
id: mainItem
property var style
property bool asynchronous: false
property bool asynchronous: false
hoverEnabled: enabled
activeFocusOnTab: true
property color disabledFilterColor: color.hslLightness > 0.5
? DefaultStyle.grey_0
: DefaultStyle.grey_400
property color disabledFilterColor: color.hslLightness > 0.5 ? DefaultStyle.grey_0 : DefaultStyle.grey_400
property bool hasNavigationFocus: enabled && (activeFocus || hovered)
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
property color color: style?.color?.normal || DefaultStyle.main1_500_main
property color hoveredColor: style?.color?.hovered || Qt.darker(color, 1.05)
property color pressedColor: style?.color?.pressed || Qt.darker(color, 1.1)
property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1)
property color pressedColor: style?.color?.pressed || Qt.darker(color, 1.1)
property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1)
property bool shadowEnabled: false
property int capitalization
property color backgroundColor: mainItem.checkable && mainItem.checked
? mainItem.checkedColor || mainItem.pressedColor
: mainItem.pressed
? mainItem.pressedColor
: mainItem.hovered
? mainItem.hoveredColor
: mainItem.color
property color backgroundColor: mainItem.checkable && mainItem.checked ? mainItem.checkedColor
|| mainItem.pressedColor : mainItem.pressed ? mainItem.pressedColor : mainItem.hovered
? mainItem.hoveredColor : mainItem.color
// Text properties
property bool underline: false
property real textSize: Utils.getSizeWithScreenRatio(18)
property real textWeight: Typography.b1.weight
property color textColor: style?.text?.normal || DefaultStyle.grey_0
property real textSize: Utils.getSizeWithScreenRatio(18)
property real textWeight: Typography.b1.weight
property color textColor: style?.text?.normal || DefaultStyle.grey_0
property color hoveredTextColor: style?.text?.hovered || Qt.darker(textColor, 1.05)
property color pressedTextColor: style?.text?.pressed || Qt.darker(textColor, 1.1)
property var textFormat: Text.AutoText
@ -51,21 +45,19 @@ Control.Button {
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Image properties
property var contentImageColor: style?.image? style.image.normal : DefaultStyle.main2_600
property var hoveredImageColor: style && style.image && style.image.hovered ? style.image.hovered : Qt.darker(contentImageColor, 1.05)
property var checkedImageColor: style && style.image && style.image.checked ? style.image.checked : Qt.darker(contentImageColor, 1.1)
property var pressedImageColor: style && style.image && style.image.pressed ? style.image.pressed : Qt.darker(contentImageColor, 1.1)
property var contentImageColor: style?.image ? style.image.normal : DefaultStyle.main2_600
property var hoveredImageColor: style && style.image && style.image.hovered ? style.image.hovered : Qt.darker(
contentImageColor, 1.05)
property var checkedImageColor: style && style.image && style.image.checked ? style.image.checked : Qt.darker(
contentImageColor, 1.1)
property var pressedImageColor: style && style.image && style.image.pressed ? style.image.pressed : Qt.darker(
contentImageColor, 1.1)
icon.source: style?.iconSource || ""
property color colorizationColor: checkable && checked
? checkedImageColor
: pressed
? pressedImageColor
: hovered
? hoveredImageColor
: contentImageColor
property color colorizationColor: checkable && checked ? checkedImageColor : pressed ? pressedImageColor : hovered
? hoveredImageColor : contentImageColor
// Size properties
spacing: Utils.getSizeWithScreenRatio(5)
property real radius: Math.ceil(height / 2)
property real radius: Math.ceil(height / 2)
MouseArea {
id: mouseArea
@ -75,27 +67,27 @@ Control.Button {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton
}
background: Loader{
background: Loader {
asynchronous: mainItem.asynchronous
anchors.fill: parent
sourceComponent: Item {
width: mainItem.width
height: mainItem.height
Rectangle {
id: buttonBackground
anchors.fill: parent
color: mainItem.backgroundColor
color: mainItem.backgroundColor
radius: mainItem.radius
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: buttonBackground
source: buttonBackground
visible: mainItem.shadowEnabled
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
@ -116,7 +108,7 @@ Control.Button {
width: mainItem.width
height: mainItem.height
}
component ButtonText: Text {
id: buttonText
horizontalAlignment: mainItem.textHAlignment
@ -126,18 +118,16 @@ Control.Button {
text: mainItem.text
textFormat: mainItem.textFormat
maximumLineCount: 1
color: mainItem.checkable && mainItem.checked || mainItem.pressed
? mainItem.pressedTextColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
color: mainItem.checkable && mainItem.checked || mainItem.pressed ? mainItem.pressedTextColor : mainItem.hovered
? mainItem.hoveredTextColor : mainItem.textColor
font {
pixelSize: mainItem.textSize
weight: mainItem.textWeight
family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization
underline: mainItem.underline
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed)
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (
mainItem.hovered || mainItem.pressed)
}
ToolTip {
parent: mainItem
@ -151,46 +141,51 @@ Control.Button {
font.bold: true
}
}
component ButtonImage: EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.colorizationColor
colorizationColor: mainItem.colorizationColor
}
contentItem: Control.StackView{
contentItem: Control.StackView {
id: stacklayout
function updateComponent(){
var item
var component = mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0
? imageTextComponent
: mainItem.text.length != 0
? textComponent
: mainItem.icon.source.toString().length != 0
? imageComponent
: emptyComponent
if( stacklayout.depth == 0)
item = stacklayout.push(component, Control.StackView.Immediate)
else if( component != stacklayout.get(0))
item = stacklayout.replace(component, Control.StackView.Immediate)
if(item){// Workaround for Qt bug : set from the item and not from the contentItem which seems to be lost
implicitHeight = Qt.binding(function() { return item.implicitHeight})
implicitWidth = Qt.binding(function() { return item.implicitWidth})
function updateComponent() {
var item;
var component = mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0 ? imageTextComponent :
mainItem.text.length != 0 ? textComponent : mainItem.icon.source.toString().length != 0
? imageComponent : emptyComponent;
if (stacklayout.depth == 0)
item = stacklayout.push(component, Control.StackView.Immediate);
else if (component != stacklayout.get(0))
item = stacklayout.replace(component, Control.StackView.Immediate);
if (item) {
// Workaround for Qt bug : set from the item and not from the contentItem which seems to be lost
implicitHeight = Qt.binding(function () {
return item.implicitHeight;
});
implicitWidth = Qt.binding(function () {
return item.implicitWidth;
});
}
}
Component.onCompleted: {
updateComponent()
updateComponent();
}
Connections{
Connections {
target: mainItem
function onTextChanged(){stacklayout.updateComponent()}
function onIconChanged(){stacklayout.updateComponent()}
function onTextChanged() {
stacklayout.updateComponent();
}
function onIconChanged() {
stacklayout.updateComponent();
}
}
Component{
Component {
id: imageTextComponent
// Workaround for centering the content when its
// width is smaller than the button width
@ -201,25 +196,26 @@ Control.Button {
id: content
spacing: mainItem.spacing
anchors.centerIn: parent
ButtonImage{
ButtonImage {
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
ButtonText {
}
ButtonText {}
}
}
}
Component{
Component {
id: textComponent
ButtonText {
width: stacklayout.width
height: stacklayout.height
// Hack for StackView binding loop
onImplicitHeightChanged: {implicitHeight}
onImplicitHeightChanged: {
implicitHeight;
}
}
}
Component{
Component {
id: imageComponent
Item {
width: stacklayout.width
@ -237,7 +233,7 @@ Control.Button {
}
}
}
Component{
Component {
id: emptyComponent
Item {
width: stacklayout.width
@ -247,29 +243,29 @@ Control.Button {
}
/*
contentItem: StackLayout {
id: stacklayout
currentIndex: mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0
? 0
: mainItem.text.length != 0
? 1
: mainItem.icon.source.toString().length != 0
? 2
: 3
width: mainItem.width
RowLayout {
spacing: mainItem.spacing
ButtonImage{
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
ButtonText{}
}
ButtonText {}
ButtonImage{}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
id: stacklayout
currentIndex: mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0
? 0
: mainItem.text.length != 0
? 1
: mainItem.icon.source.toString().length != 0
? 2
: 3
width: mainItem.width
RowLayout {
spacing: mainItem.spacing
ButtonImage{
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
ButtonText{}
}
ButtonText {}
ButtonImage{}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
}*/
}

View file

@ -16,24 +16,24 @@ ComboBox {
id: contentText
text: calendar.selectedDate ? UtilsCpp.formatDate(calendar.selectedDate, false, true, "ddd d, MMMM") : ""
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(15)
anchors.leftMargin: Utils.getSizeWithScreenRatio(15)
anchors.verticalCenter: parent.verticalCenter
verticalAlignment: Text.AlignVCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Font.Bold
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Font.Bold
}
}
popup: Control.Popup {
id: popupItem
y: mainItem.height
width: Utils.getSizeWithScreenRatio(321)
height: Utils.getSizeWithScreenRatio(270)
width: Utils.getSizeWithScreenRatio(321)
height: Utils.getSizeWithScreenRatio(270)
closePolicy: Popup.NoAutoClose
topPadding: Utils.getSizeWithScreenRatio(25)
bottomPadding: Utils.getSizeWithScreenRatio(24)
leftPadding: Utils.getSizeWithScreenRatio(21)
rightPadding: Utils.getSizeWithScreenRatio(19)
topPadding: Utils.getSizeWithScreenRatio(25)
bottomPadding: Utils.getSizeWithScreenRatio(24)
leftPadding: Utils.getSizeWithScreenRatio(21)
rightPadding: Utils.getSizeWithScreenRatio(19)
onOpened: calendar.forceActiveFocus()
background: Item {
anchors.fill: parent
@ -41,9 +41,9 @@ ComboBox {
id: calendarBg
anchors.fill: parent
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(16)
radius: Utils.getSizeWithScreenRatio(16)
border.color: DefaultStyle.main1_500_main
border.width: calendar.activeFocus? 1 : 0
border.width: calendar.activeFocus ? 1 : 0
}
MultiEffect {
anchors.fill: calendarBg

View file

@ -7,17 +7,17 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.CheckBox {
id: mainItem
hoverEnabled: enabled
indicator: Item{
implicitWidth: Utils.getSizeWithScreenRatio(20)
implicitHeight: Utils.getSizeWithScreenRatio(20)
indicator: Item {
implicitWidth: Utils.getSizeWithScreenRatio(20)
implicitHeight: Utils.getSizeWithScreenRatio(20)
x: (parent.width - width) / 2
y: (parent.height - height) / 2
Rectangle {
id: backgroundArea
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(3)
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(3)
border.color: mainItem.hovered || mainItem.activeFocus ? DefaultStyle.main1_600 : DefaultStyle.main1_500_main
border.width: Utils.getSizeWithScreenRatio(2)
border.width: Utils.getSizeWithScreenRatio(2)
color: mainItem.checked ? DefaultStyle.main1_500_main : "transparent"
EffectImage {
visible: mainItem.checked

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Controls.Basic as Control
import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Button {
id: mainItem
@ -14,11 +14,7 @@ Button {
color: style?.color?.normal || DefaultStyle.grey_500
pressedColor: checkedIconUrl ? color : style?.color?.pressed || DefaultStyle.grey_500
hoveredColor: checked ? Qt.darker(pressedColor, 1.05) : style?.color?.hovered || DefaultStyle.grey_500
property color backgroundColor: hovered
? hoveredColor
: checked
? pressedColor
: color
property color backgroundColor: hovered ? hoveredColor : checked ? pressedColor : color
checkable: true
Accessible.role: Accessible.Button
icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl

View file

@ -7,264 +7,272 @@ import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ComboBox {
id: mainItem
// Usage : each item of the model list must be {text: , img: }
// If string list, only text part of the delegate will be filled
// readonly property string currentText: selectedItemText.text
property alias listView: listView
property string constantImageSource
property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight
property real leftMargin: Utils.getSizeWithScreenRatio(10)
property bool oneLine: false
property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered
property string flagRole // Specific case if flag is shown (special font)
property var indicatorColor: DefaultStyle.main2_600
property int indicatorRightMargin: Utils.getSizeWithScreenRatio(20)
leftPadding: Utils.getSizeWithScreenRatio(10)
rightPadding: indicImage.width + indicatorRightMargin
property bool keyboardFocus: FocusHelper.keyboardFocus
// Text properties
property color textColor: DefaultStyle.main2_600
property color disabledTextColor: DefaultStyle.grey_400
// Border properties
property color borderColor: DefaultStyle.grey_200
property color disabledBorderColor: DefaultStyle.grey_400
property color activeFocusedBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Background properties
property color color: DefaultStyle.grey_100
property color disabledColor: DefaultStyle.grey_200
id: mainItem
// Usage : each item of the model list must be {text: , img: }
// If string list, only text part of the delegate will be filled
// readonly property string currentText: selectedItemText.text
property alias listView: listView
property string constantImageSource
property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight
property real leftMargin: Utils.getSizeWithScreenRatio(10)
property bool oneLine: false
property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered
property string flagRole // Specific case if flag is shown (special font)
property var indicatorColor: DefaultStyle.main2_600
property int indicatorRightMargin: Utils.getSizeWithScreenRatio(20)
leftPadding: Utils.getSizeWithScreenRatio(10)
rightPadding: indicImage.width + indicatorRightMargin
property bool keyboardFocus: FocusHelper.keyboardFocus
// Text properties
property color textColor: DefaultStyle.main2_600
property color disabledTextColor: DefaultStyle.grey_400
// Border properties
property color borderColor: DefaultStyle.grey_200
property color disabledBorderColor: DefaultStyle.grey_400
property color activeFocusedBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Background properties
property color color: DefaultStyle.grey_100
property color disabledColor: DefaultStyle.grey_200
onConstantImageSourceChanged: if (constantImageSource)
selectedItemImg.imageSource = constantImageSource
onCurrentIndexChanged: {
var item = model[currentIndex];
if (!item)
item = model.getAt(currentIndex);
if (!item)
return;
selectedItemText.text = mainItem.textRole ? item[mainItem.textRole] : item.text ? item.text : item ? item : "";
if (mainItem.flagRole)
selectedItemFlag.text = item[mainItem.flagRole];
selectedItemImg.imageSource = constantImageSource ? constantImageSource : item.img ? item.img : "";
}
onConstantImageSourceChanged: if (constantImageSource)
selectedItemImg.imageSource = constantImageSource
onCurrentIndexChanged: {
var item = model[currentIndex];
if (!item)
item = model.getAt(currentIndex);
if (!item)
return;
selectedItemText.text = mainItem.textRole ? item[mainItem.textRole] : item.text ? item.text : item ? item : "";
if (mainItem.flagRole)
selectedItemFlag.text = item[mainItem.flagRole];
selectedItemImg.imageSource = constantImageSource ? constantImageSource : item.img ? item.img : "";
}
Keys.onPressed: event => {
if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) {
mainItem.popup.open();
event.accepted = true;
}
}
Keys.onPressed: event => {
if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key
== Qt.Key_Return)) {
mainItem.popup.open();
event.accepted = true;
}
}
background: Item {
Rectangle {
id: buttonBackground
anchors.fill: parent
radius: Math.round(mainItem.height / 2)
color: mainItem.enabled ? mainItem.color : mainItem.disabledColor
border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened ? mainItem.activeFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: buttonBackground
source: buttonBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.5
shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0
}
}
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(5)
EffectImage {
id: selectedItemImg
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(24) : 0
Layout.preferredHeight: visible ? Utils.getSizeWithScreenRatio(24) : 0
Layout.leftMargin: mainItem.leftMargin
imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : ""
colorizationColor: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
visible: imageSource != ""
fillMode: Image.PreserveAspectFit
}
Text {
id: selectedItemFlag
Layout.preferredWidth: implicitWidth
Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
}
Text {
id: selectedItemText
Layout.fillWidth: true
Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.alignment: Qt.AlignCenter
color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
elide: Text.ElideRight
maximumLineCount: oneLine ? 1 : 2
wrapMode: Text.WrapAnywhere
font {
family: DefaultStyle.defaultFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
}
}
background: Item {
Rectangle {
id: buttonBackground
anchors.fill: parent
radius: Math.round(mainItem.height / 2)
color: mainItem.enabled ? mainItem.color : mainItem.disabledColor
border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened
? mainItem.activeFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: buttonBackground
source: buttonBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.5
shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0
}
}
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(5)
EffectImage {
id: selectedItemImg
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(24) : 0
Layout.preferredHeight: visible ? Utils.getSizeWithScreenRatio(24) : 0
Layout.leftMargin: mainItem.leftMargin
imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : ""
colorizationColor: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
visible: imageSource != ""
fillMode: Image.PreserveAspectFit
}
Text {
id: selectedItemFlag
Layout.preferredWidth: implicitWidth
Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
}
Text {
id: selectedItemText
Layout.fillWidth: true
Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.alignment: Qt.AlignCenter
color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
elide: Text.ElideRight
maximumLineCount: oneLine ? 1 : 2
wrapMode: Text.WrapAnywhere
font {
family: DefaultStyle.defaultFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
}
}
indicator: EffectImage {
id: indicImage
z: 1
anchors.right: parent.right
anchors.rightMargin: mainItem.indicatorRightMargin
anchors.verticalCenter: parent.verticalCenter
imageSource: AppIcons.downArrow
width: Utils.getSizeWithScreenRatio(15)
height: Utils.getSizeWithScreenRatio(15)
fillMode: Image.PreserveAspectFit
colorizationColor: mainItem.indicatorColor
// Rotate when popup open/close
transformOrigin: Item.Center
rotation: mainItem.popup.opened ? 180 : 0
Behavior on rotation {
NumberAnimation {
duration: 200
easing.type: Easing.InOutQuad
}
}
}
indicator: EffectImage {
id: indicImage
z: 1
anchors.right: parent.right
anchors.rightMargin: mainItem.indicatorRightMargin
anchors.verticalCenter: parent.verticalCenter
imageSource: AppIcons.downArrow
width: Utils.getSizeWithScreenRatio(15)
height: Utils.getSizeWithScreenRatio(15)
fillMode: Image.PreserveAspectFit
colorizationColor: mainItem.indicatorColor
// Rotate when popup open/close
transformOrigin: Item.Center
rotation: mainItem.popup.opened ? 180 : 0
Behavior on rotation {
NumberAnimation {
duration: 200
easing.type: Easing.InOutQuad
}
}
}
popup: Control.Popup {
id: popup
y: mainItem.height - 1
width: mainItem.width
implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height)
padding: Utils.getSizeWithScreenRatio(1)
popup: Control.Popup {
id: popup
y: mainItem.height - 1
width: mainItem.width
implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height)
padding: Utils.getSizeWithScreenRatio(1)
onOpened: {
listView.positionViewAtIndex(listView.currentIndex, ListView.Center);
listView.forceActiveFocus();
}
contentItem: ListView {
id: listView
clip: true
implicitHeight: contentHeight
height: popup.height
model: visible ? mainItem.model : []
currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0
highlightFollowsCurrentItem: true
highlightMoveDuration: -1
highlightMoveVelocity: -1
highlight: Rectangle {
width: listView.width
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
y: listView.currentItem ? listView.currentItem.y : 0
}
onOpened: {
listView.positionViewAtIndex(listView.currentIndex, ListView.Center);
listView.forceActiveFocus();
}
contentItem: ListView {
id: listView
clip: true
implicitHeight: contentHeight
height: popup.height
model: visible ? mainItem.model : []
currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0
highlightFollowsCurrentItem: true
highlightMoveDuration: -1
highlightMoveVelocity: -1
highlight: Rectangle {
width: listView.width
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
y: listView.currentItem ? listView.currentItem.y : 0
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
event.accepted = true;
mainItem.currentIndex = listView.currentIndex;
popup.close();
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
event.accepted = true;
mainItem.currentIndex = listView.currentIndex;
popup.close();
}
}
delegate: Item {
width: mainItem.width
height: mainItem.height
// anchors.left: listView.left
// anchors.right: listView.right
Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : ""
RowLayout {
anchors.fill: parent
EffectImage {
id: delegateImg
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(20) : 0
Layout.leftMargin: Utils.getSizeWithScreenRatio(10)
visible: imageSource != ""
imageWidth: Utils.getSizeWithScreenRatio(20)
imageSource: typeof (modelData) != "undefined" && modelData.img ? modelData.img : ""
fillMode: Image.PreserveAspectFit
}
delegate: Item {
width: mainItem.width
height: mainItem.height
// anchors.left: listView.left
// anchors.right: listView.right
Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text
? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] :
$modelData : ""
RowLayout {
anchors.fill: parent
EffectImage {
id: delegateImg
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(20) : 0
Layout.leftMargin: Utils.getSizeWithScreenRatio(10)
visible: imageSource != ""
imageWidth: Utils.getSizeWithScreenRatio(20)
imageSource: typeof (modelData) != "undefined" && modelData.img ? modelData.img : ""
fillMode: Image.PreserveAspectFit
}
Text {
id: flagItem
Layout.preferredWidth: implicitWidth
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
visible: mainItem.flagRole
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] : $modelData[mainItem.flagRole] : ""
}
Text {
Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.alignment: Qt.AlignCenter
text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : ""
elide: Text.ElideRight
maximumLineCount: 1
wrapMode: Text.WrapAnywhere
font {
family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(15)
weight: Font.Normal
}
}
}
Text {
id: flagItem
Layout.preferredWidth: implicitWidth
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
visible: mainItem.flagRole
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] :
$modelData[mainItem.flagRole] : ""
}
Text {
Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : Utils.getSizeWithScreenRatio(flagItem.visble ? 5 : 25)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.alignment: Qt.AlignCenter
text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text
? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] :
$modelData : ""
elide: Text.ElideRight
maximumLineCount: 1
wrapMode: Text.WrapAnywhere
font {
family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(15)
weight: Font.Normal
}
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
Rectangle {
anchors.fill: parent
opacity: 0.1
radius: Utils.getSizeWithScreenRatio(15)
color: DefaultStyle.main2_500_main
visible: parent.containsMouse
}
onClicked: {
mainItem.currentIndex = index;
popup.close();
}
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
Rectangle {
anchors.fill: parent
opacity: 0.1
radius: Utils.getSizeWithScreenRatio(15)
color: DefaultStyle.main2_500_main
visible: parent.containsMouse
}
onClicked: {
mainItem.currentIndex = index;
popup.close();
}
}
}
Control.ScrollIndicator.vertical: Control.ScrollIndicator {}
}
Control.ScrollIndicator.vertical: Control.ScrollIndicator {}
}
background: Item {
implicitWidth: mainItem.width
implicitHeight: Utils.getSizeWithScreenRatio(30)
Rectangle {
id: cboxBg
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(15)
}
MultiEffect {
anchors.fill: cboxBg
source: cboxBg
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: 0.1
}
}
}
background: Item {
implicitWidth: mainItem.width
implicitHeight: Utils.getSizeWithScreenRatio(30)
Rectangle {
id: cboxBg
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(15)
}
MultiEffect {
anchors.fill: cboxBg
source: cboxBg
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: 0.1
}
}
}
}

View file

@ -15,9 +15,11 @@ Control.ComboBox {
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
property string text: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1
Accessible.name: mainItem.Accessible.name
property string text: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(
combobox.currentIndex).countryCallingCode : ""
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(
defaultCallingCode)) : -1
Accessible.name: mainItem.Accessible.name
model: PhoneNumberProxy {
id: phoneNumberModel
}
@ -25,15 +27,10 @@ Control.ComboBox {
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63)
color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent"
border.color: mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor
: mainItem.enableBackgroundColors
? (mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: mainItem.activeFocus || textField.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200)
: "transparent"
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.enableBackgroundColors ? (
mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : mainItem.activeFocus
|| textField.activeFocus ? DefaultStyle.main1_500_main :
DefaultStyle.grey_200) : "transparent"
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
contentItem: RowLayout {
@ -86,7 +83,7 @@ Control.ComboBox {
fillMode: Image.PreserveAspectFit
colorizationColor: mainItem.indicatorColor
}
popup: Control.Popup {
id: listPopup
y: combobox.height - 1
@ -97,7 +94,7 @@ Control.ComboBox {
id: listView
clip: true
anchors.fill: parent
model: PhoneNumberProxy{}
model: PhoneNumberProxy {}
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
keyNavigationEnabled: true
keyNavigationWraps: true
@ -118,7 +115,7 @@ Control.ComboBox {
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(20)
spacing: Utils.getSizeWithScreenRatio(5)
Text {
id: delegateImg
visible: text.length > 0
@ -171,16 +168,16 @@ Control.ComboBox {
visible: parent.containsMouse
}
onClicked: {
combobox.currentIndex = index
listPopup.close()
combobox.currentIndex = index;
listPopup.close();
}
}
}
Control.ScrollIndicator.vertical: Control.ScrollIndicator { }
Control.ScrollIndicator.vertical: Control.ScrollIndicator {}
}
onOpened: {
listView.positionViewAtIndex(listView.currentIndex, ListView.Center)
listView.positionViewAtIndex(listView.currentIndex, ListView.Center);
}
background: Item {

View file

@ -3,14 +3,14 @@ import QtQuick.Effects
import QtQuick.Layouts
import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
MouseArea {
id: mainItem
property string iconSource
property string title
property string subTitle
property real iconSize: Utils.getSizeWithScreenRatio(32)
property real iconSize: Utils.getSizeWithScreenRatio(32)
property bool shadowEnabled: containsMouse || activeFocus
property bool arrowImageVisible: false
property alias image: image
@ -19,16 +19,16 @@ MouseArea {
height: content.implicitHeight
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
activeFocusOnTab: true
Keys.onPressed: (event) => {
if(event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return){
mainItem.clicked(undefined)
event.accepted = true
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
mainItem.clicked(undefined);
event.accepted = true;
}
}
RowLayout {
id: content
anchors.verticalCenter: parent.verticalCenter
anchors.fill:parent
anchors.fill: parent
EffectImage {
id: image
Layout.preferredWidth: mainItem.iconSize
@ -42,7 +42,7 @@ MouseArea {
width: implicitWidth
Layout.preferredWidth: width
height: implicitHeight
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Text {
Layout.fillWidth: true
maximumLineCount: 1
@ -63,7 +63,9 @@ MouseArea {
font: Typography.p1
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
EffectImage {
id: arrowImage
visible: mainItem.arrowImageVisible
@ -75,7 +77,7 @@ MouseArea {
enabled: mainItem.shadowEnabled
anchors.fill: content
source: content
visible: mainItem.shadowEnabled
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000

View file

@ -2,41 +2,35 @@ import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button {
id: mainItem
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5)
shadowEnabled: mainItem.activeFocus || hovered
style: ButtonStyle.hoveredBackground
background: Rectangle {
anchors.fill: parent
radius: mainItem.radius
color: mainItem.pressed
? mainItem.pressedColor
: mainItem.hovered || mainItem.hasNavigationFocus
? mainItem.hoveredColor
: mainItem.color
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
contentItem: EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed
? mainItem.pressedImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
background: Rectangle {
anchors.fill: parent
radius: mainItem.radius
color: mainItem.pressed ? mainItem.pressedColor : mainItem.hovered || mainItem.hasNavigationFocus ? mainItem.hoveredColor :
mainItem.color
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
contentItem: EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
}

View file

@ -2,33 +2,30 @@ import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button {
id: mainItem
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5)
shadowEnabled: mainItem.activeFocus || hovered
style: ButtonStyle.hoveredBackground
property bool inverseLayout: false
spacing: Utils.getSizeWithScreenRatio(5)
contentItem: RowLayout {
spacing: mainItem.spacing
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft: Qt.LeftToRight
spacing: mainItem.spacing
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft : Qt.LeftToRight
EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed
? mainItem.pressedImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height
}
@ -41,18 +38,15 @@ Button {
wrapMode: Text.WrapAnywhere
text: mainItem.text
maximumLineCount: 1
color: pressed
? mainItem.pressedTextColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
color: pressed ? mainItem.pressedTextColor : mainItem.hovered ? mainItem.hoveredTextColor : mainItem.textColor
font {
pixelSize: mainItem.textSize
weight: mainItem.textWeight
family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization
underline: mainItem.underline
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed)
bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (
mainItem.hovered || mainItem.pressed)
}
}
TextMetrics {
@ -67,6 +61,8 @@ Button {
bold: true
}
}
Item {Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
}
}

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {

View file

@ -9,10 +9,10 @@ Button {
id: mainItem
textSize: Typography.b2.pixelSize
textWeight: Typography.b2.weight
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(10)
bottomPadding: Utils.getSizeWithScreenRatio(10)
icon.width: Utils.getSizeWithScreenRatio(16)
icon.height: Utils.getSizeWithScreenRatio(16)
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(10)
bottomPadding: Utils.getSizeWithScreenRatio(10)
icon.width: Utils.getSizeWithScreenRatio(16)
icon.height: Utils.getSizeWithScreenRatio(16)
}

View file

@ -6,195 +6,198 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Button {
id: mainItem
property alias popup: popup
property bool shadowEnabled: mainItem.activeFocus && !keyboardFocus || hovered
property alias popupBackgroundColor: popupBackground.color
property color backgroundColor: checked ? pressedColor : hovered || mainItem.activeFocus ? hoveredColor : color
property string popUpTitle: ""
Accessible.name: popup.visible ?
//: "Close %1 popup"
qsTr("close_popup_panel_accessible_name").arg(popUpTitle) :
//: "Open %1" popup
qsTr("open_popup_panel_accessible_name").arg(popUpTitle)
style: ButtonStyle.popupButton
checked: popup.visible
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
icon.source: AppIcons.verticalDots
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
implicitWidth: Utils.getSizeWithScreenRatio(30)
implicitHeight: Utils.getSizeWithScreenRatio(30)
function close() {
popup.close();
}
function open() {
popup.open();
}
id: mainItem
property alias popup: popup
property bool shadowEnabled: mainItem.activeFocus && !keyboardFocus || hovered
property alias popupBackgroundColor: popupBackground.color
property color backgroundColor: checked ? pressedColor : hovered || mainItem.activeFocus ? hoveredColor : color
property string popUpTitle: ""
Accessible.name: popup.visible ?
//: "Close %1 popup"
qsTr("close_popup_panel_accessible_name").arg(popUpTitle) :
//: "Open %1" popup
qsTr("open_popup_panel_accessible_name").arg(popUpTitle)
style: ButtonStyle.popupButton
checked: popup.visible
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
icon.source: AppIcons.verticalDots
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
implicitWidth: Utils.getSizeWithScreenRatio(30)
implicitHeight: Utils.getSizeWithScreenRatio(30)
function close() {
popup.close();
}
function open() {
popup.open();
}
function isFocusable(item) {
return item.activeFocusOnTab;
}
function isFocusable(item) {
return item.activeFocusOnTab;
}
/**
* Check if an element has at least one child that is focusable
*/
function hasFocusableChild(content) {
return content.children.some(child => isFocusable(child));
}
/**
* Check if an element has at least one child that is focusable
*/
function hasFocusableChild(content) {
return content.children.some(child => isFocusable(child));
}
function getPreviousItem(index) {
return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index);
}
function getPreviousItem(index) {
return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index);
}
function getNextItem(index) {
return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index);
}
function getNextItem(index) {
return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index);
}
function _getPreviousItem(content, index) {
if (!content.visible) return null
if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
--index;
while (index >= 0) {
if (isFocusable(content.children[index]) && content.children[index].visible)
return content.children[index];
--index;
}
return _getPreviousItem(content, content.visibleChildren.length);
}
function _getPreviousItem(content, index) {
if (!content.visible)
return null;
if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
--index;
while (index >= 0) {
if (isFocusable(content.children[index]) && content.children[index].visible)
return content.children[index];
--index;
}
return _getPreviousItem(content, content.visibleChildren.length);
}
function _getNextItem(content, index) {
if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
++index;
while (index < content.children.length) {
if (isFocusable(content.children[index]) && content.children[index].visible)
return content.children[index];
++index;
}
return _getNextItem(content, -1);
}
function _getNextItem(content, index) {
if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
++index;
while (index < content.children.length) {
if (isFocusable(content.children[index]) && content.children[index].visible)
return content.children[index];
++index;
}
return _getNextItem(content, -1);
}
Keys.onPressed: event => {
if (mainItem.checked) {
if (event.key == Qt.Key_Escape || event.key == Qt.Key_Left || event.key == Qt.Key_Space) {
mainItem.close();
mainItem.forceActiveFocus(Qt.TabFocusReason);
event.accepted = true;
} else if (event.key == Qt.Key_Up) {
getPreviousItem(0).forceActiveFocus(Qt.TabFocusReason);
event.accepted = true;
} else if (event.key == Qt.Key_Tab || event.key == Qt.Key_Down) {
getNextItem(-1).forceActiveFocus(Qt.BacktabFocusReason);
event.accepted = true;
}
} else if (event.key == Qt.Key_Space) {
mainItem.open();
event.accepted = true;
}
}
Keys.onPressed: event => {
if (mainItem.checked) {
if (event.key == Qt.Key_Escape || event.key == Qt.Key_Left || event.key == Qt.Key_Space) {
mainItem.close();
mainItem.forceActiveFocus(Qt.TabFocusReason);
event.accepted = true;
} else if (event.key == Qt.Key_Up) {
getPreviousItem(0).forceActiveFocus(Qt.TabFocusReason);
event.accepted = true;
} else if (event.key == Qt.Key_Tab || event.key == Qt.Key_Down) {
getNextItem(-1).forceActiveFocus(Qt.BacktabFocusReason);
event.accepted = true;
}
} else if (event.key == Qt.Key_Space) {
mainItem.open();
event.accepted = true;
}
}
background: Item {
anchors.fill: mainItem
Rectangle {
id: buttonBackground
anchors.fill: parent
color: mainItem.backgroundColor
radius: Utils.getSizeWithScreenRatio(40)
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: buttonBackground
source: buttonBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
contentItem: EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.contentImageColor
}
onPressed: {
if (popup.visible)
popup.close();
else
popup.open();
}
Control.Popup {
id: popup
x: 0
y: mainItem.height
visible: false
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape
padding: Utils.getSizeWithScreenRatio(10)
parent: mainItem // Explicit define for coordinates references.
function updatePosition() {
if (!visible)
return;
var popupHeight = popup.height + popup.padding;
var popupWidth = popup.width + popup.padding;
var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem(mainItem, 0, 0) : {
"x": 0,
"y": 0
};
// Stay inside main window
y = Math.max(Math.min(winPosition.y + mainItem.Window.height - popupHeight, mainItem.height), winPosition.y);
x = Math.max(Math.min(winPosition.x + mainItem.Window.width - popupWidth, 0), winPosition.x);
// Avoid overlapping with popup button by going to the right (todo: check if left is better?)
if (y < mainItem.height && y + popupHeight > 0) {
x += mainItem.width;
}
var globalPos = mapToItem(mainItem.Window.contentItem, x, y);
if (globalPos.x + popupWidth >= mainItem.Window.width) {
x = -popupWidth;
}
}
background: Item {
anchors.fill: mainItem
Rectangle {
id: buttonBackground
anchors.fill: parent
color: mainItem.backgroundColor
radius: Utils.getSizeWithScreenRatio(40)
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: buttonBackground
source: buttonBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
contentItem: EffectImage {
imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height
colorizationColor: mainItem.contentImageColor
}
onPressed: {
if (popup.visible)
popup.close();
else
popup.open();
}
Control.Popup {
id: popup
x: 0
y: mainItem.height
visible: false
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape
padding: Utils.getSizeWithScreenRatio(10)
parent: mainItem // Explicit define for coordinates references.
function updatePosition() {
if (!visible)
return;
var popupHeight = popup.height + popup.padding;
var popupWidth = popup.width + popup.padding;
var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem(mainItem, 0, 0) : {
"x": 0,
"y": 0
};
// Stay inside main window
y = Math.max(Math.min(winPosition.y + mainItem.Window.height - popupHeight, mainItem.height), winPosition.y);
x = Math.max(Math.min(winPosition.x + mainItem.Window.width - popupWidth, 0), winPosition.x);
// Avoid overlapping with popup button by going to the right (todo: check if left is better?)
if (y < mainItem.height && y + popupHeight > 0) {
x += mainItem.width;
}
var globalPos = mapToItem(mainItem.Window.contentItem, x, y);
if (globalPos.x + popupWidth >= mainItem.Window.width) {
x = -popupWidth;
}
}
onHeightChanged: Qt.callLater(updatePosition)
onWidthChanged: Qt.callLater(updatePosition)
onVisibleChanged: Qt.callLater(updatePosition)
onHeightChanged: Qt.callLater(updatePosition)
onWidthChanged: Qt.callLater(updatePosition)
onVisibleChanged: Qt.callLater(updatePosition)
Connections {
target: mainItem.Window
function onHeightChanged() {
Qt.callLater(popup.updatePosition);
}
function onWidthChanged() {
Qt.callLater(popup.updatePosition);
}
}
Connections {
target: mainItem.Window
function onHeightChanged() {
Qt.callLater(popup.updatePosition);
}
function onWidthChanged() {
Qt.callLater(popup.updatePosition);
}
}
background: Item {
anchors.fill: parent
Rectangle {
id: popupBackground
anchors.fill: parent
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(16)
}
MultiEffect {
source: popupBackground
anchors.fill: popupBackground
shadowEnabled: true
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.4
}
MouseArea {
anchors.fill: parent
}
}
}
background: Item {
anchors.fill: parent
Rectangle {
id: popupBackground
anchors.fill: parent
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(16)
}
MultiEffect {
source: popupBackground
anchors.fill: popupBackground
shadowEnabled: true
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.4
}
MouseArea {
anchors.fill: parent
}
}
}
}

View file

@ -12,13 +12,13 @@ Control.RadioButton {
property string imgUrl
property bool checkOnClick: true
property color color
property real indicatorSize: Utils.getSizeWithScreenRatio(16)
property real indicatorSize: Utils.getSizeWithScreenRatio(16)
property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered
//onClicked: if (checkOnClick && !mainItem.checked) mainItem.toggle()
MouseArea{
MouseArea {
id: mouseArea
anchors.fill:parent
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
@ -31,16 +31,16 @@ Control.RadioButton {
Rectangle {
id: backgroundArea
anchors.fill: parent
radius: mainItem.indicatorSize/2
radius: mainItem.indicatorSize / 2
color: "transparent"
border.color: mainItem.color
border.width: Utils.getSizeWithScreenRatio(2)
border.width: Utils.getSizeWithScreenRatio(2)
Rectangle {
width: parent.width/2
height: parent.height/2
x: parent.width/4
y: parent.width/4
radius: width/2
width: parent.width / 2
height: parent.height / 2
x: parent.width / 4
y: parent.width / 4
radius: width / 2
color: mainItem.color
visible: mainItem.checked
}
@ -49,7 +49,7 @@ Control.RadioButton {
enabled: mainItem.shadowEnabled
anchors.fill: backgroundArea
source: backgroundArea
visible: mainItem.shadowEnabled
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000

View file

@ -9,10 +9,10 @@ Button {
id: mainItem
textSize: Typography.p1s.pixelSize
textWeight: Typography.p1s.weight
padding: Utils.getSizeWithScreenRatio(16)
// icon.width: width
// icon.height: width
radius: width * 2
// width: Utils.getSizeWithScreenRatio(24)
height: width
padding: Utils.getSizeWithScreenRatio(16)
// icon.width: width
// icon.height: width
radius: width * 2
// width: Utils.getSizeWithScreenRatio(24)
height: width
}

View file

@ -16,33 +16,34 @@ Control.RadioButton {
anchors.fill: parent
hoverEnabled: false
cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: if (!mainItem.checked) mainItem.toggle()
onClicked: if (!mainItem.checked)
mainItem.toggle()
}
background: Rectangle {
color: DefaultStyle.grey_100
border.color: mainItem.checked ? mainItem.color : "transparent"
radius: Utils.getSizeWithScreenRatio(20)
radius: Utils.getSizeWithScreenRatio(20)
}
indicator: RowLayout {
anchors.left: parent.left
anchors.leftMargin: Utils.getSizeWithScreenRatio(13)
anchors.leftMargin: Utils.getSizeWithScreenRatio(13)
anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(4)
anchors.topMargin: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(4)
Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Utils.getSizeWithScreenRatio(16)
radius: implicitWidth/2
implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Utils.getSizeWithScreenRatio(16)
radius: implicitWidth / 2
border.color: mainItem.color
Rectangle {
width: parent.width/2
height: parent.height/2
x: parent.width/4
y: parent.width/4
radius: width/2
width: parent.width / 2
height: parent.height / 2
x: parent.width / 4
y: parent.width / 4
radius: width / 2
color: mainItem.color
visible: mainItem.checked
}
@ -52,7 +53,7 @@ Control.RadioButton {
text: mainItem.title
font.bold: true
color: DefaultStyle.grey_900
font.pixelSize: Utils.getSizeWithScreenRatio(16)
font.pixelSize: Utils.getSizeWithScreenRatio(16)
}
Button {
padding: 0
@ -60,41 +61,41 @@ Control.RadioButton {
visible: false
}
icon.source: AppIcons.info
Layout.preferredWidth: Utils.getSizeWithScreenRatio(2)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(2)
width: Utils.getSizeWithScreenRatio(2)
height: Utils.getSizeWithScreenRatio(2)
icon.width: Utils.getSizeWithScreenRatio(2)
icon.height: Utils.getSizeWithScreenRatio(2)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(2)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(2)
width: Utils.getSizeWithScreenRatio(2)
height: Utils.getSizeWithScreenRatio(2)
icon.width: Utils.getSizeWithScreenRatio(2)
icon.height: Utils.getSizeWithScreenRatio(2)
}
}
contentItem: ColumnLayout {
anchors.top: indicator.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Utils.getSizeWithScreenRatio(13)
anchors.leftMargin: Utils.getSizeWithScreenRatio(13)
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.bottomMargin: Utils.getSizeWithScreenRatio(10)
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(10)
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
Layout.alignment: Qt.AlignVCenter
Text {
id: innerText
verticalAlignment: Text.AlignVCenter
Layout.preferredWidth: Utils.getSizeWithScreenRatio(220)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(100)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(220)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(100)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
text: mainItem.contentText
Layout.fillHeight: true
}
Image {
id: image
Layout.fillHeight: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(100)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(100)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(100)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(100)
fillMode: Image.PreserveAspectFit
source: mainItem.imgUrl
}

View file

@ -2,28 +2,28 @@ import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ComboBox {
id: mainItem
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
property string propertyName
property var propertyOwner
property var propertyOwnerGui
property alias entries: mainItem.model
oneLine: true
currentIndex: Utils.findIndex(model, function (entry) {
if(propertyOwnerGui)
return Utils.equalObject(entry,propertyOwnerGui.core[propertyName])
if (propertyOwnerGui)
return Utils.equalObject(entry, propertyOwnerGui.core[propertyName]);
else
return Utils.equalObject(entry,propertyOwner[propertyName])
return Utils.equalObject(entry, propertyOwner[propertyName]);
})
onCurrentValueChanged: {
if(propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue,propertyOwnerGui.core[propertyName])
}else{
binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName])
if (propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue, propertyOwnerGui.core[propertyName]);
} else {
binding.when = !Utils.equalObject(currentValue, propertyOwner[propertyName]);
}
}
Binding {

View file

@ -2,10 +2,10 @@ import QtQuick
import QtQuick.Controls.Basic
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
RowLayout {
id:mainItem
id: mainItem
property string titleText
property string subTitleText
property string propertyName
@ -13,13 +13,13 @@ RowLayout {
property var propertyOwnerGui
property bool enabled: true
property alias checked: switchButton.checked
spacing : Utils.getSizeWithScreenRatio(20)
spacing: Utils.getSizeWithScreenRatio(20)
signal toggled()
signal toggled
ColumnLayout {
Layout.minimumHeight: Utils.getSizeWithScreenRatio(32)
spacing: Utils.getSizeWithScreenRatio(4)
Layout.minimumHeight: Utils.getSizeWithScreenRatio(32)
spacing: Utils.getSizeWithScreenRatio(4)
Text {
text: titleText
font: Typography.p2l
@ -39,12 +39,12 @@ RowLayout {
Switch {
id: switchButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName]
: propertyOwner ? propertyOwner[mainItem.propertyName] : false
checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName] : propertyOwner
? propertyOwner[mainItem.propertyName] : false
enabled: mainItem.enabled
onToggled: {
binding.when = true
mainItem.toggled()
binding.when = true;
mainItem.toggled();
}
implicitHeight: Utils.getSizeWithScreenRatio(30)
Accessible.name: "%1 %2".arg(mainItem.titleText).arg(mainItem.subTitleText)

View file

@ -7,65 +7,71 @@ import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Slider {
id: mainItem
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
id: mainItem
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
hoverEnabled: true
// Border properties
property color borderColor: "transparent"
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
background: Item{
// Border properties
property color borderColor: "transparent"
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
background: Item {
x: mainItem.leftPadding
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Utils.getSizeWithScreenRatio(4)
implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Utils.getSizeWithScreenRatio(4)
width: mainItem.availableWidth
height: implicitHeight
Rectangle {
id: sliderBackground
anchors.fill: parent
radius: Math.round(height / 2)
radius: Math.round(height / 2)
// TODO : change the colors when mockup indicates their names
color: DefaultStyle.grey_850
Rectangle {
width: mainItem.visualPosition * parent.width
height: parent.height
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main1_300 }
GradientStop { position: 1.0; color: DefaultStyle.main1_500_main }
GradientStop {
position: 0.0
color: DefaultStyle.main1_300
}
GradientStop {
position: 1.0
color: DefaultStyle.main1_500_main
}
}
radius: Math.round(height / 2)
radius: Math.round(height / 2)
}
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: sliderBackground
source: sliderBackground
visible: mainItem.shadowEnabled
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
}
handle: Item {
handle: Item {
x: mainItem.leftPadding + mainItem.visualPosition * (mainItem.availableWidth - width)
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Utils.getSizeWithScreenRatio(16)
implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Utils.getSizeWithScreenRatio(16)
Rectangle {
id: handleRect
anchors.fill: parent
radius: Math.round(height / 2)
radius: Math.round(height / 2)
color: DefaultStyle.grey_0
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
MultiEffect {
source: handleRect

View file

@ -9,10 +9,10 @@ Button {
id: mainItem
textSize: Typography.b3.pixelSize
textWeight: Typography.b3.weight
leftPadding: Utils.getSizeWithScreenRatio(12)
rightPadding: Utils.getSizeWithScreenRatio(12)
topPadding: Utils.getSizeWithScreenRatio(6)
bottomPadding: Utils.getSizeWithScreenRatio(6)
icon.height: Utils.getSizeWithScreenRatio(14)
icon.width: Utils.getSizeWithScreenRatio(14)
leftPadding: Utils.getSizeWithScreenRatio(12)
rightPadding: Utils.getSizeWithScreenRatio(12)
topPadding: Utils.getSizeWithScreenRatio(6)
bottomPadding: Utils.getSizeWithScreenRatio(6)
icon.height: Utils.getSizeWithScreenRatio(14)
icon.width: Utils.getSizeWithScreenRatio(14)
}

View file

@ -6,69 +6,69 @@ import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Switch {
id: mainItem
hoverEnabled: true
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
// Text properties
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
// Border properties
property color borderColor: "transparent"
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
id: mainItem
hoverEnabled: true
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
// Text properties
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
// Border properties
property color borderColor: "transparent"
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
indicator: Item {
id: indicatorItem
x: mainItem.leftPadding
y: parent.height / 2 - height / 2
// Size properties
implicitHeight: Utils.getSizeWithScreenRatio(20)
implicitWidth: Math.round(implicitHeight * 1.6)
Rectangle {
id: indicatorBackground
anchors.fill: parent
radius: Math.round(indicatorItem.height / 2)
color: mainItem.checked ? DefaultStyle.success_500_main : DefaultStyle.main2_400
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
indicator: Item {
id: indicatorItem
x: mainItem.leftPadding
y: parent.height / 2 - height / 2
// Size properties
implicitHeight: Utils.getSizeWithScreenRatio(20)
implicitWidth: Math.round(implicitHeight * 1.6)
Rectangle {
id: indicatorBackground
anchors.fill: parent
radius: Math.round(indicatorItem.height / 2)
color: mainItem.checked ? DefaultStyle.success_500_main : DefaultStyle.main2_400
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
Rectangle {
anchors.verticalCenter: parent.verticalCenter
height: Math.round(indicatorItem.height * 0.6)
width: height
property real margin: Math.round((indicatorItem.height - height) / 2)
radius: Math.round(height / 2)
x: mainItem.checked ? parent.width - width - margin : margin
color: DefaultStyle.grey_0
Behavior on x {
NumberAnimation {
duration: 100
}
}
}
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: indicatorBackground
source: indicatorBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
Rectangle {
anchors.verticalCenter: parent.verticalCenter
height: Math.round(indicatorItem.height * 0.6)
width: height
property real margin: Math.round((indicatorItem.height - height) / 2)
radius: Math.round(height / 2)
x: mainItem.checked ? parent.width - width - margin : margin
color: DefaultStyle.grey_0
Behavior on x {
NumberAnimation {
duration: 100
}
}
}
}
MultiEffect {
enabled: mainItem.shadowEnabled
anchors.fill: indicatorBackground
source: indicatorBackground
visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
contentItem: Text {
text: mainItem.text
font: mainItem.font
opacity: enabled ? 1.0 : 0.3
verticalAlignment: Text.AlignVCenter
leftPadding: mainItem.indicator.width + mainItem.spacing
}
contentItem: Text {
text: mainItem.text
font: mainItem.font
opacity: enabled ? 1.0 : 0.3
verticalAlignment: Text.AlignVCenter
leftPadding: mainItem.indicator.width + mainItem.spacing
}
}

View file

@ -16,27 +16,24 @@ Item {
property alias call: allDevices.currentCall
property ConferenceGui conference: call && call.core.conference || null
property var callState: call && call.core.state || undefined
property string localAddress: call
? call.conference
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
call.core.localAddress : ""
property bool sideStickersVisible: sideStickers.visible
// currently speaking address (for hiding in list view)
property string activeSpeakerAddress
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy {
property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices
qmlName: "AS"
onCountChanged: console.log("Device count changed : " +count)
Component.onCompleted: console.log("Loaded : " +allDevices)
onCountChanged: console.log("Device count changed : " + count)
Component.onCompleted: console.log("Loaded : " + allDevices)
}
RowLayout{
RowLayout {
anchors.fill: parent
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(16)
Sticker {
id: activeSpeakerSticker
Layout.fillWidth: true
@ -46,7 +43,8 @@ Item {
displayAll: !mainItem.conference
participantDevice: mainItem.conference && mainItem.conference.core.activeSpeakerDevice
property var address: participantDevice && participantDevice.core.address
videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call && call.core.remoteVideoEnabled)
videoEnabled: (participantDevice && participantDevice.core.videoEnabled) || (!participantDevice && call
&& call.core.remoteVideoEnabled)
qmlName: 'AS'
securityBreach: !mainItem.conference && mainItem.call?.core.isMismatch || false
displayPresence: false
@ -57,35 +55,37 @@ Item {
when: true
}
}
ListView{
ListView {
id: sideStickers
Layout.fillHeight: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(300)
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(10)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(300)
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(10)
visible: allDevices.count > 2 || !!mainItem.conference?.core.isScreenSharingEnabled
//spacing: Utils.getSizeWithScreenRatio(15) // bugged? First item has twice margins
//spacing: Utils.getSizeWithScreenRatio(15) // bugged? First item has twice margins
model: allDevices
snapMode: ListView.SnapOneItem
clip: true
delegate: Item{ // Spacing workaround
visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
&& ($modelData.core.address != activeSpeakerAddress || mainItem.conference?.core.isScreenSharingEnabled) || false
height: visible ? Utils.getSizeWithScreenRatio(180 + 15) : 0
width: Utils.getSizeWithScreenRatio(300)
delegate: Item {
// Spacing workaround
visible: $modelData && mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState
!= LinphoneEnums.CallState.Released && ($modelData.core.address != activeSpeakerAddress || mainItem.conference
?.core.isScreenSharingEnabled) || false
height: visible ? Utils.getSizeWithScreenRatio(180 + 15) : 0
width: Utils.getSizeWithScreenRatio(300)
Sticker {
previewEnabled: index == 0 // before anchors for priority initialization
anchors.fill: parent
anchors.bottomMargin: Utils.getSizeWithScreenRatio(15)// Spacing
qmlName: 'S_'+index
anchors.bottomMargin: Utils.getSizeWithScreenRatio(15)// Spacing
qmlName: 'S_' + index
visible: parent.visible
videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled)
|| (!previewEnabled && call && call.core.remoteVideoEnabled)
|| (!previewEnabled && participantDevice && participantDevice.core.videoEnabled)
videoEnabled: (index === 0 && mainItem.call.core.cameraEnabled) || (!previewEnabled && call
&& call.core.remoteVideoEnabled) || (!previewEnabled && participantDevice
&& participantDevice.core.videoEnabled)
participantDevice: $modelData
displayAll: false
displayPresence: false
Component.onCompleted: console.log(qmlName + " is " +($modelData ? $modelData.core.address : "-"))
Component.onCompleted: console.log(qmlName + " is " + ($modelData ? $modelData.core.address : "-"))
}
}
}

View file

@ -14,40 +14,45 @@ Mosaic {
property ConferenceGui conference: call && call.core.conference || null
property bool videoEnabled: true
property int participantCount: gridModel.count
margins: 0
// On grid view, we limit the quality if there are enough participants// The vga mode has been activated from the factory rc
//onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality()
delegateModel: DelegateModel{
delegateModel: DelegateModel {
id: gridModel
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy {
property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices
qmlName: "G"
Component.onCompleted: console.log("Loaded : " +allDevices + " = " +allDevices.count)
Component.onCompleted: console.log("Loaded : " + allDevices + " = " + allDevices.count)
}
model: grid.call && grid.call.core.isConference ? participantDevices: [0,1]
delegate: Item{
model: grid.call && grid.call.core.isConference ? participantDevices : [0, 1]
delegate: Item {
id: avatarCell
property ParticipantDeviceGui currentDevice: index >= 0 && grid.call && grid.call.core.isConference ? $modelData : null
property ParticipantDeviceGui currentDevice: index >= 0 && grid.call && grid.call.core.isConference ? $modelData :
null
onCurrentDeviceChanged: {
if(index < 0) cameraView.enabled = false // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer)
if (index < 0)
cameraView.enabled
= false; // this is a delegate destruction. We need to stop camera before Qt change its currentDevice (and then, let CameraView to delete wrong renderer)
}
height: grid.cellHeight - Utils.getSizeWithScreenRatio(10)
width: grid.cellWidth - Utils.getSizeWithScreenRatio(10)
height: grid.cellHeight - Utils.getSizeWithScreenRatio(10)
width: grid.cellWidth - Utils.getSizeWithScreenRatio(10)
Sticker {
id: cameraView
previewEnabled: index == 0
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
visible: mainItem.callState != LinphoneEnums.CallState.End && mainItem.callState != LinphoneEnums.CallState.Released
anchors.fill: parent
qmlName: 'G_'+index
qmlName: 'G_' + index
call: grid.call && !grid.call.core.isConference ? grid.call : null
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: (index == 0 && accountObj) ? accountObj.value : null
displayAll: false
displayPresence: false
participantDevice: avatarCell.currentDevice
Component.onCompleted: console.log(qmlName + " is " +(call ? call.core.remoteAddress : currentDevice ? currentDevice.core.address : 'addr_NotDefined'))
Component.onCompleted: console.log(qmlName + " is " + (call ? call.core.remoteAddress : currentDevice
? currentDevice.core.address : 'addr_NotDefined'))
}
}
}

View file

@ -5,12 +5,12 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
spacing: Utils.getSizeWithScreenRatio(30)
spacing: Utils.getSizeWithScreenRatio(30)
property var callHistoryGui
@ -20,35 +20,32 @@ ColumnLayout {
property bool isConference: conferenceInfo != undefined && conferenceInfo != null
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value: ""
property string contactName: contact
? contact.core.fullName
: callHistoryGui
? callHistoryGui.core.displayName
: computedContactName
property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""
property string contactName: contact ? contact.core.fullName : callHistoryGui ? callHistoryGui.core.displayName :
computedContactName
// Set this property to get the security informations
// Set this property to get the security informations
// for a specific address and not for the entire contact
property string specificAddress: ""
property alias buttonContent: rightButton.data
property alias detailContent: detailControl.data
signal conferenceChatDisplayRequested()
signal conferenceCallHistoryDisplayRequested()
signal conferenceChatDisplayRequested
signal conferenceCallHistoryDisplayRequested
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(13)
spacing: Utils.getSizeWithScreenRatio(13)
Layout.alignment: Qt.AlignHCenter
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: detailAvatar.height
Layout.alignment: Qt.AlignHCenter
Avatar {
id: detailAvatar
anchors.horizontalCenter: parent.horizontalCenter
width: Utils.getSizeWithScreenRatio(100)
height: Utils.getSizeWithScreenRatio(100)
width: Utils.getSizeWithScreenRatio(100)
height: Utils.getSizeWithScreenRatio(100)
contact: mainItem.contact || null
isConference: !!mainItem.conferenceInfo
displayNameVal: mainItem.contactName
@ -58,18 +55,18 @@ ColumnLayout {
id: rightButton
anchors.right: parent.right
anchors.verticalCenter: detailAvatar.verticalCenter
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
}
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
spacing: Utils.getSizeWithScreenRatio(5)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
spacing: Utils.getSizeWithScreenRatio(5)
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2)
spacing: Utils.getSizeWithScreenRatio(2)
Layout.alignment: Qt.AlignHCenter
Text {
Layout.preferredWidth: implicitWidth
@ -79,8 +76,8 @@ ColumnLayout {
text: detailAvatar.displayNameVal
maximumLineCount: 1
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
Text {
@ -92,8 +89,8 @@ ColumnLayout {
elide: Text.ElideMiddle
maximumLineCount: 1
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
@ -105,8 +102,8 @@ ColumnLayout {
text: contact ? contact.core.presenceStatus : ""
color: contact ? contact.core.presenceColor : 'transparent'
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
@ -119,9 +116,9 @@ ColumnLayout {
style: ButtonStyle.grey
onClicked: {
if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow);
}
}
}
@ -129,96 +126,103 @@ ColumnLayout {
id: confWithChatLayout
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature && mainItem.chatGui !== null
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72)
spacing: Utils.getSizeWithScreenRatio(72)
// Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
LabelButton {
visible: !SettingsCpp.disableChatFeature
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoconference
//: "Join"
label: qsTr("meeting_info_join_title")
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoconference
//: "Join"
label: qsTr("meeting_info_join_title")
button.onClicked: if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
}
}
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow);
}
}
LabelButton {
visible: !SettingsCpp.disableChatFeature
button.checkable: true
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked
//: "Call history"
? qsTr("contact_call_history_action")
//: "Conversation"
: qsTr("contact_conversation_action")
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked ?
//: "Call history"
qsTr("contact_call_history_action") :
//: "Conversation"
qsTr("contact_conversation_action")
button.onCheckedChanged: {
if (button.checked) mainItem.conferenceChatDisplayRequested()
else mainItem.conferenceCallHistoryDisplayRequested()
if (button.checked)
mainItem.conferenceChatDisplayRequested();
else
mainItem.conferenceCallHistoryDisplayRequested();
}
}
}
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72)
spacing: Utils.getSizeWithScreenRatio(72)
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
visible: !mainItem.isConference
LabelButton {
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.phone
//: "Appel"
label: qsTr("contact_call_action")
//: "Appel"
label: qsTr("contact_call_action")
button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress)
if (mainItem.specificAddress === "")
mainWindow.startCallWithContact(mainItem.contact, false, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress);
}
}
LabelButton {
visible: !SettingsCpp.disableChatFeature
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.chatTeardropText
//: "Message"
label: qsTr("contact_message_action")
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.chatTeardropText
//: "Message"
label: qsTr("contact_message_action")
button.onClicked: {
console.debug("[CallHistoryLayout.qml] Open conversation")
console.debug("[CallHistoryLayout.qml] Open conversation");
if (mainItem.specificAddress === "") {
mainWindow.sendMessageToContact(mainItem.contact)
}
else {
console.log("specific address", mainItem.specificAddress)
mainWindow.displayChatPage(mainItem.specificAddress)
mainWindow.sendMessageToContact(mainItem.contact);
} else {
console.log("specific address", mainItem.specificAddress);
mainWindow.displayChatPage(mainItem.specificAddress);
}
}
}
LabelButton {
visible: SettingsCpp.videoEnabled
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoCamera
//: "Appel Video"
label: qsTr("contact_video_call_action")
button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem)
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true})
}
}
}
LabelButton {
visible: SettingsCpp.videoEnabled
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoCamera
//: "Appel Video"
label: qsTr("contact_video_call_action")
button.onClicked: {
if (mainItem.specificAddress === "")
mainWindow.startCallWithContact(mainItem.contact, true, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress, {
'localVideoEnabled': true
});
}
}
}
ColumnLayout {
id: detailControl
@ -226,6 +230,6 @@ ColumnLayout {
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Utils.getSizeWithScreenRatio(30)
Layout.topMargin: Utils.getSizeWithScreenRatio(30)
}
}

View file

@ -16,106 +16,97 @@ Item {
property CallGui call
property ConferenceGui conference: call && call.core.conference
property bool callTerminatedByUser: false
property bool callStarted: call? call.core.isStarted : false
property bool callStarted: call ? call.core.isStarted : false
readonly property var callState: call?.core.state
onCallStateChanged: if (callState === LinphoneEnums.CallState.End || callState === LinphoneEnums.CallState.Released) preview.visible = false
onCallStateChanged: if (callState === LinphoneEnums.CallState.End || callState === LinphoneEnums.CallState.Released)
preview.visible = false
property int conferenceLayout: call ? call.core.conferenceVideoLayout : LinphoneEnums.ConferenceLayout.ActiveSpeaker
property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
property int lastConfLayoutBeforeSharing: -1
property string localAddress: call
? call.conference
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
call.core.localAddress : ""
onParticipantDeviceCountChanged: {
setConferenceLayout()
setConferenceLayout();
}
Component.onCompleted: setConferenceLayout()
onConferenceLayoutChanged: {
console.log("CallLayout change : " +conferenceLayout)
setConferenceLayout()
console.log("CallLayout change : " + conferenceLayout);
setConferenceLayout();
}
Connections {
target: mainItem.conference? mainItem.conference.core : null
target: mainItem.conference ? mainItem.conference.core : null
function onIsScreenSharingEnabledChanged() {
setConferenceLayout()
setConferenceLayout();
}
function onIsLocalScreenSharingChanged() {
if (mainItem.conference.core.isLocalScreenSharing) {
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout;
}
setConferenceLayout()
setConferenceLayout();
}
}
function setConferenceLayout() {
callLayout.sourceComponent = undefined // unload old view before opening the new view to avoid conflicts in Video UI.
callLayout.sourceComponent = undefined; // unload old view before opening the new view to avoid conflicts in Video UI.
// If stop sharing screen, reset conference layout to the previous one
if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !== -1) {
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing
mainItem.lastConfLayoutBeforeSharing = -1
if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !==
-1) {
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing;
mainItem.lastConfLayoutBeforeSharing = -1;
}
callLayout.sourceComponent = conference
? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent
: participantDeviceCount <= 1
? waitingForOthersComponent
: gridComponent
: activeSpeakerComponent
callLayout.sourceComponent = conference ? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout
== LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent : participantDeviceCount <= 1 ? waitingForOthersComponent : gridComponent :
activeSpeakerComponent;
}
Text {
id: callTerminatedText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(25)
anchors.topMargin: Utils.getSizeWithScreenRatio(25)
z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference
//: "Vous avez quitté la conférence"
? qsTr("meeting_event_conference_destroyed")
: mainItem.callTerminatedByUser
//: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user")
: mainItem.callStarted
//: "Votre correspondant a terminé l'appel"
? qsTr("call_ended_by_remote")
: call && call.core.lastErrorMessage || ""
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error
|| mainItem.callState === LinphoneEnums.CallState.Released
text: mainItem.conference ?
//: "Vous avez quitté la conférence"
qsTr("meeting_event_conference_destroyed") : mainItem.callTerminatedByUser ?
//: "Vous avez terminé l'appel"
qsTr("call_ended_by_user") : mainItem.callStarted ?
//: "Votre correspondant a terminé l'appel"
qsTr("call_ended_by_remote") : call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(22)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(22)
weight: Utils.getSizeWithScreenRatio(300)
}
}
Loader{
Loader {
id: callLayout
anchors.fill: parent
sourceComponent: mainItem.participantDeviceCount === 0
? waitingForOthersComponent
: activeSpeakerComponent
sourceComponent: mainItem.participantDeviceCount === 0 ? waitingForOthersComponent : activeSpeakerComponent
}
Sticker {
id: preview
qmlName: 'P'
previewEnabled: true
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent === waitingForOthersComponent)
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingInit
&& !mainItem.conference?.core.isScreenSharingEnabled
&& mainItem.participantDeviceCount <= 2
height: Utils.getSizeWithScreenRatio(180)
width: Utils.getSizeWithScreenRatio(300)
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent
=== waitingForOthersComponent) && mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState
!== LinphoneEnums.CallState.OutgoingInit && !mainItem.conference?.core.isScreenSharingEnabled
&& mainItem.participantDeviceCount <= 2
height: Utils.getSizeWithScreenRatio(180)
width: Utils.getSizeWithScreenRatio(300)
anchors.right: mainItem.right
anchors.bottom: mainItem.bottom
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
onVideoEnabledChanged: console.log("Preview : " +videoEnabled + " / " +visible +" / " +mainItem.call)
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
onVideoEnabledChanged: console.log("Preview : " + videoEnabled + " / " + visible + " / " + mainItem.call)
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: accountObj && accountObj.value || null
account: accountObj && accountObj.value || null
call: mainItem.call
displayAll: false
displayPresence: false
@ -124,21 +115,21 @@ Item {
id: previewMouseArea
anchors.fill: parent
movableArea: mainItem
margin: Utils.getSizeWithScreenRatio(10)
function resetPosition(){
preview.anchors.right = mainItem.right
preview.anchors.bottom = mainItem.bottom
preview.anchors.rightMargin = previewMouseArea.margin
preview.anchors.bottomMargin = previewMouseArea.margin
}
onVisibleChanged: if(!visible){
resetPosition()
margin: Utils.getSizeWithScreenRatio(10)
function resetPosition() {
preview.anchors.right = mainItem.right;
preview.anchors.bottom = mainItem.bottom;
preview.anchors.rightMargin = previewMouseArea.margin;
preview.anchors.bottomMargin = previewMouseArea.margin;
}
onVisibleChanged: if (!visible) {
resetPosition();
}
drag.target: preview
onDraggingChanged: if(dragging) {
preview.anchors.right = undefined
preview.anchors.bottom = undefined
}
onDraggingChanged: if (dragging) {
preview.anchors.right = undefined;
preview.anchors.bottom = undefined;
}
onRequestResetPosition: resetPosition()
}
}
@ -147,22 +138,22 @@ Item {
id: waitingForOthersComponent
Rectangle {
color: DefaultStyle.grey_600
radius: Utils.getSizeWithScreenRatio(15)
radius: Utils.getSizeWithScreenRatio(15)
ColumnLayout {
anchors.centerIn: parent
spacing: Utils.getSizeWithScreenRatio(22)
spacing: Utils.getSizeWithScreenRatio(22)
width: waitText.implicitWidth
Text {
id: waitText
//: "En attente d'autres participants"
text: qsTr("conference_call_empty")
Layout.preferredHeight: Utils.getSizeWithScreenRatio(67)
//: "En attente d'autres participants"
text: qsTr("conference_call_empty")
Layout.preferredHeight: Utils.getSizeWithScreenRatio(67)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(30)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(30)
weight: Utils.getSizeWithScreenRatio(300)
}
}
Item {
@ -172,16 +163,16 @@ Item {
borderColor: DefaultStyle.main2_400
icon.source: AppIcons.shareNetwork
contentImageColor: DefaultStyle.main2_400
//: "Partager le lien"
text: qsTr("conference_share_link_title")
//: "Partager le lien"
text: qsTr("conference_share_link_title")
anchors.centerIn: parent
textColor: DefaultStyle.main2_400
onClicked: {
if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.conference.core.uri)
showInformationPopup(qsTr("copied"),
//: Le lien de la réunion a été copié dans le presse-papier
qsTr("information_popup_meeting_address_copied_to_clipboard"), true)
UtilsCpp.copyToClipboard(mainItem.conference.core.uri);
showInformationPopup(qsTr("copied"),
//: Le lien de la réunion a été copié dans le presse-papier
qsTr("information_popup_meeting_address_copied_to_clipboard"), true);
}
}
}
@ -189,20 +180,19 @@ Item {
}
}
}
Component{
Component {
id: activeSpeakerComponent
ActiveSpeakerLayout{
ActiveSpeakerLayout {
id: activeSpeaker
Layout.fillWidth: true
Layout.fillHeight: true
call: mainItem.call
}
}
Component{
Component {
id: gridComponent
CallGridLayout{
CallGridLayout {
Layout.fillWidth: true
Layout.fillHeight: true
call: mainItem.call

View file

@ -11,109 +11,110 @@ ColumnLayout {
property alias cellHeight: grid.cellHeight
property alias cellWidth: grid.cellWidth
property alias margins: grid.margin
function appendItem(item){
mainLayout.delegateModel.model.append(item)
function appendItem(item) {
mainLayout.delegateModel.model.append(item);
}
function add(item){
if( !grid.isLayoutWillChanged())
appendItem(item)
function add(item) {
if (!grid.isLayoutWillChanged())
appendItem(item);
else
bufferModels.append(item)
bufferModels.append(item);
}
function remove(index){
if(mainLayout.delegateModel.model.count > index)
mainLayout.delegateModel.model.remove( index, 1)
function remove(index) {
if (mainLayout.delegateModel.model.count > index)
mainLayout.delegateModel.model.remove(index, 1);
}
function get(index){
return mainLayout.delegateModel.model.get(index)
function get(index) {
return mainLayout.delegateModel.model.get(index);
}
function tryToAdd(item){
if( !grid.isLayoutWillChanged()) {
appendItem(item)
return true
}else
return false
function tryToAdd(item) {
if (!grid.isLayoutWillChanged()) {
appendItem(item);
return true;
} else
return false;
}
function clear(){
if(mainLayout.delegateModel.model.clear) {
mainLayout.delegateModel.model.clear()
bufferModels.clear()
function clear() {
if (mainLayout.delegateModel.model.clear) {
mainLayout.delegateModel.model.clear();
bufferModels.clear();
}
}
property int transitionCount : 0
property var bufferModels : ListModel{}
property int transitionCount: 0
property var bufferModels: ListModel {}
onWidthChanged: grid.updateLayout()
onHeightChanged: grid.updateLayout()
spacing: 0
GridView{
GridView {
id: grid
property real margin: Utils.getSizeWithScreenRatio(10)
property int itemCount: model.count ? model.count :( model.length ? model.length : 0)
property real margin: Utils.getSizeWithScreenRatio(10)
property int itemCount: model.count ? model.count : (model.length ? model.length : 0)
property int columns: 1
property int rows: 1
function getBestLayout(itemCount){
var availableW = mainLayout.width - grid.margin
var availableH = mainLayout.height - grid.margin
var bestSize = 0
var bestC = 1, bestR = 1
for(var R = 1 ; R <= itemCount ; ++R){
for(var C = itemCount ; C >= 1 ; --C){
if( R * C >= itemCount){// This is a good layout candidate
var estimatedSize = Math.min(availableW / C, availableH / R)
if(estimatedSize > bestSize // Size is better
|| (estimatedSize == bestSize && Math.abs(bestR-bestC) > Math.abs(R - C) )){// Stickers are more homogenized
bestSize = estimatedSize
bestC = C
bestR = R
function getBestLayout(itemCount) {
var availableW = mainLayout.width - grid.margin;
var availableH = mainLayout.height - grid.margin;
var bestSize = 0;
var bestC = 1, bestR = 1;
for (var R = 1; R <= itemCount; ++R) {
for (var C = itemCount; C >= 1; --C) {
if (R * C >= itemCount) {
// This is a good layout candidate
var estimatedSize = Math.min(availableW / C, availableH / R);
if (estimatedSize > bestSize // Size is better
|| (estimatedSize == bestSize && Math.abs(bestR - bestC) > Math.abs(R - C))) {
// Stickers are more homogenized
bestSize = estimatedSize;
bestC = C;
bestR = R;
}
}
}
}
return [bestR, bestC]
return [bestR, bestC];
}
function updateLayout(){
var bestLayout = getBestLayout(itemCount)
if( rows != bestLayout[0])
rows = bestLayout[0]
if( columns != bestLayout[1])
columns = bestLayout[1]
function updateLayout() {
var bestLayout = getBestLayout(itemCount);
if (rows != bestLayout[0])
rows = bestLayout[0];
if (columns != bestLayout[1])
columns = bestLayout[1];
}
function updateCells(){
cellWidth = Math.min(computedWidth, computedHeight)
cellHeight = Math.min(computedWidth, computedHeight)
function updateCells() {
cellWidth = Math.min(computedWidth, computedHeight);
cellHeight = Math.min(computedWidth, computedHeight);
}
onItemCountChanged: updateLayout()
property real computedWidth: (mainLayout.width - grid.margin ) / columns
property real computedHeight: (mainLayout.height - grid.margin ) / rows
property real computedWidth: (mainLayout.width - grid.margin) / columns
property real computedHeight: (mainLayout.height - grid.margin) / rows
onComputedHeightChanged: Qt.callLater(updateCells)
onComputedWidthChanged: Qt.callLater(updateCells)
cellWidth: Math.min(computedWidth, computedHeight)
cellHeight: Math.min(computedWidth, computedHeight)
function isLayoutWillChanged(){
var bestLayout = getBestLayout(itemCount+1)
return rows !== bestLayout[0] || columns !== bestLayout[1]
function isLayoutWillChanged() {
var bestLayout = getBestLayout(itemCount + 1);
return rows !== bestLayout[0] || columns !== bestLayout[1];
}
Layout.preferredWidth: cellWidth * columns
Layout.preferredHeight: cellHeight * rows
Layout.alignment: Qt.AlignCenter
interactive: false
model: DelegateModel{}
model: DelegateModel {}
onCountChanged: grid.updateLayout()
}
}

View file

@ -13,10 +13,10 @@ ColumnLayout {
required property int itemsCount
property int currentIndex: carouselStackLayout.currentIndex
property var currentItem: carouselButton.itemAt(currentIndex)
spacing: Utils.getSizeWithScreenRatio(61)
spacing: Utils.getSizeWithScreenRatio(61)
function goToSlide(index) {
carouselStackLayout.goToSlideAtIndex(index)
carouselStackLayout.goToSlideAtIndex(index);
}
StackLayout {
@ -26,15 +26,18 @@ ColumnLayout {
currentIndex: 0
function goToSlideAtIndex(index) {
carouselStackLayout.previousIndex = carouselStackLayout.currentIndex
carouselStackLayout.currentIndex = index
carouselStackLayout.previousIndex = carouselStackLayout.currentIndex;
carouselStackLayout.currentIndex = index;
}
onCurrentIndexChanged: {
var currentItem = children[currentIndex]
var crossFaderAnim = crossFader.createObject(parent, {fadeInTarget: currentItem, mirrored: (previousIndex > currentIndex)})
crossFaderAnim.restart()
mainItem.currentIndex = currentIndex
var currentItem = children[currentIndex];
var crossFaderAnim = crossFader.createObject(parent, {
fadeInTarget: currentItem,
mirrored: (previousIndex > currentIndex)
});
crossFaderAnim.restart();
mainItem.currentIndex = currentIndex;
}
Component {
@ -56,7 +59,7 @@ ColumnLayout {
XAnimator {
target: fadeInTarget
from: (mirrored ? -1 : 1) * fadeInTarget.width/3.
from: (mirrored ? -1 : 1) * fadeInTarget.width / 3.
to: 0
duration: 300
easing.type: Easing.OutCubic
@ -68,40 +71,46 @@ ColumnLayout {
Item {
Rectangle {
id: currentIndicator
width: Utils.getSizeWithScreenRatio(13)
height: Utils.getSizeWithScreenRatio(8)
radius: Utils.getSizeWithScreenRatio(30)
width: Utils.getSizeWithScreenRatio(13)
height: Utils.getSizeWithScreenRatio(8)
radius: Utils.getSizeWithScreenRatio(30)
color: DefaultStyle.main1_500_main
z: 1
x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width/2 + mainItem.currentItem.width/2 : 0
Behavior on x { NumberAnimation {duration: 100}}
x: mainItem.currentIndex >= 0 && mainItem.currentItem ? mainItem.currentItem.x - width / 2
+ mainItem.currentItem.width / 2 : 0
Behavior on x {
NumberAnimation {
duration: 100
}
}
}
RowLayout {
id: carouselButtonsLayout
spacing: Utils.getSizeWithScreenRatio(7.5)
anchors.leftMargin: Utils.getSizeWithScreenRatio(2.5)
spacing: Utils.getSizeWithScreenRatio(7.5)
anchors.leftMargin: Utils.getSizeWithScreenRatio(2.5)
Repeater {
id: carouselButton
model: mainItem.itemsCount
delegate: Button {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(8)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(8)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(8)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(8)
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
background: Rectangle {
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(30)
radius: Utils.getSizeWithScreenRatio(30)
anchors.fill: parent
}
onClicked: {
mainItem.goToSlide(modelData)
mainItem.goToSlide(modelData);
}
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
}
}
}

View file

@ -14,11 +14,10 @@ GridLayout {
property bool isHoveringFile: false
property int itemCount: delModel.count
property int itemWidth: Utils.getSizeWithScreenRatio(95)
// cellWidth:
// cellWidth:
// cellHeight: Utils.getSizeWithScreenRatio(105)
property real maxWidth: Utils.getSizeWithScreenRatio(3 * 105)
columns: optimalColumns
property int optimalColumns: {
let maxCols = Math.floor(maxWidth / itemWidth);
@ -30,10 +29,7 @@ GridLayout {
let rows = Math.ceil(itemCount / cols);
let emptySlots = cols * rows - itemCount;
if (
rows < minRows ||
(rows === minRows && emptySlots < minEmptySlots)
) {
if (rows < minRows || (rows === minRows && emptySlots < minEmptySlots)) {
bestCols = cols;
minRows = rows;
minEmptySlots = emptySlots;
@ -55,4 +51,4 @@ GridLayout {
// onIsHoveringChanged: mainItem.isHoveringFile = isHovering
}
}
}
}

View file

@ -5,12 +5,12 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
spacing: Utils.getSizeWithScreenRatio(30)
spacing: Utils.getSizeWithScreenRatio(30)
property FriendGui contact
@ -18,18 +18,18 @@ ColumnLayout {
property alias content: detailLayout.data
property alias bannerContent: bannerLayout.data
property alias secondLineContent: verticalLayoutSecondLine.data
property real minimumWidthForSwitchintToRowLayout: Utils.getSizeWithScreenRatio(756)
property var useVerticalLayout: width < minimumWidthForSwitchintToRowLayout
property real minimumWidthForSwitchintToRowLayout: Utils.getSizeWithScreenRatio(756)
property var useVerticalLayout: width < minimumWidthForSwitchintToRowLayout
GridLayout {
Layout.leftMargin: Utils.getSizeWithScreenRatio(64)
Layout.rightMargin: Utils.getSizeWithScreenRatio(64)
Layout.topMargin: Utils.getSizeWithScreenRatio(56)
Layout.leftMargin: Utils.getSizeWithScreenRatio(64)
Layout.rightMargin: Utils.getSizeWithScreenRatio(64)
Layout.topMargin: Utils.getSizeWithScreenRatio(56)
Layout.fillWidth: true
columns: mainItem.useVerticalLayout ? 1 : children.length
rows: 1
columnSpacing: Utils.getSizeWithScreenRatio(49)
rowSpacing: Utils.getSizeWithScreenRatio(27)
columnSpacing: Utils.getSizeWithScreenRatio(49)
rowSpacing: Utils.getSizeWithScreenRatio(27)
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(16)
@ -48,13 +48,25 @@ ColumnLayout {
radius: Utils.getSizeWithScreenRatio(15)
borderGradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_100 }
GradientStop { position: 1.0; color: DefaultStyle.main2_200 }
GradientStop {
position: 0.0
color: DefaultStyle.grey_100
}
GradientStop {
position: 1.0
color: DefaultStyle.main2_200
}
}
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 }
GradientStop { position: 1.0; color: DefaultStyle.grey_100 }
GradientStop {
position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
}
}
contentItem: RowLayout {
@ -90,7 +102,7 @@ ColumnLayout {
}
}
Rectangle {
Layout.fillWidth:true
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(79)
color: 'transparent'
visible: contact && contact.core.presenceNote.length > 0 && !mainItem.useVerticalLayout
@ -104,10 +116,10 @@ ColumnLayout {
StackLayout {
id: detailLayout
Layout.alignment: Qt.AlignCenter
Layout.topMargin: mainItem.useVerticalLayout ? 0 : Utils.getSizeWithScreenRatio(30)
Layout.leftMargin: Utils.getSizeWithScreenRatio(64)
Layout.rightMargin: Utils.getSizeWithScreenRatio(64)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(53)
Layout.topMargin: mainItem.useVerticalLayout ? 0 : Utils.getSizeWithScreenRatio(30)
Layout.leftMargin: Utils.getSizeWithScreenRatio(64)
Layout.rightMargin: Utils.getSizeWithScreenRatio(64)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(53)
Layout.fillWidth: true
Layout.fillHeight: true
}

View file

@ -5,49 +5,49 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle {
id: mainItem
property FriendGui friendGui
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(20)
border.color: DefaultStyle.main2_200
border.width: Utils.getSizeWithScreenRatio(2)
id: mainItem
property FriendGui friendGui
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(20)
border.color: DefaultStyle.main2_200
border.width: Utils.getSizeWithScreenRatio(2)
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(16)
spacing: Utils.getSizeWithScreenRatio(8)
ColumnLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(16)
spacing: Utils.getSizeWithScreenRatio(8)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(6)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(6)
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.presenceNote
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Utils.getSizeWithScreenRatio(17)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(17)
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.presenceNote
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Utils.getSizeWithScreenRatio(17)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(17)
}
Text {
font: Typography.p2
color: DefaultStyle.main2_600
text: qsTr("contact_presence_note_title")
}
}
Text {
font: Typography.p2
color: DefaultStyle.main2_600
text: qsTr("contact_presence_note_title")
}
}
Text {
font: Typography.p3
color: DefaultStyle.main2_500_main
text: mainItem.friendGui?.core.presenceNote || ""
wrapMode: Text.Wrap
Layout.fillWidth: true
}
}
Text {
font: Typography.p3
color: DefaultStyle.main2_500_main
text: mainItem.friendGui?.core.presenceNote || ""
wrapMode: Text.Wrap
Layout.fillWidth: true
}
}
}

View file

@ -6,120 +6,127 @@ import QtQuick.Effects
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope {
id: mainItem
property color searchBarColor: DefaultStyle.grey_100
property color searchBarBorderColor: "transparent"
property alias searchBar: searchBar
property string startGroupButtonText
property bool startGroupButtonVisible: true
property string startGroupButtonText
property bool startGroupButtonVisible: true
property NumericPadPopup numPadPopup
signal groupCreationRequested()
signal groupCreationRequested
signal contactClicked(FriendGui contact)
clip: true
property alias topContent: topLayout.data
property bool topLayoutVisible: topLayout.children.length > 0
property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39)
property alias topContent: topLayout.data
property bool topLayoutVisible: topLayout.children.length > 0
property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39)
ColumnLayout {
anchors.fill: parent
spacing: Utils.getSizeWithScreenRatio(22)
spacing: Utils.getSizeWithScreenRatio(22)
ColumnLayout {
id: topLayout
visible: mainItem.topLayoutVisible
spacing: Utils.getSizeWithScreenRatio(18)
id: topLayout
visible: mainItem.topLayoutVisible
spacing: Utils.getSizeWithScreenRatio(18)
}
ColumnLayout {
onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close()
spacing: Utils.getSizeWithScreenRatio(38)
SearchBar {
id: searchBar
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.rightMargin: mainItem.searchBarRightMaring
focus: true
color: mainItem.searchBarColor
borderColor: mainItem.searchBarBorderColor
//: "Rechercher un contact"
placeholderText: qsTr("search_bar_look_for_contact_text")
numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: groupCreationButton
}
ColumnLayout {
id: content
spacing: Utils.getSizeWithScreenRatio(32)
Button {
id: groupCreationButton
visible: mainItem.startGroupButtonVisible
Layout.preferredWidth: Utils.getSizeWithScreenRatio(320)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(44)
padding: 0
KeyNavigation.up: searchBar
KeyNavigation.down: contactList
onClicked: mainItem.groupCreationRequested()
background: Rectangle {
anchors.fill: parent
radius: height / 2
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main2_100}
GradientStop { position: 1.0; color: DefaultStyle.grey_0}
}
// Black border for keyboard navigation
border.color: DefaultStyle.main2_900
border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
}
Accessible.name: mainItem.startGroupButtonText
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(16)
anchors.verticalCenter: parent.verticalCenter
Rectangle {
width: Utils.getSizeWithScreenRatio(44)
height: width
radius: width / 2
color: DefaultStyle.main1_500_main
EffectImage {
imageSource: AppIcons.usersThreeFilled
anchors.centerIn: parent
width: Utils.getSizeWithScreenRatio(24)
height: width
fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0
}
}
Text {
text: mainItem.startGroupButtonText
color: DefaultStyle.grey_1000
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
Item {
Layout.fillWidth: true
}
EffectImage {
imageSource: AppIcons.rightArrow
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
colorizationColor: DefaultStyle.main2_500_main
}
}
}
AllContactListView{
id: contactList
Layout.fillWidth: true
Layout.fillHeight: true
showContactMenu: false
searchBarText: searchBar.text
onContactSelected: (contact) => {
mainItem.contactClicked(contact)
}
}
}
}
}
ColumnLayout {
onVisibleChanged: if (!visible && mainItem.numPadPopup)
mainItem.numPadPopup.close()
spacing: Utils.getSizeWithScreenRatio(38)
SearchBar {
id: searchBar
Layout.alignment: Qt.AlignTop
Layout.fillWidth: true
Layout.rightMargin: mainItem.searchBarRightMaring
focus: true
color: mainItem.searchBarColor
borderColor: mainItem.searchBarBorderColor
//: "Rechercher un contact"
placeholderText: qsTr("search_bar_look_for_contact_text")
numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: groupCreationButton
}
ColumnLayout {
id: content
spacing: Utils.getSizeWithScreenRatio(32)
Button {
id: groupCreationButton
visible: mainItem.startGroupButtonVisible
Layout.preferredWidth: Utils.getSizeWithScreenRatio(320)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(44)
padding: 0
KeyNavigation.up: searchBar
KeyNavigation.down: contactList
onClicked: mainItem.groupCreationRequested()
background: Rectangle {
anchors.fill: parent
radius: height / 2
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
position: 0.0
color: DefaultStyle.main2_100
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_0
}
}
// Black border for keyboard navigation
border.color: DefaultStyle.main2_900
border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
}
Accessible.name: mainItem.startGroupButtonText
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(16)
anchors.verticalCenter: parent.verticalCenter
Rectangle {
width: Utils.getSizeWithScreenRatio(44)
height: width
radius: width / 2
color: DefaultStyle.main1_500_main
EffectImage {
imageSource: AppIcons.usersThreeFilled
anchors.centerIn: parent
width: Utils.getSizeWithScreenRatio(24)
height: width
fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0
}
}
Text {
text: mainItem.startGroupButtonText
color: DefaultStyle.grey_1000
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
Item {
Layout.fillWidth: true
}
EffectImage {
imageSource: AppIcons.rightArrow
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
colorizationColor: DefaultStyle.main2_500_main
}
}
}
AllContactListView {
id: contactList
Layout.fillWidth: true
Layout.fillHeight: true
showContactMenu: false
searchBarText: searchBar.text
onContactSelected: contact => {
mainItem.contactClicked(contact);
}
}
}
}
}
}

View file

@ -5,51 +5,51 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
spacing: Utils.getSizeWithScreenRatio(15)
property string label
property var icon
property alias content: contentControl.contentItem
signal titleIconClicked
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Text {
text: mainItem.label
color: DefaultStyle.main1_500_main
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
RoundButton {
visible: mainItem.icon != undefined
icon.source: mainItem.icon
style: ButtonStyle.noBackgroundOrange
onClicked: mainItem.titleIconClicked()
}
Item {
Layout.fillWidth: true
}
RoundButton {
id: expandButton
style: ButtonStyle.noBackground
checkable: true
checked: true
icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow
KeyNavigation.down: contentControl
}
}
RoundedPane {
id: contentControl
visible: expandButton.checked
Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(17)
bottomPadding: Utils.getSizeWithScreenRatio(17)
}
}
id: mainItem
spacing: Utils.getSizeWithScreenRatio(15)
property string label
property var icon
property alias content: contentControl.contentItem
signal titleIconClicked
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Text {
text: mainItem.label
color: DefaultStyle.main1_500_main
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
RoundButton {
visible: mainItem.icon != undefined
icon.source: mainItem.icon
style: ButtonStyle.noBackgroundOrange
onClicked: mainItem.titleIconClicked()
}
Item {
Layout.fillWidth: true
}
RoundButton {
id: expandButton
style: ButtonStyle.noBackground
checkable: true
checked: true
icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow
KeyNavigation.down: contentControl
}
}
RoundedPane {
id: contentControl
visible: expandButton.checked
Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(17)
bottomPadding: Utils.getSizeWithScreenRatio(17)
}
}

View file

@ -5,7 +5,7 @@ import Linphone
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope{
FocusScope {
id: mainItem
property alias contentItem: contentItem.data
property string label: ""
@ -21,33 +21,32 @@ FocusScope{
implicitHeight: layout.implicitHeight
function clearErrorText() {
errorText.clear()
errorText.clear();
}
onErrorMessageChanged: if (errorMessage.length > 0) {
var item = mainItem
do {
var parentItem = item.parent
if (parentItem.contentItem) {
var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y)
if (parentItem.contentY > itemPosInParent.y) {
parentItem.contentY = itemPosInParent.y;
}
else if (parentItem.contentY+parentItem.height < itemPosInParent.y+mainItem.height) {
parentItem.contentY = itemPosInParent.y + mainItem.height - height;
}
}
item = parentItem
} while(item.parent != undefined && parentItem.contentItem === undefined)
}
var item = mainItem;
do {
var parentItem = item.parent;
if (parentItem.contentItem) {
var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y);
if (parentItem.contentY > itemPosInParent.y) {
parentItem.contentY = itemPosInParent.y;
} else if (parentItem.contentY + parentItem.height < itemPosInParent.y + mainItem.height) {
parentItem.contentY = itemPosInParent.y + mainItem.height - height;
}
}
item = parentItem;
} while (item.parent != undefined && parentItem.contentItem === undefined)
}
ColumnLayout {
id: layout
spacing: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(5)
anchors.left: parent.left
anchors.right: parent.right
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
Text {
visible: label.length > 0
verticalAlignment: Text.AlignVCenter
@ -57,13 +56,15 @@ FocusScope{
wrapMode: Text.Wrap
maximumLineCount: 1
textFormat: Text.RichText
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
PopupButton {
visible: mainItem.tooltip !== ""
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
@ -78,11 +79,11 @@ FocusScope{
Text {
visible: mainItem.labelIndication !== undefined
font.pixelSize: Utils.getSizeWithScreenRatio(12)
font.weight: Utils.getSizeWithScreenRatio(300)
text: mainItem.labelIndication
font.weight: Utils.getSizeWithScreenRatio(300)
text: mainItem.labelIndication
}
}
Item {
Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true
@ -99,6 +100,5 @@ FocusScope{
color: DefaultStyle.danger_500_main
}
}
}
}

View file

@ -6,94 +6,93 @@ import QtQuick.Effects
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope {
id: mainItem
property alias addParticipantsLayout: addParticipantsLayout
property alias groupNameItem: groupNameItem
property alias groupName: groupName
property string formTitle
property string createGroupButtonText
property int selectedParticipantsCount
signal returnRequested()
signal groupCreationRequested()
ColumnLayout {
spacing: 0
anchors.fill: parent
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Button {
id: backGroupCallButton
style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.leftArrow
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
KeyNavigation.down: groupName
KeyNavigation.right: groupCallButton
KeyNavigation.left: groupCallButton
//: Return
Accessible.name: qsTr("return_accessible_name")
onClicked: {
mainItem.returnRequested()
}
}
Text {
text: mainItem.formTitle
color: DefaultStyle.main1_500_main
maximumLineCount: 1
font {
pixelSize: Utils.getSizeWithScreenRatio(18)
weight: Typography.h4.weight
}
Layout.fillWidth: true
}
SmallButton {
id: groupCallButton
enabled: mainItem.selectedParticipantsCount.length != 0
Layout.rightMargin: Utils.getSizeWithScreenRatio(21)
text: mainItem.createGroupButtonText
style: ButtonStyle.main
KeyNavigation.down: addParticipantsLayout
KeyNavigation.left: backGroupCallButton
KeyNavigation.right: backGroupCallButton
onClicked: {
mainItem.groupCreationRequested()
}
}
}
FormItemLayout {
id: groupNameItem
enableErrorText: true
Layout.fillWidth: true
Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Utils.getSizeWithScreenRatio(38)
//: "Nom du groupe"
label: qsTr("group_start_dialog_subject_hint")
//: "Requis"
labelIndication: qsTr("required")
contentItem: TextField {
id: groupName
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
focus: true
isError: groupNameItem.errorMessage !== ""
KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar
Accessible.name: qsTr("group_start_dialog_subject_hint")
}
}
AddParticipantsForm {
id: addParticipantsLayout
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: Utils.getSizeWithScreenRatio(15)
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
focus: true
}
}
id: mainItem
property alias addParticipantsLayout: addParticipantsLayout
property alias groupNameItem: groupNameItem
property alias groupName: groupName
property string formTitle
property string createGroupButtonText
property int selectedParticipantsCount
signal returnRequested
signal groupCreationRequested
ColumnLayout {
spacing: 0
anchors.fill: parent
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Button {
id: backGroupCallButton
style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.leftArrow
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
KeyNavigation.down: groupName
KeyNavigation.right: groupCallButton
KeyNavigation.left: groupCallButton
//: Return
Accessible.name: qsTr("return_accessible_name")
onClicked: {
mainItem.returnRequested();
}
}
Text {
text: mainItem.formTitle
color: DefaultStyle.main1_500_main
maximumLineCount: 1
font {
pixelSize: Utils.getSizeWithScreenRatio(18)
weight: Typography.h4.weight
}
Layout.fillWidth: true
}
SmallButton {
id: groupCallButton
enabled: mainItem.selectedParticipantsCount.length != 0
Layout.rightMargin: Utils.getSizeWithScreenRatio(21)
text: mainItem.createGroupButtonText
style: ButtonStyle.main
KeyNavigation.down: addParticipantsLayout
KeyNavigation.left: backGroupCallButton
KeyNavigation.right: backGroupCallButton
onClicked: {
mainItem.groupCreationRequested();
}
}
}
FormItemLayout {
id: groupNameItem
enableErrorText: true
Layout.fillWidth: true
Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Utils.getSizeWithScreenRatio(38)
//: "Nom du groupe"
label: qsTr("group_start_dialog_subject_hint")
//: "Requis"
labelIndication: qsTr("required")
contentItem: TextField {
id: groupName
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
focus: true
isError: groupNameItem.errorMessage !== ""
KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar
Accessible.name: qsTr("group_start_dialog_subject_hint")
}
}
AddParticipantsForm {
id: addParticipantsLayout
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: Utils.getSizeWithScreenRatio(15)
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
focus: true
}
}
}

View file

@ -46,11 +46,11 @@ ColumnLayout {
color: mainItem.panelColor
Layout.fillWidth: true
Layout.fillHeight: true
MouseArea {
anchors.fill: parent
onClicked: {
rightPanelContent.forceActiveFocus()
}
}
MouseArea {
anchors.fill: parent
onClicked: {
rightPanelContent.forceActiveFocus();
}
}
}
}

View file

@ -8,10 +8,10 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ScrollBar {
id: mainItem
padding: 0
property color color: DefaultStyle.grey_850
property color color: DefaultStyle.grey_850
contentItem: Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(6)
radius: Utils.getSizeWithScreenRatio(32)
color: mainItem.color
implicitWidth: Utils.getSizeWithScreenRatio(6)
radius: Utils.getSizeWithScreenRatio(32)
color: mainItem.color
}
}

View file

@ -9,22 +9,22 @@ Layout with line separator used in several views
*/
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(15)
spacing: Utils.getSizeWithScreenRatio(15)
property alias content: contentLayout.data
property alias contentLayout: contentLayout
ColumnLayout {
id: contentLayout
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
// width: parent.width
// Layout.fillWidth: true
// Layout.preferredHeight: childrenRect.height
// Layout.preferredWidth: parent.width
// Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
// Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
}
Rectangle {
color: DefaultStyle.main2_200
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
width: parent.width
}
}

View file

@ -4,16 +4,14 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Effects
import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TabBar {
id: mainItem
property var model
readonly property int originX: count > 0
? itemAt(0).x
: 0
property real pixelSize: Typography.h3.pixelSize
property real textWeight: Typography.h3.weight
readonly property int originX: count > 0 ? itemAt(0).x : 0
property real pixelSize: Typography.h3.pixelSize
property real textWeight: Typography.h3.weight
property int capitalization: Font.Capitalize
wheelEnabled: true
background: Item {
@ -22,7 +20,7 @@ Control.TabBar {
Rectangle {
id: barBG
height: Utils.getSizeWithScreenRatio(4)
height: Utils.getSizeWithScreenRatio(4)
color: DefaultStyle.grey_200
anchors.bottom: parent.bottom
width: parent.width
@ -34,7 +32,7 @@ Control.TabBar {
// anchors.bottom: parent.bottom
// // anchors.left: mainItem.currentItem.left
// // anchors.right: mainItem.currentItem.right
// x: mainItem.currentItem
// x: mainItem.currentItem
// ? mainItem.currentItem.x - mainItem.originX
// : 0
// width: mainItem.currentItem ? mainItem.currentItem.width : 0
@ -61,9 +59,9 @@ Control.TabBar {
delay: 1000
text: modelData
}
MouseArea{
MouseArea {
anchors.fill: parent
cursorShape: tabButton.hovered ? Qt.PointingHandCursor: Qt.ArrowCursor
cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton
}
@ -72,7 +70,7 @@ Control.TabBar {
Rectangle {
id: tabBackground
visible: mainItem.currentIndex === index || tabButton.hovered
height: Utils.getSizeWithScreenRatio(5)
height: Utils.getSizeWithScreenRatio(5)
color: mainItem.currentIndex === index ? DefaultStyle.main1_500_main : DefaultStyle.main2_400
anchors.bottom: parent.bottom
anchors.left: parent.left
@ -89,7 +87,7 @@ Control.TabBar {
shadowBlur: 0.1
shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0
}
Rectangle{
Rectangle {
id: borderBackground
visible: tabButton.keyboardFocus
height: tabButton.height
@ -113,7 +111,7 @@ Control.TabBar {
elide: Text.ElideRight
maximumLineCount: 1
text: modelData
bottomPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
}
}
}

View file

@ -5,12 +5,12 @@ import QtQuick.Effects
import Linphone
import SettingsCpp
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TabBar {
id: mainItem
//spacing: Utils.getSizeWithScreenRatio(32)
topPadding: Utils.getSizeWithScreenRatio(36)
//spacing: Utils.getSizeWithScreenRatio(32)
topPadding: Utils.getSizeWithScreenRatio(36)
property var model
readonly property alias cornerRadius: bottomLeftCorner.radius
@ -19,49 +19,51 @@ Control.TabBar {
property int visibleCount: 0
signal enterPressed()
signal spacePressed()
signal enterPressed
signal spacePressed
// Call it after model is ready. If done before, Repeater will not be updated
function initButtons(){
actionsRepeater.model = mainItem.model
function initButtons() {
actionsRepeater.model = mainItem.model;
}
function updateVisibleCount() {
mainItem.visibleCount = 0
mainItem.visibleCount = 0;
contentChildren.forEach(child => {
if (child.visible) mainItem.visibleCount = mainItem.visibleCount + 1
})
if (child.visible)
mainItem.visibleCount = mainItem.visibleCount + 1;
});
}
onDefaultAccountChanged: {
if (defaultAccount) defaultAccount.core?.lRefreshNotifications()
if (defaultAccount)
defaultAccount.core?.lRefreshNotifications();
}
Connections {
target: SettingsCpp
function onDisableMeetingsFeatureChanged() {
initButtons()
}
function onDisableChatFeatureChanged() {
initButtons()
}
}
contentItem: ListView {
model: mainItem.contentModel
currentIndex: mainItem.currentIndex
Connections {
target: SettingsCpp
function onDisableMeetingsFeatureChanged() {
initButtons();
}
function onDisableChatFeatureChanged() {
initButtons();
}
}
spacing: mainItem.spacing
orientation: ListView.Vertical
// boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded
// snapMode: ListView.SnapToItem
contentItem: ListView {
model: mainItem.contentModel
currentIndex: mainItem.currentIndex
// highlightMoveDuration: 0
// highlightRangeMode: ListView.ApplyRange
// preferredHighlightBegin: 40
// preferredHighlightEnd: width - 40
}
spacing: mainItem.spacing
orientation: ListView.Vertical
// boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded
// snapMode: ListView.SnapToItem
// highlightMoveDuration: 0
// highlightRangeMode: ListView.ApplyRange
// preferredHighlightBegin: 40
// preferredHighlightEnd: width - 40
}
background: Item {
id: background
@ -70,30 +72,30 @@ Control.TabBar {
id: bottomLeftCorner
anchors.fill: parent
color: DefaultStyle.main1_500_main
radius: Utils.getSizeWithScreenRatio(25)
radius: Utils.getSizeWithScreenRatio(25)
}
Rectangle {
color: DefaultStyle.main1_500_main
anchors.left: parent.left
anchors.top: parent.top
width: parent.width/2
height: parent.height/2
width: parent.width / 2
height: parent.height / 2
}
Rectangle {
color: DefaultStyle.main1_500_main
y: parent.y + parent.height/2
y: parent.y + parent.height / 2
width: parent.width
height: parent.height/2
height: parent.height / 2
}
}
Repeater {
Repeater {
id: actionsRepeater
Control.TabButton {
id: tabButton
width: mainItem.width
bottomInset: Utils.getSizeWithScreenRatio(32)
topInset: Utils.getSizeWithScreenRatio(32)
bottomInset: Utils.getSizeWithScreenRatio(32)
topInset: Utils.getSizeWithScreenRatio(32)
hoverEnabled: true
visible: modelData?.visible != undefined ? modelData.visible : true
onVisibleChanged: mainItem.updateVisibleCount()
@ -102,23 +104,18 @@ Control.TabBar {
focusPolicy: Qt.StrongFocus
activeFocusOnTab: true
UnreadNotification {
unread: !defaultAccount
? -1
: index === 0
? defaultAccount.core?.unreadCallNotifications || -1
: index === 2
? defaultAccount.core?.unreadMessageNotifications || -1
: 0
unread: !defaultAccount ? -1 : index === 0 ? defaultAccount.core?.unreadCallNotifications || -1 : index === 2
? defaultAccount.core?.unreadMessageNotifications || -1 : 0
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
anchors.top: parent.top
}
MouseArea {
anchors.fill: tabButton
cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton
acceptedButtons: Qt.NoButton
}
background: Rectangle{
background: Rectangle {
// Black border for keyboard navigation
visible: tabButton.keyboardFocus
color: "transparent"
@ -130,7 +127,8 @@ Control.TabBar {
contentItem: ColumnLayout {
EffectImage {
id: buttonIcon
property real buttonSize: Utils.getSizeWithScreenRatio(mainItem.currentIndex !== index && tabButton.hovered ? 26 : 24)
property real buttonSize: Utils.getSizeWithScreenRatio(mainItem.currentIndex !== index && tabButton.hovered ? 26 :
24)
imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon
Layout.preferredWidth: buttonSize
Layout.preferredHeight: buttonSize
@ -138,18 +136,16 @@ Control.TabBar {
fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0
useColor: !modelData.colored
onStatusChanged: if (status === Image.Ready && !buttonText.visible) buttonText.visible = true
onStatusChanged: if (status === Image.Ready && !buttonText.visible)
buttonText.visible = true
}
Text {
id: buttonText
text: modelData.label
visible: false
font {
weight: mainItem.currentIndex === index
? Utils.getSizeWithScreenRatio(800)
: tabButton.hovered
? Utils.getSizeWithScreenRatio(600)
: Utils.getSizeWithScreenRatio(400)
weight: mainItem.currentIndex === index ? Utils.getSizeWithScreenRatio(800) : tabButton.hovered
? Utils.getSizeWithScreenRatio(600) : Utils.getSizeWithScreenRatio(400)
pixelSize: Utils.getSizeWithScreenRatio(11)
}
color: DefaultStyle.grey_0
@ -166,29 +162,29 @@ Control.TabBar {
text: modelData.label
font: buttonText.font
Component.onCompleted: {
font.weight = Utils.getSizeWithScreenRatio(800)
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize)
font.weight = Utils.getSizeWithScreenRatio(800);
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize);
}
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.enterPressed()
} else if(event.key === Qt.Key_Space){
mainItem.spacePressed()
} else if(event.key === Qt.Key_Down){
event.accepted = true;
if(TabBar.index >= mainItem.visibleCount - 1)
return;
tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason)
} else if(event.key === Qt.Key_Up){
event.accepted = true;
if(TabBar.index <= 0)
return;
tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason)
}
}
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.enterPressed();
} else if (event.key === Qt.Key_Space) {
mainItem.spacePressed();
} else if (event.key === Qt.Key_Down) {
event.accepted = true;
if (TabBar.index >= mainItem.visibleCount - 1)
return;
tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason);
} else if (event.key === Qt.Key_Up) {
event.accepted = true;
if (TabBar.index <= 0)
return;
tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason);
}
}
onClicked: {
mainItem.setCurrentIndex(TabBar.index)
mainItem.setCurrentIndex(TabBar.index);
}
}
}

View file

@ -10,289 +10,281 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
clip: true
keyNavigationEnabled: false // We will reimplement the keyNavigation
activeFocusOnTab: true
id: mainItem
clip: true
keyNavigationEnabled: false // We will reimplement the keyNavigation
activeFocusOnTab: true
property SearchBar searchBar
property bool loading: false
property string searchText: searchBar?.text
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool lastFocusByNavigationKeyboard: false // Workaround to get the correct focusReason
property SearchBar searchBar
property bool loading: false
property string searchText: searchBar?.text
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool lastFocusByNavigationKeyboard: false // Workaround to get the correct focusReason
signal resultsReceived
signal resultsReceived
onResultsReceived: {
loading = false
}
onResultsReceived: {
loading = false;
}
model: CallHistoryProxy {
id: callHistoryProxy
onListAboutToBeReset: loading = true
filterText: mainItem.searchText
onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(56)))
displayItemsStep: 3 * initialDisplayItems / 2
onModelAboutToBeReset: loading = true
onModelReset: {
mainItem.resultsReceived()
}
}
flickDeceleration: 10000
spacing: Utils.getSizeWithScreenRatio(10)
model: CallHistoryProxy {
id: callHistoryProxy
onListAboutToBeReset: loading = true
filterText: mainItem.searchText
onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(56)))
displayItemsStep: 3 * initialDisplayItems / 2
onModelAboutToBeReset: loading = true
onModelReset: {
mainItem.resultsReceived();
}
}
flickDeceleration: 10000
spacing: Utils.getSizeWithScreenRatio(10)
Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) {
console.log("Back")
searchBar.forceActiveFocus(Qt.BacktabFocusReason)
event.accepted = true
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) {
console.log("Back");
searchBar.forceActiveFocus(Qt.BacktabFocusReason);
event.accepted = true;
} else
// Re-implement key navigation to have Qt.TabFocusReason and Qt.BacktabFocusReason instead of Qt.OtherFocusReason when using arrows to navigate in listView
else if (event.key === Qt.Key_Up) {
if(currentIndex === 0){
searchBar.forceActiveFocus(Qt.BacktabFocusReason)
lastFocusByNavigationKeyboard = false
}else{
decrementCurrentIndex()
currentItem.forceActiveFocus(Qt.BacktabFocusReason) // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true
}
event.accepted = true
}
else if(event.key === Qt.Key_Down){
incrementCurrentIndex()
currentItem.forceActiveFocus(Qt.TabFocusReason) // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true
event.accepted = true
}
}
// Re-implement key navigation to have Qt.TabFocusReason and Qt.BacktabFocusReason instead of Qt.OtherFocusReason when using arrows to navigate in listView
if (event.key === Qt.Key_Up) {
if (currentIndex === 0) {
searchBar.forceActiveFocus(Qt.BacktabFocusReason);
lastFocusByNavigationKeyboard = false;
} else {
decrementCurrentIndex();
currentItem.forceActiveFocus(
Qt.BacktabFocusReason); // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true;
}
event.accepted = true;
} else if (event.key === Qt.Key_Down) {
incrementCurrentIndex();
currentItem.forceActiveFocus(
Qt.TabFocusReason); // The focusReason is created by QT later, need to create a workaround
lastFocusByNavigationKeyboard = true;
event.accepted = true;
}
}
Component.onCompleted: cacheBuffer = Math.max(mainItem.height,0) //contentHeight>0 ? contentHeight : 0// cache all items
// remove binding loop
// onContentHeightChanged: Qt.callLater(function () {
// if (mainItem)
// mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0
// })
Component.onCompleted: cacheBuffer = Math.max(mainItem.height,
0) //contentHeight>0 ? contentHeight : 0// cache all items
// remove binding loop
// onContentHeightChanged: Qt.callLater(function () {
// if (mainItem)
// mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0
// })
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0) currentIndex = 0
onCountChanged: {
if (currentIndex < 0 && count > 0) {
mainItem.currentIndex = 0 // Select first item after loading model
}
if (atYBeginning)
positionViewAtBeginning() // Stay at beginning
}
Connections {
target: deleteHistoryPopup
function onAccepted() {
mainItem.model.removeAllEntries()
}
}
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0
onCountChanged: {
if (currentIndex < 0 && count > 0) {
mainItem.currentIndex = 0; // Select first item after loading model
}
if (atYBeginning)
positionViewAtBeginning(); // Stay at beginning
}
Connections {
target: deleteHistoryPopup
function onAccepted() {
mainItem.model.removeAllEntries();
}
}
onAtYEndChanged: {
if (atYEnd && count > 0) {
callHistoryProxy.displayMore()
}
}
//----------------------------------------------------------------
function moveToCurrentItem() {
if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem)
}
onCurrentItemChanged: {
moveToCurrentItem()
}
// Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem()
}
Behavior on contentY {
NumberAnimation {
id: moveAnimation
duration: 500
easing.type: Easing.OutExpo
alwaysRunToEnd: true
}
}
onAtYEndChanged: {
if (atYEnd && count > 0) {
callHistoryProxy.displayMore();
}
}
//----------------------------------------------------------------
function moveToCurrentItem() {
if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem);
}
onCurrentItemChanged: {
moveToCurrentItem();
}
// Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem();
}
Behavior on contentY {
NumberAnimation {
id: moveAnimation
duration: 500
easing.type: Easing.OutExpo
alwaysRunToEnd: true
}
}
//----------------------------------------------------------------
//----------------------------------------------------------------
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea.
// So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1
delegate: FocusScope {
width: mainItem.width
height: Utils.getSizeWithScreenRatio(56)
Accessible.role: Accessible.ListItem
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea.
// So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1
delegate: FocusScope {
width: mainItem.width
height: Utils.getSizeWithScreenRatio(56)
Accessible.role: Accessible.ListItem
RowLayout {
z: 1
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
Avatar {
id: historyAvatar
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress)
contact: contactObj?.value || null
displayNameVal: modelData.core.displayName
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
width: Utils.getSizeWithScreenRatio(45)
height: Utils.getSizeWithScreenRatio(45)
isConference: modelData.core.isConference
shadowEnabled: false
asynchronous: false
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(5)
Text {
Layout.fillWidth: true
maximumLineCount: 1
text: modelData.core.displayName
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(6)
EffectImage {
id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined
|| modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
colorizationColor: modelData.core.status
=== LinphoneEnums.CallStatus.Declined
|| modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere
|| modelData.core.status
=== LinphoneEnums.CallStatus.Aborted
|| modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(12)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
transform: Rotation {
angle: modelData.core.isOutgoing
&& (modelData.core.status === LinphoneEnums.CallStatus.Declined
|| modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|| modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
origin {
x: statusIcon.width / 2
y: statusIcon.height / 2
}
}
}
Text {
// text: modelData.core.date
text: UtilsCpp.formatDate(modelData.core.date)
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
}
BigButton {
id: callButton
visible: !modelData.core.isConference || !SettingsCpp.disableMeetingsFeature
style: ButtonStyle.noBackground
icon.source: AppIcons.phone
focus: false
activeFocusOnTab: false
asynchronous: false
//: Call %1
Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal)
onClicked: {
if (modelData.core.isConference) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(
modelData.core.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
} else {
UtilsCpp.createCall(modelData.core.remoteAddress)
}
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Left){
backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason)
lastFocusByNavigationKeyboard = true;
}
}
onActiveFocusChanged: {
if (!activeFocus) {
console.log("Unfocus button");
callButton.focus = false // Make sure to be unfocusable (could be when called by forceActiveFocus)
backgroundMouseArea.focus = true
}
}
}
}
MouseArea {
id: backgroundMouseArea
hoverEnabled: true
anchors.fill: parent
focus: true
property bool keyboardFocus: FocusHelper.keyboardFocus || activeFocus && lastFocusByNavigationKeyboard
RowLayout {
z: 1
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
Avatar {
id: historyAvatar
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress)
contact: contactObj?.value || null
displayNameVal: modelData.core.displayName
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
width: Utils.getSizeWithScreenRatio(45)
height: Utils.getSizeWithScreenRatio(45)
isConference: modelData.core.isConference
shadowEnabled: false
asynchronous: false
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(5)
Text {
Layout.fillWidth: true
maximumLineCount: 1
text: modelData.core.displayName
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(6)
EffectImage {
id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow :
modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status
=== LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
=== LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main :
modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(12)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
transform: Rotation {
angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
=== LinphoneEnums.CallStatus.Aborted || modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
origin {
x: statusIcon.width / 2
y: statusIcon.height / 2
}
}
}
Text {
// text: modelData.core.date
text: UtilsCpp.formatDate(modelData.core.date)
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
}
BigButton {
id: callButton
visible: !modelData.core.isConference || !SettingsCpp.disableMeetingsFeature
style: ButtonStyle.noBackground
icon.source: AppIcons.phone
focus: false
activeFocusOnTab: false
asynchronous: false
//: %1 - %2 - %3 - right arrow for call-back button
Accessible.name: qsTr("call_history_entry_accessible_name").arg(
//: "Appel manqué"
modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title")
//: "Appel sortant"
: modelData.core.isOutgoing ? qsTr("call_outgoing")
//: "Appel entrant"
: qsTr("call_audio_incoming")
).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(modelData.core.date))
onContainsMouseChanged: {
if (containsMouse)
mainItem.lastMouseContainsIndex = index
else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1
}
Rectangle {
anchors.fill: parent
opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex
=== index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
//: Call %1
Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal)
onClicked: {
if (modelData.core.isConference) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(modelData.core.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow);
} else {
UtilsCpp.createCall(modelData.core.remoteAddress);
}
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Left) {
backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason);
lastFocusByNavigationKeyboard = true;
}
}
onActiveFocusChanged: {
if (!activeFocus) {
console.log("Unfocus button");
callButton.focus = false; // Make sure to be unfocusable (could be when called by forceActiveFocus)
backgroundMouseArea.focus = true;
}
}
}
}
MouseArea {
id: backgroundMouseArea
hoverEnabled: true
anchors.fill: parent
focus: true
property bool keyboardFocus: FocusHelper.keyboardFocus || activeFocus && lastFocusByNavigationKeyboard
//: %1 - %2 - %3 - right arrow for call-back button
Accessible.name: qsTr("call_history_entry_accessible_name").arg(
//: "Appel manqué"
modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") :
//: "Appel sortant"
modelData.core.isOutgoing ? qsTr("call_outgoing") :
//: "Appel entrant"
qsTr("call_audio_incoming")).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(
modelData.core.date))
onContainsMouseChanged: {
if (containsMouse)
mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1;
}
Rectangle {
anchors.fill: parent
opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
border.color: backgroundMouseArea.keyboardFocus ? DefaultStyle.main2_900 : "transparent"
border.width: backgroundMouseArea.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
visible: mainItem.lastMouseContainsIndex === index
|| mainItem.currentIndex === index
}
onPressed: {
mainItem.currentIndex = model.index
mainItem.forceActiveFocus()
mainItem.lastFocusByNavigationKeyboard = false
}
Keys.onPressed: event => {
if(event.key === Qt.Key_Right){
callButton.forceActiveFocus(Qt.TabFocusReason)
}
}
}
}
visible: mainItem.lastMouseContainsIndex === index || mainItem.currentIndex === index
}
onPressed: {
mainItem.currentIndex = model.index;
mainItem.forceActiveFocus();
mainItem.lastFocusByNavigationKeyboard = false;
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Right) {
callButton.forceActiveFocus(Qt.TabFocusReason);
}
}
}
}
}

View file

@ -6,42 +6,39 @@ import Linphone
import QtQml
import SettingsCpp
import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
implicitHeight: contentHeight
spacing: Utils.getSizeWithScreenRatio(15)
spacing: Utils.getSizeWithScreenRatio(15)
clip: true
property bool isTransferList: false
property string currentRemoteAddress: AppCpp.calls.currentCall ? AppCpp.calls.currentCall.core.remoteAddress : ""
property string currentRemoteAddress: AppCpp.calls.currentCall ? AppCpp.calls.currentCall.core.remoteAddress : ""
signal transferCallToAnotherRequested(CallGui dest)
onCountChanged: forceLayout()
model: CallProxy {
id: callProxy
sourceModel: AppCpp.calls
showCurrentCall: !mainItem.isTransferList
}
}
delegate: RowLayout {
id: callInformationItem
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
width: mainItem.width
height: Utils.getSizeWithScreenRatio(45)
height: Utils.getSizeWithScreenRatio(45)
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
property var callName : (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference)
? modelData.core.conference.core.subject
: remoteNameObj
? remoteNameObj.value
: ""
property var callName: (modelData && !SettingsCpp.disableMeetingsFeature && modelData.core.isConference)
? modelData.core.conference.core.subject : remoteNameObj ? remoteNameObj.value : ""
Avatar {
id: delegateAvatar
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
_address: modelData.core.remoteAddress
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
isConference: modelData.core.isConference
@ -52,48 +49,48 @@ ListView {
Text {
id: delegateName
text: callInformationItem.callName
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
Layout.fillWidth: true
maximumLineCount: 1
}
Text {
id: callStateText
//: "Réunion
property string type: modelData.core.isConference ? qsTr("meeting")
//: "Appel"
: qsTr("call")
Layout.rightMargin: Utils.getSizeWithScreenRatio(2)
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
//: "%1 en pause"
? qsTr("paused_call_or_meeting").arg(type)
//: "%1 en cours"
: qsTr("ongoing_call_or_meeting").arg(type)
//: "Réunion
property string type: modelData.core.isConference ? qsTr("meeting") :
//: "Appel"
qsTr("call")
Layout.rightMargin: Utils.getSizeWithScreenRatio(2)
text: modelData.core.state === LinphoneEnums.CallState.Paused || modelData.core.state
=== LinphoneEnums.CallState.PausedByRemote ?
//: "%1 en pause"
qsTr("paused_call_or_meeting").arg(type) :
//: "%1 en cours"
qsTr("ongoing_call_or_meeting").arg(type)
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
Button {
id: transferButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.alignment: Qt.AlignVCenter
visible: mainItem.isTransferList
&& (mainItem.currentRemoteAddress !== modelData.core.remoteAddress)
&& modelData.core.state !== LinphoneEnums.CallState.IncomingReceived
&& modelData.core.state !== LinphoneEnums.CallState.PushIncomingReceived
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingInit
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingRinging
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingEarlyMedia
&& modelData.core.state !== LinphoneEnums.CallState.IncomingEarlyMedia
visible: mainItem.isTransferList && (mainItem.currentRemoteAddress !== modelData.core.remoteAddress)
&& modelData.core.state !== LinphoneEnums.CallState.IncomingReceived && modelData.core.state
!== LinphoneEnums.CallState.PushIncomingReceived && modelData.core.state !== LinphoneEnums.CallState.OutgoingInit
&& modelData.core.state !== LinphoneEnums.CallState.OutgoingProgress && modelData.core.state
!== LinphoneEnums.CallState.OutgoingRinging && modelData.core.state
!== LinphoneEnums.CallState.OutgoingEarlyMedia && modelData.core.state
!== LinphoneEnums.CallState.IncomingEarlyMedia
icon.source: AppIcons.transferCall
style: ButtonStyle.noBackground
onClicked: {
mainItem.transferCallToAnotherRequested(modelData)
mainItem.transferCallToAnotherRequested(modelData);
}
//: Transfer call %1
Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName)
@ -101,21 +98,21 @@ ListView {
Button {
id: pausingButton
enabled: !(modelData.core.state === LinphoneEnums.CallState.PausedByRemote)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(28)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(28)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
Layout.alignment: Qt.AlignVCenter
leftPadding: Utils.getSizeWithScreenRatio(5)
rightPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
leftPadding: Utils.getSizeWithScreenRatio(5)
rightPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
property bool pausedByUser: modelData.core.state === LinphoneEnums.CallState.Paused
color: pausedByUser ? DefaultStyle.success_500_main : DefaultStyle.grey_500
contentImageColor: DefaultStyle.grey_0
KeyNavigation.right: endCallButton
KeyNavigation.left: endCallButton
icon.source: pausedByUser ? AppIcons.play : AppIcons.pause
icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18)
icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18)
onClicked: modelData.core.lSetPaused(!modelData.core.paused)
TextMetrics {
id: pauseMeter
@ -123,25 +120,24 @@ ListView {
font.bold: true
}
Accessible.name: (pausedByUser ?
//: Resume %1 call
qsTr("resume_call_name_accessible_name") :
//: Pause %1 call
qsTr("pause_call_name_accessible_name")
).arg(callInformationItem.callName)
//: Resume %1 call
qsTr("resume_call_name_accessible_name") :
//: Pause %1 call
qsTr("pause_call_name_accessible_name")).arg(callInformationItem.callName)
}
SmallButton {
id: endCallButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
style: ButtonStyle.phoneRed
KeyNavigation.left: pausingButton
KeyNavigation.right: pausingButton
contentImageColor: DefaultStyle.grey_0
icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18)
icon.width: Utils.getSizeWithScreenRatio(18)
icon.height: Utils.getSizeWithScreenRatio(18)
onClicked: {
mainWindow.callTerminatedByUser = true
mainWindow.endCall(modelData)
mainWindow.callTerminatedByUser = true;
mainWindow.endCall(modelData);
}
TextMetrics {
id: endMeter

View file

@ -9,64 +9,64 @@ ColumnLayout {
id: mainItem
property var call
property string objectName: "statsPanel"
spacing: Utils.getSizeWithScreenRatio(20)
spacing: Utils.getSizeWithScreenRatio(20)
RoundedPane {
Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
Layout.topMargin: Utils.getSizeWithScreenRatio(13)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
Layout.topMargin: Utils.getSizeWithScreenRatio(13)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
contentItem: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
Layout.alignment: Qt.AlignHCenter
Text {
//: "Audio"
text: qsTr("call_stats_audio_title")
//: "Audio"
text: qsTr("call_stats_audio_title")
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
Layout.alignment: Qt.AlignHCenter
Text {
text: mainItem.call ? mainItem.call.core.audioStats.codec : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.audioStats.bandwidth : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.audioStats.lossRate : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.audioStats.jitterBufferSize : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
@ -74,73 +74,75 @@ ColumnLayout {
}
RoundedPane {
Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
visible: mainItem.call && (mainItem.call.core.localVideoEnabled || mainItem.call.core.remoteVideoEnabled)
contentItem: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
Layout.alignment: Qt.AlignHCenter
Text {
//: "Vidéo"
text: qsTr("call_stats_video_title")
//: "Vidéo"
text: qsTr("call_stats_video_title")
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
Layout.alignment: Qt.AlignHCenter
Text {
text: mainItem.call ? mainItem.call.core.videoStats.codec : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.videoStats.bandwidth : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.videoStats.lossRate : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.videoStats.resolution : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
text: mainItem.call ? mainItem.call.core.videoStats.fps : ""
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
}
}
Item{Layout.fillHeight: true}
Item {
Layout.fillHeight: true
}
}

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
// ---------------------------------------------------------------------
// Separated file to show a single image bigger in chat message
// The FileView file does not allow that as it is a Loader and the image
@ -23,7 +22,7 @@ AnimatedImage {
mipmap: false//SettingsModel.mipmapEnabled
autoTransform: true
fillMode: Image.PreserveAspectFit
source: contentGui && UtilsCpp.isAnimatedImage(contentGui.core.filePath) ? ('file:/'+ contentGui.core.filePath) : ""
source: contentGui && UtilsCpp.isAnimatedImage(contentGui.core.filePath) ? ('file:/' + contentGui.core.filePath) : ""
// sourceSize.width: implicitWidth
// sourceSize.height: implicitHeight
states: State {
@ -38,19 +37,21 @@ AnimatedImage {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
mainItem.state = containsMouse ? 'hovered' : ''
}
onPressed: (mouse) => {
mouse.accepted = true
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
mainItem.state = containsMouse ? 'hovered' : '';
}
onPressed: mouse => {
mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile();
}
}
}
}

View file

@ -13,76 +13,77 @@ Item {
// used for creating a voice recording message
property var chatMessageObj
property ChatMessageGui chatMessage: chatMessageObj && chatMessageObj.value || null
property bool isPlaying : soudPlayerLoader.item && soudPlayerLoader.item.core.playbackState === LinphoneEnums.PlaybackState.PlayingState
property bool isPlaying: soudPlayerLoader.item && soudPlayerLoader.item.core.playbackState
=== LinphoneEnums.PlaybackState.PlayingState
onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop()
property bool recording: false
property RecorderGui recorderGui: recorderLoader.item || null
signal voiceRecordingMessageCreationRequested(RecorderGui recorderGui)
signal stopRecording()
signal endOfFileReached()
signal stopRecording
signal endOfFileReached
// auto play if follows a voice recording
function requestPlaying() {
if(soudPlayerLoader.item) {
soudPlayerLoader.item.play(true)
if (soudPlayerLoader.item) {
soudPlayerLoader.item.play(true);
}
}
function createVoiceMessageInChat(chat) {
if (recorderLoader.item) {
mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat)
mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat);
} else {
//: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: Failed to create voice message : error in recorder
qsTr("information_popup_voice_message_error_message"), false)
//: Failed to create voice message : error in recorder
qsTr("information_popup_voice_message_error_message"), false);
}
}
Loader {
id: soudPlayerLoader
property int duration: mainItem.chatMessageContentGui
? mainItem.chatMessageContentGui.core.fileDuration
: item
? item.core.duration
: 0
property int duration: mainItem.chatMessageContentGui ? mainItem.chatMessageContentGui.core.fileDuration : item
? item.core.duration : 0
property int position: item?.core.position || 0
active: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.isVoiceRecording
sourceComponent: SoundPlayerGui {
id: soundPlayerGui
source: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.filePath
function play(restartIfPlaying){
if(mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)){// Pause the play
soundPlayerGui.core.lPause()
} else if (restartIfPlaying) { //Play from scratch
soundPlayerGui.core.lRestart()
} else {// Play the audio
soundPlayerGui.core.lPlay()
function play(restartIfPlaying) {
if (mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)) {
// Pause the play
soundPlayerGui.core.lPause();
} else if (restartIfPlaying) {
//Play from scratch
soundPlayerGui.core.lRestart();
} else {
// Play the audio
soundPlayerGui.core.lPlay();
}
}
onStopped: {
mediaProgressBar.value = 101
mediaProgressBar.value = 101;
}
onPositionChanged: {
mediaProgressBar.progressPosition = soudPlayerLoader.position
mediaProgressBar.value = 100 * ( mediaProgressBar.progressPosition / soudPlayerLoader.duration)
mediaProgressBar.progressPosition = soudPlayerLoader.position;
mediaProgressBar.value = 100 * (mediaProgressBar.progressPosition / soudPlayerLoader.duration);
}
onSourceChanged: if (source != "") {
core.lOpen() // Open the file and allow seeking
mediaProgressBar.value = 0
mediaProgressBar.refresh()
}
onErrorChanged: (error) => {
//: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false)
}
core.lOpen(); // Open the file and allow seeking
mediaProgressBar.value = 0;
mediaProgressBar.refresh();
}
onErrorChanged: error => {
//: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false);
}
onEofReached: {
mainItem.endOfFileReached()
mainItem.endOfFileReached();
}
}
}
Loader {
id: recorderLoader
active: mainItem.recording && !mainItem.chatMessageContentGui
@ -93,57 +94,55 @@ Item {
Connections {
target: mainItem
function onStopRecording() {
recorderLoader.item.core.lStop()
recorderLoader.item.core.lStop();
}
}
sourceComponent: RecorderGui {
id: recorderGui
onReady: core.lStart()
onStateChanged: (state) => {
if (state === LinphoneEnums.RecorderState.Running) mediaProgressBar.start()
if (state === LinphoneEnums.RecorderState.Closed) {
mediaProgressBar.stop()
mainItem.voiceRecordingMessageCreationRequested(recorderGui)
}
}
onStateChanged: state => {
if (state === LinphoneEnums.RecorderState.Running)
mediaProgressBar.start();
if (state === LinphoneEnums.RecorderState.Closed) {
mediaProgressBar.stop();
mainItem.voiceRecordingMessageCreationRequested(recorderGui);
}
}
}
}
MediaProgressBar{
MediaProgressBar {
id: mediaProgressBar
anchors.fill: parent
progressDuration: soudPlayerLoader.active
? soudPlayerLoader.duration
: recorderLoader
? recorderLoader.duration
: chatMessageContentGui.core.fileDuration
progressDuration: soudPlayerLoader.active ? soudPlayerLoader.duration : recorderLoader ? recorderLoader.duration :
chatMessageContentGui.core.fileDuration
progressPosition: 0
value: 0
recording: recorderLoader.state === LinphoneEnums.RecorderState.Running
function refresh(){
if(soudPlayerLoader.item){
soudPlayerLoader.item.core.lRefreshPosition()
function refresh() {
if (soudPlayerLoader.item) {
soudPlayerLoader.item.core.lRefreshPosition();
} else if (recorderLoader.item) {
recorderLoader.item.core.lRefresh()
recorderLoader.item.core.lRefresh();
}
}
onEndReached:{
if(soudPlayerLoader.item)
soudPlayerLoader.item.core.lStop()
onEndReached: {
if (soudPlayerLoader.item)
soudPlayerLoader.item.core.lStop();
}
onPlayStopButtonToggled: {
if(soudPlayerLoader.item) {
soudPlayerLoader.item.play()
if (soudPlayerLoader.item) {
soudPlayerLoader.item.play();
} else if (recorderLoader.item) {
recorderLoader.item.core.lStop()
recorderLoader.item.core.lStop();
}
}
onRefreshPositionRequested: refresh()
onSeekRequested: (ms) => {
if(soudPlayerLoader.active) {
soudPlayerLoader.item.core.lSeek(ms)
}
}
onSeekRequested: ms => {
if (soudPlayerLoader.active) {
soudPlayerLoader.item.core.lSeek(ms);
}
}
}
}
}

View file

@ -9,235 +9,241 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
clip: true
id: mainItem
clip: true
property SearchBar searchBar
property bool loading: false
property string searchText: searchBar?.text
property alias chatProxy: chatProxy
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property SearchBar searchBar
property bool loading: false
property string searchText: searchBar?.text
property alias chatProxy: chatProxy
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property ChatGui currentChatGui: model.getAt(currentIndex) || null
onCurrentChatGuiChanged: positionViewAtIndex(currentIndex, ListView.Center)
property ChatGui chatToSelect: null
property ChatGui chatToSelectLater: null
onChatToSelectChanged: {
if (chatToSelect) {
// first clear the chatToSelect property in case we need to
// force adding the chat to the list and the layout changes
var toselect = chatToSelect
chatToSelect = null
selectChat(toselect, true)
}
}
property ChatGui currentChatGui: model.getAt(currentIndex) || null
onCurrentChatGuiChanged: positionViewAtIndex(currentIndex, ListView.Center)
property ChatGui chatToSelect: null
property ChatGui chatToSelectLater: null
onChatToSelectChanged: {
if (chatToSelect) {
// first clear the chatToSelect property in case we need to
// force adding the chat to the list and the layout changes
var toselect = chatToSelect;
chatToSelect = null;
selectChat(toselect, true);
}
}
onChatClicked: (chat) => {selectChat(chat)}
signal markAllAsRead()
signal chatClicked(ChatGui chat)
onChatClicked: chat => {
selectChat(chat);
}
model: ChatProxy {
id: chatProxy
filterText: mainItem.searchText
onFilterTextChanged: {
chatToSelectLater = currentChatGui
}
onModelAboutToBeReset: {
loading = true
}
onModelReset: {
loading = false
if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater)
mainItem.chatToSelectLater = null
}
else if (mainItem.chatToSelect) {
selectChat(mainItem.chatToSelect)
mainItem.chatToSelect = null
} else {
selectChat(mainItem.currentChatGui)
}
}
onChatAdded: (chat) => {
mainItem.chatToSelect = chat
}
onRowsRemoved: {
var index = mainItem.currentIndex
mainItem.currentIndex = -1
mainItem.currentIndex = index
}
onLayoutChanged: {
loading = false
if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater)
mainItem.chatToSelectLater = null
}
else if (mainItem.chatToSelect) {
selectChat(mainItem.chatToSelect)
mainItem.chatToSelect = null
}
else {
selectChat(mainItem.currentChatGui)
}
}
}
// flickDeceleration: 10000
spacing: Utils.getSizeWithScreenRatio(10)
signal markAllAsRead
signal chatClicked(ChatGui chat)
function selectChat(chatGui, force) {
var index = chatProxy.findChatIndex(chatGui)
// force adding chat to list if it already exists
// but has not been added to the list yet because
// it is empty and hide_empty_chatrooms is set
if (index === -1 && force === true && chatGui) {
if (chatProxy.addChatInList(chatGui)) {
var index = chatProxy.findChatIndex(chatGui)
}
}
mainItem.currentIndex = index
}
model: ChatProxy {
id: chatProxy
filterText: mainItem.searchText
onFilterTextChanged: {
chatToSelectLater = currentChatGui;
}
onModelAboutToBeReset: {
loading = true;
}
onModelReset: {
loading = false;
if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater);
mainItem.chatToSelectLater = null;
} else if (mainItem.chatToSelect) {
selectChat(mainItem.chatToSelect);
mainItem.chatToSelect = null;
} else {
selectChat(mainItem.currentChatGui);
}
}
onChatAdded: chat => {
mainItem.chatToSelect = chat;
}
onRowsRemoved: {
var index = mainItem.currentIndex;
mainItem.currentIndex = -1;
mainItem.currentIndex = index;
}
onLayoutChanged: {
loading = false;
if (mainItem.chatToSelectLater) {
selectChat(mainItem.chatToSelectLater);
mainItem.chatToSelectLater = null;
} else if (mainItem.chatToSelect) {
selectChat(mainItem.chatToSelect);
mainItem.chatToSelect = null;
} else {
selectChat(mainItem.currentChatGui);
}
}
}
// flickDeceleration: 10000
spacing: Utils.getSizeWithScreenRatio(10)
// remove binding loop
onContentHeightChanged: Qt.callLater(function () {
if (mainItem)
mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0
})
function selectChat(chatGui, force) {
var index = chatProxy.findChatIndex(chatGui);
// force adding chat to list if it already exists
// but has not been added to the list yet because
// it is empty and hide_empty_chatrooms is set
if (index === -1 && force === true && chatGui) {
if (chatProxy.addChatInList(chatGui)) {
var index = chatProxy.findChatIndex(chatGui);
}
}
mainItem.currentIndex = index;
}
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0
// remove binding loop
onContentHeightChanged: Qt.callLater(function () {
if (mainItem)
mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0;
})
//----------------------------------------------------------------
function moveToCurrentItem() {
if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem)
}
onCurrentItemChanged: {
moveToCurrentItem()
}
// Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem()
}
Behavior on contentY {
NumberAnimation {
id: moveAnimation
duration: 500
easing.type: Easing.OutExpo
alwaysRunToEnd: true
}
}
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
currentIndex = 0
// //----------------------------------------------------------------
//----------------------------------------------------------------
function moveToCurrentItem() {
if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem);
}
onCurrentItemChanged: {
moveToCurrentItem();
}
// Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem();
}
Behavior on contentY {
NumberAnimation {
id: moveAnimation
duration: 500
easing.type: Easing.OutExpo
alwaysRunToEnd: true
}
}
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
// //----------------------------------------------------------------
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea.
// So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
delegate: FocusScope {
visible: !mainItem.loading
width: mainItem.width
height: Utils.getSizeWithScreenRatio(63)
Connections {
target: mainItem
function onMarkAllAsRead() {modelData.core.lMarkAsRead()}
}
RowLayout {
z: 1
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(11)
anchors.rightMargin: Utils.getSizeWithScreenRatio(11)
anchors.topMargin: Utils.getSizeWithScreenRatio(9)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(9)
spacing: Utils.getSizeWithScreenRatio(10)
Avatar {
property var contactObj: modelData ? UtilsCpp.findFriendByAddress(modelData.core.peerAddress) : null
contact: contactObj?.value || null
displayNameVal: modelData && modelData.core.avatarUri || ""
secured: modelData?.core.isSecured || false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
// isConference: modelData.core.isConference
shadowEnabled: false
asynchronous: false
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(5)
Text {
id: friendAddress
Layout.fillWidth: true
maximumLineCount: 1
text: modelData ? modelData.core.title : ""
textFormat: Text.PlainText
color: DefaultStyle.main2_800
font {
pixelSize: Typography.p1.pixelSize
weight: unreadCount.unread > 0 ? Typography.p2.weight : Typography.p1.weight
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(5)
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea.
// So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1
delegate: FocusScope {
visible: !mainItem.loading
width: mainItem.width
height: Utils.getSizeWithScreenRatio(63)
Connections {
target: mainItem
function onMarkAllAsRead() {
modelData.core.lMarkAsRead();
}
}
RowLayout {
z: 1
anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(11)
anchors.rightMargin: Utils.getSizeWithScreenRatio(11)
anchors.topMargin: Utils.getSizeWithScreenRatio(9)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(9)
spacing: Utils.getSizeWithScreenRatio(10)
Avatar {
property var contactObj: modelData ? UtilsCpp.findFriendByAddress(modelData.core.peerAddress) : null
contact: contactObj?.value || null
displayNameVal: modelData && modelData.core.avatarUri || ""
secured: modelData?.core.isSecured || false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
// isConference: modelData.core.isConference
shadowEnabled: false
asynchronous: false
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(5)
Text {
id: friendAddress
Layout.fillWidth: true
maximumLineCount: 1
text: modelData ? modelData.core.title : ""
textFormat: Text.PlainText
color: DefaultStyle.main2_800
font {
pixelSize: Typography.p1.pixelSize
weight: unreadCount.unread > 0 ? Typography.p2.weight : Typography.p1.weight
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(5)
Layout.fillWidth: true
EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isReply && !remoteComposingInfo.visible
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isReply &&
!remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.reply
colorizationColor: DefaultStyle.main2_500
colorizationColor: DefaultStyle.main2_500
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
}
EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isForward && !remoteComposingInfo.visible
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isForward &&
!remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.forward
colorizationColor: DefaultStyle.main2_500
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
}
EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.hasFileContent && !remoteComposingInfo.visible
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.hasFileContent
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.paperclip
colorizationColor: DefaultStyle.main2_500
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
}
EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isVoiceRecording && !remoteComposingInfo.visible
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isVoiceRecording
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.waveform
colorizationColor: DefaultStyle.main2_500
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
}
EffectImage {
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isCalendarInvite && !remoteComposingInfo.visible
visible: modelData != undefined && modelData.core.lastMessage && modelData.core.lastMessage.core.isCalendarInvite
&& !remoteComposingInfo.visible
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.calendarBlank
colorizationColor: DefaultStyle.main2_500
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
}
Text {
id: lastMessageText
Layout.fillWidth: true
@ -258,207 +264,195 @@ ListView {
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
italic: modelData?.core.sendingText !== ""
italic: modelData?.core.sendingText !== ""
}
//: %1 is writing
text: modelData
? modelData.core.composingName !== ""
? qsTr("chat_message_is_writing_info").arg(modelData.core.composingName)
: modelData.core.sendingText !== ""
? qsTr("chat_message_draft_sending_text").arg(modelData.core.sendingText)
: ""
: ""
text: modelData ? modelData.core.composingName !== "" ? qsTr("chat_message_is_writing_info").arg(
modelData.core.composingName) : modelData.core.sendingText !== "" ? qsTr(
"chat_message_draft_sending_text").arg(modelData.core.sendingText) : "" : ""
}
}
}
ColumnLayout {
Layout.alignment: Qt.AlignRight
RowLayout {
Item{Layout.fillWidth: true}
Text {
color: DefaultStyle.main2_500_main
property string format: modelData && UtilsCpp.isCurrentYear(modelData.core.lastUpdatedTime) ? "dd/MM" : "dd/MM/yy"
text: modelData ? UtilsCpp.formatDate(modelData.core.lastUpdatedTime, true, false, format) : ""
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
capitalization: Font.Capitalize
}
}
}
}
}
ColumnLayout {
Layout.alignment: Qt.AlignRight
RowLayout {
Item {
Layout.fillWidth: true
}
Text {
color: DefaultStyle.main2_500_main
property string format: modelData && UtilsCpp.isCurrentYear(modelData.core.lastUpdatedTime) ? "dd/MM" : "dd/MM/yy"
text: modelData ? UtilsCpp.formatDate(modelData.core.lastUpdatedTime, true, false, format) : ""
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
capitalization: Font.Capitalize
}
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Item {Layout.fillWidth: true}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Item {
Layout.fillWidth: true
}
EffectImage {
visible: modelData?.core.ephemeralEnabled || false
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main2_400
imageSource: AppIcons.clockCountDown
}
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main2_400
imageSource: AppIcons.clockCountDown
}
EffectImage {
visible: modelData != undefined && !modelData.core.isEncrypted && AppCpp.currentAccount
&& AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress
!== ""
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.warning_700
imageSource: AppIcons.lockSimpleOpen
}
EffectImage {
visible: modelData != undefined && !modelData.core.isEncrypted && AppCpp.currentAccount && AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress !== ""
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.warning_700
imageSource: AppIcons.lockSimpleOpen
}
EffectImage {
visible: modelData != undefined && modelData?.core.muted
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main2_400
imageSource: AppIcons.bellSlash
}
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main2_400
imageSource: AppIcons.bellSlash
}
UnreadNotification {
id: unreadCount
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
unread: modelData?.core.unreadMessagesCount || false
}
EffectImage {
visible: modelData?.core.lastMessage && modelData?.core.lastMessageState !== LinphoneEnums.ChatMessageState.StateIdle
&& !modelData.core.lastMessage.core.isRemoteMessage || false
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main1_500_main
imageSource: modelData
? modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDelivered
? AppIcons.envelope
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDeliveredToUser
? AppIcons.check
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateNotDelivered
? AppIcons.warningCircle
: modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDisplayed
? AppIcons.checks
: ""
: ""
}
}
}
PopupButton {
id: chatroomPopup
// z: 1
popup.x: 0
popup.padding: Utils.getSizeWithScreenRatio(10)
visible: mouseArea.containsMouse || hovered || popup.opened
enabled: visible
popup.contentItem: ColumnLayout {
id: unreadCount
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
unread: modelData?.core.unreadMessagesCount || false
}
EffectImage {
visible: modelData?.core.lastMessage && modelData?.core.lastMessageState
!== LinphoneEnums.ChatMessageState.StateIdle && !modelData.core.lastMessage.core.isRemoteMessage || false
Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(14) : 0
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
colorizationColor: DefaultStyle.main1_500_main
imageSource: modelData ? modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateDelivered
? AppIcons.envelope : modelData.core.lastMessageState
=== LinphoneEnums.ChatMessageState.StateDeliveredToUser ? AppIcons.check :
modelData.core.lastMessageState === LinphoneEnums.ChatMessageState.StateNotDelivered
? AppIcons.warningCircle : modelData.core.lastMessageState
=== LinphoneEnums.ChatMessageState.StateDisplayed ? AppIcons.checks : "" : ""
}
}
}
PopupButton {
id: chatroomPopup
// z: 1
popup.x: 0
popup.padding: Utils.getSizeWithScreenRatio(10)
visible: mouseArea.containsMouse || hovered || popup.opened
enabled: visible
popup.contentItem: ColumnLayout {
IconLabelButton {
//: "Mute"
text: modelData
? modelData.core.muted
? qsTr("chat_room_unmute")
: qsTr("chat_room_mute")
: ""
//: "Mute"
text: modelData ? modelData.core.muted ? qsTr("chat_room_unmute") : qsTr("chat_room_mute") : ""
icon.source: modelData ? modelData.core.muted ? AppIcons.bell : AppIcons.bellSlash : ""
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
modelData.core.muted = !modelData.core.muted
chatroomPopup.close()
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
modelData.core.muted = !modelData.core.muted;
chatroomPopup.close();
}
}
IconLabelButton {
visible: modelData && modelData.core.unreadMessagesCount !== 0 || false
//: "Mark as read"
text: qsTr("chat_room_mark_as_read")
icon.source: AppIcons.checks
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
modelData.core.lMarkAsRead()
chatroomPopup.close()
}
}
ColumnLayout {
spacing: parent.spacing
visible: modelData && !modelData.core.isReadOnly && modelData.core.isGroupChat || false
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
color: DefaultStyle.main2_400
}
IconLabelButton {
//: "leave"
text: qsTr("chat_room_leave")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
//: leave the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_leave_chat_popup_title"),
//: You will not be able to send or receive messages in this conversation anymore. Do You want to continue ?
qsTr("chat_list_leave_chat_popup_message"),
"",
function(confirmed) {
if (confirmed) {
modelData.core.lLeave()
chatroomPopup.close()
}
})
}
style: ButtonStyle.hoveredBackground
}
}
Rectangle {
visible: deleteButton.visible
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
color: DefaultStyle.main2_400
}
IconLabelButton {
id: deleteButton
//: "Delete"
text: qsTr("chat_room_delete")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
//: Delete the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_delete_chat_popup_title"),
//: This conversation and all its messages will be deleted. Do You want to continue ?
qsTr("chat_list_delete_chat_popup_message"),
"",
function(confirmed) {
if (confirmed) {
modelData.core.lDelete()
chatroomPopup.close()
}
})
}
style: ButtonStyle.hoveredBackgroundRed
}
}
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onContainsMouseChanged: {
if (containsMouse)
mainItem.lastMouseContainsIndex = index
else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1
}
Rectangle {
anchors.fill: parent
opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
visible: mainItem.lastMouseContainsIndex === index || mainItem.currentIndex === index
}
onPressed: {
if (pressedButtons & Qt.RightButton) {
chatroomPopup.open()
} else {
mainItem.chatClicked(modelData)
}
}
}
}
}
IconLabelButton {
visible: modelData && modelData.core.unreadMessagesCount !== 0 || false
//: "Mark as read"
text: qsTr("chat_room_mark_as_read")
icon.source: AppIcons.checks
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
modelData.core.lMarkAsRead();
chatroomPopup.close();
}
}
ColumnLayout {
spacing: parent.spacing
visible: modelData && !modelData.core.isReadOnly && modelData.core.isGroupChat || false
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
color: DefaultStyle.main2_400
}
IconLabelButton {
//: "leave"
text: qsTr("chat_room_leave")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
//: leave the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_leave_chat_popup_title"),
//: You will not be able to send or receive messages in this conversation anymore. Do You want to continue ?
qsTr("chat_list_leave_chat_popup_message"), "", function (confirmed) {
if (confirmed) {
modelData.core.lLeave();
chatroomPopup.close();
}
});
}
style: ButtonStyle.hoveredBackground
}
}
Rectangle {
visible: deleteButton.visible
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(1)
color: DefaultStyle.main2_400
}
IconLabelButton {
id: deleteButton
//: "Delete"
text: qsTr("chat_room_delete")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
Layout.fillWidth: true
onClicked: {
//: Delete the conversation ?
mainWindow.showConfirmationLambdaPopup(qsTr("chat_list_delete_chat_popup_title"),
//: This conversation and all its messages will be deleted. Do You want to continue ?
qsTr("chat_list_delete_chat_popup_message"), "", function (confirmed) {
if (confirmed) {
modelData.core.lDelete();
chatroomPopup.close();
}
});
}
style: ButtonStyle.hoveredBackgroundRed
}
}
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onContainsMouseChanged: {
if (containsMouse)
mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1;
}
Rectangle {
anchors.fill: parent
opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
visible: mainItem.lastMouseContainsIndex === index || mainItem.currentIndex === index
}
onPressed: {
if (pressedButtons & Qt.RightButton) {
chatroomPopup.open();
} else {
mainItem.chatClicked(modelData);
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -14,30 +14,30 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
property ChatMessageGui chatMessageGui: null
property bool isRemoteMessage: chatMessageGui? chatMessageGui.core.isRemoteMessage : false
property bool isRemoteMessage: chatMessageGui ? chatMessageGui.core.isRemoteMessage : false
property ChatGui chatGui: null
signal isFileHoveringChanged(bool isFileHovering)
signal lastSelectedTextChanged(string selectedText)
// signal conferenceIcsCopied()
signal mouseEvent(MouseEvent event)
signal endOfVoiceRecordingReached()
signal requestAutoPlayVoiceRecording()
signal endOfVoiceRecordingReached
signal requestAutoPlayVoiceRecording
property string selectedText
property color textColor
property string searchedTextPart
property int fileBorderWidth : 0
property int fileBorderWidth: 0
property int maxWidth
spacing: Utils.getSizeWithScreenRatio(5)
property ChatMessageContentProxy filescontentProxy: ChatMessageContentProxy {
filterType: ChatMessageContentProxy.FilterContentType.File
chatMessageGui: mainItem.chatMessageGui
}
// VOICE MESSAGES
Repeater {
id: messagesVoicesList
@ -57,7 +57,7 @@ ColumnLayout {
Connections {
target: mainItem
function onRequestAutoPlayVoiceRecording() {
audioContent.requestPlaying()
audioContent.requestPlaying();
}
}
// width: conferenceList.width
@ -68,14 +68,14 @@ ColumnLayout {
Repeater {
id: conferenceList
visible: count > 0
model: ChatMessageContentProxy{
model: ChatMessageContentProxy {
filterType: ChatMessageContentProxy.FilterContentType.Conference
chatMessageGui: mainItem.chatMessageGui
}
delegate: ChatMessageInvitationBubble {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(490)
conferenceInfoGui: modelData.core.conferenceInfo
onMouseEvent: (event) => mainItem.mouseEvent(event)
onMouseEvent: event => mainItem.mouseEvent(event)
}
}
// SINGLE FILE
@ -83,9 +83,7 @@ ColumnLayout {
id: singleImageFile
cache: false
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit
@ -93,9 +91,7 @@ ColumnLayout {
AnimatedImageFileView {
id: singleAnimatedImageFile
visible: mainItem.filescontentProxy.count === 1 && source !== "" && UtilsCpp.isAnimatedImage(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
Layout.preferredHeight: paintedHeight
Layout.alignment: Qt.AlignHCenter
@ -107,22 +103,20 @@ ColumnLayout {
onStatusChanged: {
if (status == Image.Ready) {
if (singleAnimatedImageFile.initialization) {
initialSourceWidth = sourceSize.width
initialSourceHeight = sourceSize.height
singleAnimatedImageFile.initialization = false
initialSourceWidth = sourceSize.width;
initialSourceHeight = sourceSize.height;
singleAnimatedImageFile.initialization = false;
}
var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth)
sourceSize.height = Math.round((sourceW/initialSourceWidth) * initialSourceHeight)
sourceSize.width = sourceW
var sourceW = Math.min(initialSourceWidth, mainItem.maxWidth);
sourceSize.height = Math.round((sourceW / initialSourceWidth) * initialSourceHeight);
sourceSize.width = sourceW;
}
}
}
VideoFileView {
id: singleVideoFile
visible: mainItem.filescontentProxy.count === 1 && UtilsCpp.isVideo(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
contentGui: mainItem.filescontentProxy.count === 1 ? mainItem.filescontentProxy.getChatMessageContentAtIndex(0) : null
Layout.fillWidth: true
width: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
height: Math.min(Utils.getSizeWithScreenRatio(285), mainItem.maxWidth)
@ -135,13 +129,11 @@ ColumnLayout {
// FILES
ChatFilesGridLayout {
id: messageFilesList
visible: mainItem.filescontentProxy.count > 0
&& !singleImageFile.visible
&& !singleAnimatedImageFile.visible
&& !singleVideoFile.visible
visible: mainItem.filescontentProxy.count > 0 && !singleImageFile.visible && !singleAnimatedImageFile.visible &&
!singleVideoFile.visible
Layout.fillWidth: visible
Layout.fillHeight: visible
maxWidth: Utils.getSizeWithScreenRatio(115*3)
maxWidth: Utils.getSizeWithScreenRatio(115 * 3)
// Layout.fillHeight: true
proxyModel: visible ? mainItem.filescontentProxy : null
// onIsHoveringFileChanged: mainItem.isFileHoveringChanged(isHoveringFile)

View file

@ -9,16 +9,15 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
spacing: 0
id: mainItem
spacing: 0
width: Utils.getSizeWithScreenRatio(490)
property ConferenceInfoGui conferenceInfoGui
property var conferenceInfo: conferenceInfoGui?.core
property string timeRangeText: ""
property bool linkHovered: false
signal mouseEvent(MouseEvent event)
function updateTimeRange() {
@ -36,9 +35,8 @@ ColumnLayout {
let offsetHours = Math.floor(offsetMinutes / 60);
let timeZone = "UTC" + (offsetHours >= 0 ? "+" : "") + offsetHours;
timeRangeText =
qsTr("ics_bubble_meeting_from") + startTime +
qsTr("ics_bubble_meeting_to") + endTime + " (" + timeZone + ")";
timeRangeText = qsTr("ics_bubble_meeting_from") + startTime + qsTr("ics_bubble_meeting_to") + endTime + " ("
+ timeZone + ")";
}
Control.Control {
@ -56,23 +54,19 @@ ColumnLayout {
}
contentItem: ColumnLayout {
Text {
visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated
|| conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled
text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated
//: Meeting has been updated
? qsTr("ics_bubble_meeting_modified") + " :"
: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled
//: Meeting has been canceled
? qsTr("ics_bubble_meeting_cancelled") + " :"
: ""
visible: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated || conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled
text: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
//: Meeting has been updated
qsTr("ics_bubble_meeting_modified") + " :" : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled ?
//: Meeting has been canceled
qsTr("ics_bubble_meeting_cancelled") + " :" : ""
font: Typography.p2
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ?
DefaultStyle.main2_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
DefaultStyle.warning_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
DefaultStyle.danger_500_main :
DefaultStyle.main2_600
color: conferenceInfo.state == LinphoneEnums.ConferenceInfoState.New ? DefaultStyle.main2_600 : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Updated ? DefaultStyle.warning_600 : conferenceInfo.state
== LinphoneEnums.ConferenceInfoState.Cancelled ? DefaultStyle.danger_500_main :
DefaultStyle.main2_600
}
RowLayout {
@ -170,18 +164,16 @@ ColumnLayout {
style: ButtonStyle.noBackground
icon.source: AppIcons.calendarPlus
onClicked: {
conferenceInfo.exportConferenceToICS()
conferenceInfo.exportConferenceToICS();
}
}
}
Text {
//: from %1 to %2 (UTC%3)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0
? "+" + conferenceInfo.timeZoneModel.offsetFromUtc/3600
: conferenceInfo.timeZoneModel.offsetFromUtc/3600
text: qsTr("").arg(
conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(
conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc)
property string offsetFromUtc: conferenceInfo.timeZoneModel.offsetFromUtc > 0 ? "+" + conferenceInfo.timeZoneModel.offsetFromUtc
/ 3600 : conferenceInfo.timeZoneModel.offsetFromUtc / 3600
text: qsTr("").arg(conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(conferenceInfo.endDateTime.toLocaleString(
Qt.locale(), "hh:mm")).arg(offsetFromUtc)
color: DefaultStyle.main2_500_main
font: Typography.p4
}
@ -195,8 +187,7 @@ ColumnLayout {
}
}
}
Rectangle {
visible: conferenceInfo.description.length > 0 || conferenceInfo.participantCount > 0
Layout.fillWidth: true
@ -225,7 +216,7 @@ ColumnLayout {
MouseArea {
anchors.fill: parent
cursorShape: mainItem.linkHovered ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: (mouse) => mouseEvent(mouse)
onClicked: mouse => mouseEvent(mouse)
acceptedButtons: Qt.AllButtons // Send all to parent
}
@ -234,7 +225,7 @@ ColumnLayout {
color: DefaultStyle.grey_0
radius: Utils.getSizeWithScreenRatio(10)
}
contentItem: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(10)
@ -259,14 +250,14 @@ ColumnLayout {
maximumLineCount: 3
elide: Text.ElideRight
visible: conferenceInfo.description.length > 0
onLinkActivated: (link) => {
if (link.startsWith('sip'))
UtilsCpp.createCall(link)
else
Qt.openUrlExternally(link)
}
onLinkActivated: link => {
if (link.startsWith('sip'))
UtilsCpp.createCall(link);
else
Qt.openUrlExternally(link);
}
onHoveredLinkChanged: {
mainItem.linkHovered = hoveredLink !== ""
mainItem.linkHovered = hoveredLink !== "";
}
}
}
@ -297,9 +288,9 @@ ColumnLayout {
text: qsTr("ics_bubble_join")
visible: !SettingsCpp.disableMeetingsFeature && conferenceInfo.state != LinphoneEnums.ConferenceInfoState.Cancelled
onClicked: {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfoGui)
UtilsCpp.smartShowWindow(callsWindow)
var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfoGui);
UtilsCpp.smartShowWindow(callsWindow);
}
}
}

View file

@ -5,418 +5,415 @@ import QtQuick.Controls.Basic as Control
import Qt.labs.qmlmodels
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
spacing: Utils.getSizeWithScreenRatio(4)
property ChatGui chat
property color backgroundColor
property bool lastItemVisible: false
property int lastIndexFoundWithFilter: -1
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool loading: false
property bool isEncrypted: chat && chat.core.isEncrypted
property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress !== ""
highlightFollowsCurrentItem: true
id: mainItem
spacing: Utils.getSizeWithScreenRatio(4)
property ChatGui chat
property color backgroundColor
property bool lastItemVisible: false
property int lastIndexFoundWithFilter: -1
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool loading: false
property bool isEncrypted: chat && chat.core.isEncrypted
property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== ""
&& AppCpp.currentAccount.core.conferenceFactoryAddress !== ""
highlightFollowsCurrentItem: true
verticalLayoutDirection: ListView.BottomToTop
signal showReactionsForMessageRequested(ChatMessageGui chatMessage)
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
signal replyToMessageRequested(ChatMessageGui chatMessage)
signal forwardMessageRequested(ChatMessageGui chatMessage)
signal editMessageRequested(ChatMessageGui chatMessage)
signal requestHighlight(int indexToHighlight)
signal requestAutoPlayVoiceRecording(int indexToPlay)
signal searchMessageByIdRequested(string id)
currentIndex: -1
verticalLayoutDirection: ListView.BottomToTop
signal showReactionsForMessageRequested(ChatMessageGui chatMessage)
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
signal replyToMessageRequested(ChatMessageGui chatMessage)
signal forwardMessageRequested(ChatMessageGui chatMessage)
signal editMessageRequested(ChatMessageGui chatMessage)
signal requestHighlight(int indexToHighlight)
signal requestAutoPlayVoiceRecording(int indexToPlay)
signal searchMessageByIdRequested(string id)
currentIndex: -1
property string filterText
onFilterTextChanged: {
lastIndexFoundWithFilter = -1
if (filterText === "") return
eventLogProxy.filterText = filterText
var indexVisible = indexAt(contentX, contentY)
eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true)
}
signal findIndexWithFilter(bool forward)
property bool searchForward: true
onFindIndexWithFilter: (forward) => {
searchForward = forward
eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false)
}
onSearchMessageByIdRequested: (id) => {
eventLogProxy.findChatMessageById(id)
}
property string filterText
onFilterTextChanged: {
lastIndexFoundWithFilter = -1;
if (filterText === "")
return;
eventLogProxy.filterText = filterText;
var indexVisible = indexAt(contentX, contentY);
eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true);
}
signal findIndexWithFilter(bool forward)
property bool searchForward: true
onFindIndexWithFilter: forward => {
searchForward = forward;
eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false);
}
onSearchMessageByIdRequested: id => {
eventLogProxy.findChatMessageById(id);
}
Button {
visible: !mainItem.lastItemVisible
icon.source: AppIcons.downArrow
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20)
anchors.bottom: parent.bottom
style: ButtonStyle.main
anchors.right: parent.right
anchors.bottomMargin: Utils.getSizeWithScreenRatio(18)
anchors.rightMargin: Utils.getSizeWithScreenRatio(18)
onClicked: {
var index = eventLogProxy.findFirstUnreadIndex()
mainItem.positionViewAtIndex(index, ListView.Contain)
eventLogProxy.markIndexAsRead(index)
}
UnreadNotification {
anchors.top: parent.top
anchors.right: parent.right
anchors.topMargin: Utils.getSizeWithScreenRatio(-5)
anchors.rightMargin: Utils.getSizeWithScreenRatio(-5)
unread: mainItem.chat?.core.unreadMessagesCount || 0
}
}
Button {
visible: !mainItem.lastItemVisible
icon.source: AppIcons.downArrow
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20)
anchors.bottom: parent.bottom
style: ButtonStyle.main
anchors.right: parent.right
anchors.bottomMargin: Utils.getSizeWithScreenRatio(18)
anchors.rightMargin: Utils.getSizeWithScreenRatio(18)
onClicked: {
var index = eventLogProxy.findFirstUnreadIndex();
mainItem.positionViewAtIndex(index, ListView.Contain);
eventLogProxy.markIndexAsRead(index);
}
UnreadNotification {
anchors.top: parent.top
anchors.right: parent.right
anchors.topMargin: Utils.getSizeWithScreenRatio(-5)
anchors.rightMargin: Utils.getSizeWithScreenRatio(-5)
unread: mainItem.chat?.core.unreadMessagesCount || 0
}
}
onAtYBeginningChanged: if (atYBeginning && count !== 0) {
eventLogProxy.displayMore()
}
onAtYEndChanged: if (atYEnd && chat && count !== 0) {
chat.core.lMarkAsRead()
}
onAtYBeginningChanged: if (atYBeginning && count !== 0) {
eventLogProxy.displayMore();
}
onAtYEndChanged: if (atYEnd && chat && count !== 0) {
chat.core.lMarkAsRead();
}
model: EventLogProxy {
id: eventLogProxy
chatGui: mainItem.chat
filterText: mainItem.filterText
initialDisplayItems: 20
displayItemsStep: 20
onModelAboutToBeReset: {
loading = true
}
onModelReset: loading = false
onModelUpdated: {
loading = false
var index = eventLogProxy.findFirstUnreadIndex()
var itemToSelect = mainItem.itemAtIndex(index)
mainItem.positionViewAtIndex(index, ListView.Beginning)
var lastMessage = itemAtIndex(0)
mainItem.lastItemVisible = lastMessage.isFullyVisible
eventLogProxy.markIndexAsRead(index)
}
onEventInsertedByUser: (index) => {
mainItem.positionViewAtIndex(index, ListView.Beginning)
}
onIndexWithFilterFound: (index) => {
if (index !== -1) {
currentIndex = index
mainItem.positionViewAtIndex(index, ListView.Center)
mainItem.requestHighlight(index)
mainItem.lastIndexFoundWithFilter = index
} else {
if (mainItem.lastIndexFoundWithFilter !== index) {
//: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"),
mainItem.searchForward
//: Last result reached
? qsTr("info_popup_last_result_message")
//: First result reached
: qsTr("info_popup_first_result_message"), false)
mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center)
mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter)
}
else {
//: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"),
//: No result found
qsTr("info_popup_no_result_message"), false)
}
}
}
onFoundMessagById: (index) => {
if (index !== -1) {
currentIndex = index
mainItem.positionViewAtIndex(index, ListView.Center)
mainItem.requestHighlight(index)
}
}
}
model: EventLogProxy {
id: eventLogProxy
chatGui: mainItem.chat
filterText: mainItem.filterText
initialDisplayItems: 20
displayItemsStep: 20
onModelAboutToBeReset: {
loading = true;
}
onModelReset: loading = false
onModelUpdated: {
loading = false;
var index = eventLogProxy.findFirstUnreadIndex();
var itemToSelect = mainItem.itemAtIndex(index);
mainItem.positionViewAtIndex(index, ListView.Beginning);
var lastMessage = itemAtIndex(0);
mainItem.lastItemVisible = lastMessage.isFullyVisible;
eventLogProxy.markIndexAsRead(index);
}
onEventInsertedByUser: index => {
mainItem.positionViewAtIndex(index, ListView.Beginning);
}
onIndexWithFilterFound: index => {
if (index !== -1) {
currentIndex = index;
mainItem.positionViewAtIndex(index, ListView.Center);
mainItem.requestHighlight(index);
mainItem.lastIndexFoundWithFilter = index;
} else {
if (mainItem.lastIndexFoundWithFilter !== index) {
//: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), mainItem.searchForward ?
//: Last result reached
qsTr("info_popup_last_result_message") :
//: First result reached
qsTr("info_popup_first_result_message"), false);
mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center);
mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter);
} else {
//: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"),
//: No result found
qsTr("info_popup_no_result_message"), false);
}
}
}
onFoundMessagById: index => {
if (index !== -1) {
currentIndex = index;
mainItem.positionViewAtIndex(index, ListView.Center);
mainItem.requestHighlight(index);
}
}
}
footer: Item {
visible: mainItem.chat && !mainItem.loading
height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(30)
width: headerMessage.width
anchors.horizontalCenter: parent.horizontalCenter
Control.Control {
id: headerMessage
visible: mainItem.showEncryptedInfo
property int topMargin: Utils.getSizeWithScreenRatio(mainItem.contentHeight > mainItem.height ? 30 : 50)
property int bottomMargin: Utils.getSizeWithScreenRatio(30)
anchors.topMargin: topMargin
anchors.bottomMargin: bottomMargin
anchors.top: parent.top
padding: Utils.getSizeWithScreenRatio(10)
background: Rectangle {
color: "transparent"
border.color: DefaultStyle.main2_200
border.width: Utils.getSizeWithScreenRatio(2)
radius: Utils.getSizeWithScreenRatio(10)
}
contentItem: RowLayout {
EffectImage {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(23)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(23)
imageSource: mainItem.isEncrypted ? AppIcons.lockSimple : AppIcons.lockSimpleOpen
colorizationColor: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2)
Text {
text: mainItem.isEncrypted
//: End to end encrypted chat
? qsTr("chat_message_list_encrypted_header_title")
//: This conversation is not encrypted !
: qsTr("unencrypted_conversation_warning")
Layout.fillWidth: true
color: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
Text {
text: mainItem.isEncrypted
//: Messages in this conversation are e2e encrypted. \n Only your correspondent can decrypt them.
? qsTr("chat_message_list_encrypted_header_message")
//: Messages are not end to end encrypted, \n may sure you don't share any sensitive information !
: qsTr("chat_message_list_not_encrypted_header_message")
Layout.fillWidth: true
color: DefaultStyle.grey_400
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
}
}
}
}
}
}
footerPositioning: mainItem.contentHeight > mainItem.height ? ListView.InlineFooter : ListView.PullBackFooter
headerPositioning: ListView.OverlayHeader
header: Control.Control {
visible: composeLayout.composingName !== "" && composeLayout.composingName !== undefined
width: mainItem.width
// height: visible ? contentItem.implicitHeight + topPadding + bottomPadding : 0
z: mainItem.z + 2
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
background: Rectangle {
anchors.fill: parent
color: mainItem.backgroundColor
}
contentItem: RowLayout {
id: composeLayout
property var composingName: mainItem.chat?.core.composingName
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
_address: mainItem.chat?.core.composingAddress
}
Text {
Layout.fillWidth: true
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
}
//: %1 is writing
text: qsTr("chat_message_is_writing_info").arg(composeLayout.composingName)
}
}
}
footer: Item {
visible: mainItem.chat && !mainItem.loading
height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(
30)
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
anchors.verticalCenter: mainItem.verticalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
Dialog {
id: messageDeletionDialog
width: Utils.getSizeWithScreenRatio(637)
//: "Supprimer le message ?"
title: qsTr("conversation_dialog_delete_chat_message_title")
property var chatMessage
buttons: RowLayout {
id: buttonsLayout
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
spacing: Utils.getSizeWithScreenRatio(20)
MediumButton {
id: firstButtonId
text: qsTr("conversation_dialog_delete_locally_label")
style: ButtonStyle.main
onClicked: {
messageDeletionDialog.chatMessage.core.lDelete()
messageDeletionDialog.close()
}
KeyNavigation.left: thirdButtonId
KeyNavigation.right: secondButtonId
width: headerMessage.width
anchors.horizontalCenter: parent.horizontalCenter
Control.Control {
id: headerMessage
visible: mainItem.showEncryptedInfo
property int topMargin: Utils.getSizeWithScreenRatio(mainItem.contentHeight > mainItem.height ? 30 : 50)
property int bottomMargin: Utils.getSizeWithScreenRatio(30)
anchors.topMargin: topMargin
anchors.bottomMargin: bottomMargin
anchors.top: parent.top
padding: Utils.getSizeWithScreenRatio(10)
background: Rectangle {
color: "transparent"
border.color: DefaultStyle.main2_200
border.width: Utils.getSizeWithScreenRatio(2)
radius: Utils.getSizeWithScreenRatio(10)
}
contentItem: RowLayout {
EffectImage {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(23)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(23)
imageSource: mainItem.isEncrypted ? AppIcons.lockSimple : AppIcons.lockSimpleOpen
colorizationColor: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
}
MediumButton {
id: secondButtonId
text: qsTr("conversation_dialog_delete_for_everyone_label")
style: ButtonStyle.main
onClicked: {
messageDeletionDialog.chatMessage.core.lRetract()
messageDeletionDialog.close()
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2)
Text {
text: mainItem.isEncrypted ?
//: End to end encrypted chat
qsTr("chat_message_list_encrypted_header_title") :
//: This conversation is not encrypted !
qsTr("unencrypted_conversation_warning")
Layout.fillWidth: true
color: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
KeyNavigation.left: firstButtonId
KeyNavigation.right: thirdButtonId
}
MediumButton {
id: thirdButtonId
text: qsTr("dialog_cancel")
style: ButtonStyle.secondary
onClicked: {
messageDeletionDialog.close()
Text {
text: mainItem.isEncrypted ?
//: Messages in this conversation are e2e encrypted. \n Only your correspondent can decrypt them.
qsTr("chat_message_list_encrypted_header_message") :
//: Messages are not end to end encrypted, \n may sure you don't share any sensitive information !
qsTr("chat_message_list_not_encrypted_header_message")
Layout.fillWidth: true
color: DefaultStyle.grey_400
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
}
}
KeyNavigation.left: secondButtonId
KeyNavigation.right: firstButtonId
}
}
}
delegate: DelegateChooser {
role: "eventType"
DelegateChoice {
roleValue: "chatMessage"
delegate: ChatMessage {
id: chatMessageDelegate
visible: !mainItem.loading
property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
chatMessage: modelData.core.chatMessageGui
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible
}
}
Component.onCompleted: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible
}
}
chat: mainItem.chat
searchedTextPart: mainItem.filterText
maxWidth: Math.round(mainItem.width * (3/4))
width: mainItem.width
property var previousIndex: index - 1
property ChatMessageGui nextChatMessage: index <= 0
? null
: eventLogProxy.getEventAtIndex(index-1)
? eventLogProxy.getEventAtIndex(index-1).core.chatMessageGui
: null
property var previousFromAddress: eventLogProxy.getEventAtIndex(index+1)?.core.chatMessage?.fromAddress
backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100
isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress
anchors.right: !isRemoteMessage && parent
? parent.right
: undefined
}
}
footerPositioning: mainItem.contentHeight > mainItem.height ? ListView.InlineFooter : ListView.PullBackFooter
headerPositioning: ListView.OverlayHeader
header: Control.Control {
visible: composeLayout.composingName !== "" && composeLayout.composingName !== undefined
width: mainItem.width
// height: visible ? contentItem.implicitHeight + topPadding + bottomPadding : 0
z: mainItem.z + 2
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
background: Rectangle {
anchors.fill: parent
color: mainItem.backgroundColor
}
contentItem: RowLayout {
id: composeLayout
property var composingName: mainItem.chat?.core.composingName
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
_address: mainItem.chat?.core.composingAddress
}
Text {
Layout.fillWidth: true
font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
}
//: %1 is writing
text: qsTr("chat_message_is_writing_info").arg(composeLayout.composingName)
}
}
}
onMessageDeletionRequested: {
if (chatMessage.core.isOutgoing && chatMessage.core.isRetractable && !chatMessage.core.isRetracted) {
messageDeletionDialog.chatMessage = chatMessage
messageDeletionDialog.open()
} else {
chatMessage.core.lDelete()
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
anchors.verticalCenter: mainItem.verticalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
Dialog {
id: messageDeletionDialog
width: Utils.getSizeWithScreenRatio(637)
//: "Supprimer le message ?"
title: qsTr("conversation_dialog_delete_chat_message_title")
property var chatMessage
buttons: RowLayout {
id: buttonsLayout
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
spacing: Utils.getSizeWithScreenRatio(20)
MediumButton {
id: firstButtonId
text: qsTr("conversation_dialog_delete_locally_label")
style: ButtonStyle.main
onClicked: {
messageDeletionDialog.chatMessage.core.lDelete();
messageDeletionDialog.close();
}
KeyNavigation.left: thirdButtonId
KeyNavigation.right: secondButtonId
}
MediumButton {
id: secondButtonId
text: qsTr("conversation_dialog_delete_for_everyone_label")
style: ButtonStyle.main
onClicked: {
messageDeletionDialog.chatMessage.core.lRetract();
messageDeletionDialog.close();
}
KeyNavigation.left: firstButtonId
KeyNavigation.right: thirdButtonId
}
MediumButton {
id: thirdButtonId
text: qsTr("dialog_cancel")
style: ButtonStyle.secondary
onClicked: {
messageDeletionDialog.close();
}
KeyNavigation.left: secondButtonId
KeyNavigation.right: firstButtonId
}
}
}
delegate: DelegateChooser {
role: "eventType"
DelegateChoice {
roleValue: "chatMessage"
delegate: ChatMessage {
id: chatMessageDelegate
visible: !mainItem.loading
property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
chatMessage: modelData.core.chatMessageGui
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible;
}
}
onMessageEditionRequested: mainItem.editMessageRequested(chatMessage)
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
onSearchMessageByIdRequested: (id) => mainItem.searchMessageByIdRequested(id)
onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage)
onEndOfVoiceRecordingReached: {
if (nextChatMessage && nextChatMessage.core.isVoiceRecording) mainItem.requestAutoPlayVoiceRecording(index - 1)
}
Connections {
target: mainItem
function onRequestHighlight(indexToHighlight) {
if (indexToHighlight === index) {
requestHighlight()
}
}
function onRequestAutoPlayVoiceRecording(indexToPlay) {
if (indexToPlay === index) {
chatMessageDelegate.requestAutoPlayVoiceRecording()
}
}
}
}
Component.onCompleted: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible;
}
}
chat: mainItem.chat
searchedTextPart: mainItem.filterText
maxWidth: Math.round(mainItem.width * (3 / 4))
width: mainItem.width
property var previousIndex: index - 1
property ChatMessageGui nextChatMessage: index <= 0 ? null : eventLogProxy.getEventAtIndex(index - 1)
? eventLogProxy.getEventAtIndex(index - 1).core.chatMessageGui : null
property var previousFromAddress: eventLogProxy.getEventAtIndex(index + 1)?.core.chatMessage?.fromAddress
backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100
isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress
anchors.right: !isRemoteMessage && parent ? parent.right : undefined
onMessageDeletionRequested: {
if (chatMessage.core.isOutgoing && chatMessage.core.isRetractable && !chatMessage.core.isRetracted) {
messageDeletionDialog.chatMessage = chatMessage;
messageDeletionDialog.open();
} else {
chatMessage.core.lDelete();
}
}
onMessageEditionRequested: mainItem.editMessageRequested(chatMessage)
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
onSearchMessageByIdRequested: id => mainItem.searchMessageByIdRequested(id)
onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage)
onEndOfVoiceRecordingReached: {
if (nextChatMessage && nextChatMessage.core.isVoiceRecording)
mainItem.requestAutoPlayVoiceRecording(index - 1);
}
Connections {
target: mainItem
function onRequestHighlight(indexToHighlight) {
if (indexToHighlight === index) {
requestHighlight();
}
}
function onRequestAutoPlayVoiceRecording(indexToPlay) {
if (indexToPlay === index) {
chatMessageDelegate.requestAutoPlayVoiceRecording();
}
}
}
Connections {
target: chatMessage.core
onIsRetractedChanged: {
if (chatMessage.core.isRetracted && chatMessage.core.isOutgoing) {
UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"),
//: The message has been deleted
qsTr("info_toast_deleted_message"), true)
UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"),
//: The message has been deleted
qsTr("info_toast_deleted_message"), true);
}
}
}
}
}
}
}
DelegateChoice {
roleValue: "event"
delegate: Item {
id: eventDelegate
visible: !mainItem.loading
property int yoff: Math.round(eventDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible
}
}
property bool showTopMargin: !header.visible && index == 0
width: mainItem.width
height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + eventItem.implicitHeight
Event {
id: eventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0
width: parent.width
eventLogGui: modelData
}
}
}
DelegateChoice {
roleValue: "ephemeralEvent"
delegate: Item {
id: ephemeralEventDelegate
visible: !mainItem.loading
property int yoff: Math.round(ephemeralEventDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible
}
}
property bool showTopMargin: !header.visible && index == 0
width: mainItem.width
//height: Utils.getSizeWithScreenRatio(40)
height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + ephemeralEventItem.height
EphemeralEvent {
id: ephemeralEventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0
eventLogGui: modelData
}
}
}
}
roleValue: "event"
delegate: Item {
id: eventDelegate
visible: !mainItem.loading
property int yoff: Math.round(eventDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible;
}
}
property bool showTopMargin: !header.visible && index == 0
width: mainItem.width
height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + eventItem.implicitHeight
Event {
id: eventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0
width: parent.width
eventLogGui: modelData
}
}
}
DelegateChoice {
roleValue: "ephemeralEvent"
delegate: Item {
id: ephemeralEventDelegate
visible: !mainItem.loading
property int yoff: Math.round(ephemeralEventDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: {
if (index === 0) {
mainItem.lastItemVisible = isFullyVisible;
}
}
property bool showTopMargin: !header.visible && index == 0
width: mainItem.width
//height: Utils.getSizeWithScreenRatio(40)
height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + ephemeralEventItem.height
EphemeralEvent {
id: ephemeralEventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0
eventLogGui: modelData
}
}
}
}
}

View file

@ -5,84 +5,89 @@ import Linphone
import UtilsCpp
// TODO : into Loader
// =============================================================================
TextEdit {
id: mainItem
property ChatMessageContentGui contentGui
property ChatGui chatGui: null
property string lastTextSelected : ''
property string lastTextSelected: ''
property string searchedTextPart
color: DefaultStyle.main2_700
// force restoring cursor in case we click on a mention, otherwise
// the cursor stays IBeam
onVisibleChanged: if (!visible) UtilsCpp.restoreGlobalCursor()
onVisibleChanged: if (!visible)
UtilsCpp.restoreGlobalCursor()
font {
pixelSize: (contentGui && UtilsCpp.isOnlyEmojis(contentGui.core.text)) ? Typography.h1.pixelSize : Typography.p1.pixelSize
pixelSize: (contentGui && UtilsCpp.isOnlyEmojis(contentGui.core.text)) ? Typography.h1.pixelSize :
Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
// property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth
visible: contentGui && contentGui.core.isText
textMargin: 0
readOnly: true
selectByMouse: true
text: contentGui.core.richFormatText
onSearchedTextPartChanged: {
contentGui.core.setSearchedTextPart(searchedTextPart)
contentGui.core.setSearchedTextPart(searchedTextPart);
}
textFormat: Text.RichText // To supports links and imgs.
wrapMode: TextEdit.Wrap
onLinkActivated: (link) => {
if (link.startsWith('sip'))
UtilsCpp.createCall(link)
else if (link.startsWith('mention:')) {
var mentionAddress = link.substring(8) // remove "mention:"
UtilsCpp.openContactAtAddress(mentionAddress);
}
else
Qt.openUrlExternally(link)
}
onSelectedTextChanged:{
if(selectedText != '') lastTextSelected = selectedText
onLinkActivated: link => {
if (link.startsWith('sip'))
UtilsCpp.createCall(link);
else if (link.startsWith('mention:')) {
var mentionAddress = link.substring(8); // remove "mention:"
UtilsCpp.openContactAtAddress(mentionAddress);
} else
Qt.openUrlExternally(link);
}
onSelectedTextChanged: {
if (selectedText != '')
lastTextSelected = selectedText;
}
onLinkHovered: {
if (hoveredLink !== "") UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
if (hoveredLink !== "")
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
}
onActiveFocusChanged: {
if(activeFocus) {
lastTextSelected = ''
}
else mouseArea.keepLastSelection = false
if (activeFocus) {
lastTextSelected = '';
} else
mouseArea.keepLastSelection = false;
// deselect()
}
MouseArea {
id: mouseArea
property bool keepLastSelection: false
property int lastStartSelection:0
property int lastEndSelection:0
property int lastStartSelection: 0
property int lastEndSelection: 0
anchors.fill: parent
propagateComposedEvents: true
hoverEnabled: true
scrollGestureEnabled: false
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.IBeamCursor)
else UtilsCpp.restoreGlobalCursor()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.IBeamCursor);
else
UtilsCpp.restoreGlobalCursor();
}
cursorShape: mainItem.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
acceptedButtons: Qt.LeftButton
onPressed: (mouse) => {
// if(!keepLastSelection) {
// lastStartSelection = parent.selectionStart
// lastEndSelection = parent.selectionEnd
// }
keepLastSelection = true
mouse.accepted = false
}
onPressed: mouse => {
// if(!keepLastSelection) {
// lastStartSelection = parent.selectionStart
// lastEndSelection = parent.selectionEnd
// }
keepLastSelection = true;
mouse.accepted = false;
}
}
}

View file

@ -1,5 +1,5 @@
/*
* MIT License
* MIT License
Copyright (c) 2023 AmirHosseinCH
@ -27,238 +27,241 @@ import QtQuick.Controls
import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// import EmojiModel
ColumnLayout {
id: mainItem
property var editor
property EmojiModel model: EmojiModel {
id: emojiModel
iconsPath: "image://emoji/emojiSvgs/"
iconsType: '.svg'
}
property var categories: ['Smileys & Emotion', 'People & Body', 'Animals & Nature',
'Food & Drink', 'Activities', 'Travel & Places', 'Objects', 'Symbols', 'Flags']
property var searchModel: ListModel {}
property bool searchMode: false
property int skinColor: -1
signal emojiClicked(string emoji)
id: mainItem
property var editor
property EmojiModel model: EmojiModel {
id: emojiModel
iconsPath: "image://emoji/emojiSvgs/"
iconsType: '.svg'
}
property var categories: ['Smileys & Emotion', 'People & Body', 'Animals & Nature', 'Food & Drink', 'Activities',
'Travel & Places', 'Objects', 'Symbols', 'Flags']
property var searchModel: ListModel {}
property bool searchMode: false
property int skinColor: -1
function changeSkinColor(index) {
if (index !== skinColors.current) {
skinColors.itemAt(skinColors.current + 1).scale = 0.6
skinColors.itemAt(index + 1).scale = 1
skinColors.current = index
mainItem.skinColor = index
}
}
function refreshSearchModel() {
searchModel.clear()
var searchResult = model.search(searchField.text, skinColor)
for (var i = 0; i < searchResult.length; ++i) {
searchModel.append({path: searchResult[i]})
}
}
RowLayout {
id: categoriesRow
Layout.preferredWidth: parent.width - Utils.getSizeWithScreenRatio(15)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(35)
Layout.leftMargin: Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
spacing: Utils.getSizeWithScreenRatio(searchField.widthSize > 0 ? 7 : 17)
clip: true
Image {
id: searchIcon
source: "image://emoji/icons/search.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21),Utils.getSizeWithScreenRatio(21))
visible: !mainItem.searchMode
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.searchMode = true
searchField.widthSize = categoriesRow.width - Utils.getSizeWithScreenRatio(25)
list.model = 1
searchField.focus = true
}
}
}
Image {
id: closeIcon
source: "image://emoji/icons/close.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21),Utils.getSizeWithScreenRatio(21))
visible: mainItem.searchMode
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.searchMode = false
searchField.widthSize = 0
list.model = mainItem.categories
searchField.clear()
}
}
}
TextField {
id: searchField
property int widthSize: 0
Layout.preferredWidth: widthSize
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
visible: widthSize > 0 ? true : false
placeholderText: 'Search Emoji'
Behavior on widthSize {
NumberAnimation {
duration: 400
}
}
background: Rectangle {
radius: Utils.getSizeWithScreenRatio(10)
border.color: DefaultStyle.main1_500_main
}
onTextChanged: {
text.length > 0 ? mainItem.refreshSearchModel() : mainItem.searchModel.clear()
}
}
Repeater {
id: cateIcons
property var blackSvg: ['emoji-smiley.svg', 'emoji-people.svg', 'emoji-animal.svg', 'emoji-food.svg',
'emoji-activity.svg', 'emoji-travel.svg', 'emoji-object.svg', 'emoji-symbol.svg', 'emoji-flag.svg']
property var blueSvg: ['emoji-smiley-blue.svg', 'emoji-people-blue.svg', 'emoji-animal-blue.svg',
'emoji-food-blue.svg', 'emoji-activity-blue.svg', 'emoji-travel-blue.svg', 'emoji-object-blue.svg',
'emoji-symbol-blue.svg', 'emoji-flag-blue.svg']
property int current: 0
model: 9
delegate: Image {
id: icon
source: "image://emoji/icons/" + cateIcons.blackSvg[index]
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(20),Utils.getSizeWithScreenRatio(20))
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (cateIcons.current !== index) {
icon.source = "image://emoji/icons/" + cateIcons.blueSvg[index]
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current]
cateIcons.current = index
}
list.positionViewAtIndex(index, ListView.Beginning)
}
}
}
Component.onCompleted: {
itemAt(0).source = "image://emoji/icons/" + cateIcons.blueSvg[0]
}
}
}
ListView {
id: list
width: mainItem.width
height: Utils.getSizeWithScreenRatio(250)
Layout.fillWidth: true
Layout.fillHeight: true
model: mainItem.categories
spacing: Utils.getSizeWithScreenRatio(30)
topMargin: Utils.getSizeWithScreenRatio(7)
bottomMargin: Utils.getSizeWithScreenRatio(7)
leftMargin: Utils.getSizeWithScreenRatio(12)
clip: true
delegate: GridLayout {
id: grid
property string category: mainItem.searchMode ? 'Search Result' : modelData
property int columnCount: Math.round(list.width / Utils.getSizeWithScreenRatio(50))
property int sc: grid.category === 'People & Body' ? mainItem.skinColor : -1
columns: columnCount
width: list.width
columnSpacing: Utils.getSizeWithScreenRatio(5)
Text {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
text: grid.category
color: Qt.rgba(0, 0, 0, 0.5)
font.pixelSize: Utils.getSizeWithScreenRatio(15)
horizontalAlignment: Text.AlignLeft
leftPadding: Utils.getSizeWithScreenRatio(6)
Layout.columnSpan: grid.columnCount != 0 ? grid.columnCount : 1
Layout.bottomMargin: Utils.getSizeWithScreenRatio(8)
}
Repeater {
model: mainItem.searchMode ? mainItem.searchModel : mainItem.model.count(grid.category)
delegate: Rectangle {
property alias es: emojiSvg
Layout.preferredWidth: Utils.getSizeWithScreenRatio(40)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(40)
radius: Utils.getSizeWithScreenRatio(40)
color: mouseArea.containsMouse ? '#e6e6e6' : '#ffffff'
Image {
id: emojiSvg
source: mainItem.searchMode ? path : mainItem.model.path(grid.category, index, grid.sc)
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(30),Utils.getSizeWithScreenRatio(30))
anchors.centerIn: parent
asynchronous: true
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
property string imageUrl: emojiSvg.source
onClicked: {
var emojiInFont = Utils.codepointFromFilename(UtilsCpp.getFilename(emojiSvg.source))
if (mainItem.editor) mainItem.editor.insert(mainItem.editor.cursorPosition, emojiInFont)
mainItem.emojiClicked(emojiInFont)
}
}
}
}
}
onContentYChanged: {
var index = list.indexAt(0, contentY + 15)
if (index !== -1 && index !== cateIcons.current) {
cateIcons.itemAt(index).source = "image://emoji/icons/" + cateIcons.blueSvg[index]
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current]
cateIcons.current = index
}
}
}
RowLayout {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(35)
Layout.alignment: Qt.AlignCenter
spacing: 10
Repeater {
id: skinColors
property var colors: ['#ffb84d', '#ffdab3', '#d2a479', '#ac7139', '#734b26', '#26190d']
property int current: -1
model: 6
delegate: Rectangle {
id: colorRect
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(3)
radius: Utils.getSizeWithScreenRatio(30)
scale: 0.65
color: skinColors.colors[index]
Behavior on scale {
NumberAnimation {
duration: 100
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.changeSkinColor(index - 1)
if (mainItem.searchMode) {
mainItem.refreshSearchModel();
}
}
}
}
Component.onCompleted: {
itemAt(0).scale = 1
}
}
}
signal emojiClicked(string emoji)
function changeSkinColor(index) {
if (index !== skinColors.current) {
skinColors.itemAt(skinColors.current + 1).scale = 0.6;
skinColors.itemAt(index + 1).scale = 1;
skinColors.current = index;
mainItem.skinColor = index;
}
}
function refreshSearchModel() {
searchModel.clear();
var searchResult = model.search(searchField.text, skinColor);
for (var i = 0; i < searchResult.length; ++i) {
searchModel.append({
path: searchResult[i]
});
}
}
RowLayout {
id: categoriesRow
Layout.preferredWidth: parent.width - Utils.getSizeWithScreenRatio(15)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(35)
Layout.leftMargin: Utils.getSizeWithScreenRatio(5)
Layout.alignment: Qt.AlignCenter
spacing: Utils.getSizeWithScreenRatio(searchField.widthSize > 0 ? 7 : 17)
clip: true
Image {
id: searchIcon
source: "image://emoji/icons/search.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21), Utils.getSizeWithScreenRatio(21))
visible: !mainItem.searchMode
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.searchMode = true;
searchField.widthSize = categoriesRow.width - Utils.getSizeWithScreenRatio(25);
list.model = 1;
searchField.focus = true;
}
}
}
Image {
id: closeIcon
source: "image://emoji/icons/close.svg"
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(21), Utils.getSizeWithScreenRatio(21))
visible: mainItem.searchMode
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.searchMode = false;
searchField.widthSize = 0;
list.model = mainItem.categories;
searchField.clear();
}
}
}
TextField {
id: searchField
property int widthSize: 0
Layout.preferredWidth: widthSize
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)
visible: widthSize > 0 ? true : false
placeholderText: 'Search Emoji'
Behavior on widthSize {
NumberAnimation {
duration: 400
}
}
background: Rectangle {
radius: Utils.getSizeWithScreenRatio(10)
border.color: DefaultStyle.main1_500_main
}
onTextChanged: {
text.length > 0 ? mainItem.refreshSearchModel() : mainItem.searchModel.clear();
}
}
Repeater {
id: cateIcons
property var blackSvg: ['emoji-smiley.svg', 'emoji-people.svg', 'emoji-animal.svg', 'emoji-food.svg',
'emoji-activity.svg', 'emoji-travel.svg', 'emoji-object.svg', 'emoji-symbol.svg', 'emoji-flag.svg']
property var blueSvg: ['emoji-smiley-blue.svg', 'emoji-people-blue.svg', 'emoji-animal-blue.svg',
'emoji-food-blue.svg', 'emoji-activity-blue.svg', 'emoji-travel-blue.svg', 'emoji-object-blue.svg',
'emoji-symbol-blue.svg', 'emoji-flag-blue.svg']
property int current: 0
model: 9
delegate: Image {
id: icon
source: "image://emoji/icons/" + cateIcons.blackSvg[index]
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(20), Utils.getSizeWithScreenRatio(20))
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (cateIcons.current !== index) {
icon.source = "image://emoji/icons/" + cateIcons.blueSvg[index];
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current];
cateIcons.current = index;
}
list.positionViewAtIndex(index, ListView.Beginning);
}
}
}
Component.onCompleted: {
itemAt(0).source = "image://emoji/icons/" + cateIcons.blueSvg[0];
}
}
}
ListView {
id: list
width: mainItem.width
height: Utils.getSizeWithScreenRatio(250)
Layout.fillWidth: true
Layout.fillHeight: true
model: mainItem.categories
spacing: Utils.getSizeWithScreenRatio(30)
topMargin: Utils.getSizeWithScreenRatio(7)
bottomMargin: Utils.getSizeWithScreenRatio(7)
leftMargin: Utils.getSizeWithScreenRatio(12)
clip: true
delegate: GridLayout {
id: grid
property string category: mainItem.searchMode ? 'Search Result' : modelData
property int columnCount: Math.round(list.width / Utils.getSizeWithScreenRatio(50))
property int sc: grid.category === 'People & Body' ? mainItem.skinColor : -1
columns: columnCount
width: list.width
columnSpacing: Utils.getSizeWithScreenRatio(5)
Text {
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
text: grid.category
color: Qt.rgba(0, 0, 0, 0.5)
font.pixelSize: Utils.getSizeWithScreenRatio(15)
horizontalAlignment: Text.AlignLeft
leftPadding: Utils.getSizeWithScreenRatio(6)
Layout.columnSpan: grid.columnCount != 0 ? grid.columnCount : 1
Layout.bottomMargin: Utils.getSizeWithScreenRatio(8)
}
Repeater {
model: mainItem.searchMode ? mainItem.searchModel : mainItem.model.count(grid.category)
delegate: Rectangle {
property alias es: emojiSvg
Layout.preferredWidth: Utils.getSizeWithScreenRatio(40)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(40)
radius: Utils.getSizeWithScreenRatio(40)
color: mouseArea.containsMouse ? '#e6e6e6' : '#ffffff'
Image {
id: emojiSvg
source: mainItem.searchMode ? path : mainItem.model.path(grid.category, index, grid.sc)
sourceSize: Qt.size(Utils.getSizeWithScreenRatio(30), Utils.getSizeWithScreenRatio(30))
anchors.centerIn: parent
asynchronous: true
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
property string imageUrl: emojiSvg.source
onClicked: {
var emojiInFont = Utils.codepointFromFilename(UtilsCpp.getFilename(emojiSvg.source));
if (mainItem.editor)
mainItem.editor.insert(mainItem.editor.cursorPosition, emojiInFont);
mainItem.emojiClicked(emojiInFont);
}
}
}
}
}
onContentYChanged: {
var index = list.indexAt(0, contentY + 15);
if (index !== -1 && index !== cateIcons.current) {
cateIcons.itemAt(index).source = "image://emoji/icons/" + cateIcons.blueSvg[index];
cateIcons.itemAt(cateIcons.current).source = "image://emoji/icons/" + cateIcons.blackSvg[cateIcons.current];
cateIcons.current = index;
}
}
}
RowLayout {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(35)
Layout.alignment: Qt.AlignCenter
spacing: 10
Repeater {
id: skinColors
property var colors: ['#ffb84d', '#ffdab3', '#d2a479', '#ac7139', '#734b26', '#26190d']
property int current: -1
model: 6
delegate: Rectangle {
id: colorRect
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(3)
radius: Utils.getSizeWithScreenRatio(30)
scale: 0.65
color: skinColors.colors[index]
Behavior on scale {
NumberAnimation {
duration: 100
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.changeSkinColor(index - 1);
if (mainItem.searchMode) {
mainItem.refreshSearchModel();
}
}
}
}
Component.onCompleted: {
itemAt(0).scale = 1;
}
}
}
}

View file

@ -45,4 +45,3 @@ RowLayout {
color: DefaultStyle.main2_200
}
}

View file

@ -4,12 +4,11 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
Item {
id: mainItem
property ChatMessageContentGui contentGui
@ -17,7 +16,7 @@ Item {
property string name: contentGui && contentGui.core.name
property string filePath: contentGui && contentGui.core.filePath
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
property bool isAnimatedImage: contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath) && UtilsCpp.fileExists(filePath)
property int fileSize: contentGui ? contentGui.core.fileSize : 0
property bool isTransferring
@ -28,29 +27,23 @@ Item {
// property to change default view display
property bool showAsSquare: true
// default image
property var imageSource: mainItem.contentGui
? UtilsCpp.isImage(mainItem.filePath)
? AppIcons.fileImage
: UtilsCpp.isPdf(mainItem.filePath)
? AppIcons.filePdf
: UtilsCpp.isText(mainItem.filePath)
? AppIcons.fileText
: AppIcons.file
: ''
property var imageSource: mainItem.contentGui ? UtilsCpp.isImage(mainItem.filePath) ? AppIcons.fileImage :
UtilsCpp.isPdf(mainItem.filePath) ? AppIcons.filePdf : UtilsCpp.isText(mainItem.filePath)
? AppIcons.fileText : AppIcons.file : ''
property var thumbnailFillMode: Image.PreserveAspectCrop
Connections {
enabled: contentGui
target: contentGui ? contentGui.core : null
function onMsgStateChanged(state) {
mainItem.isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress
|| state === LinphoneEnums.ChatMessageState.StateInProgress
mainItem.isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress || state
=== LinphoneEnums.ChatMessageState.StateInProgress;
}
}
// property bool isHovering: thumbnailProvider.state == 'hovered'
property bool isOutgoing: false
// ---------------------------------------------------------------------
// Thumbnail
// ---------------------------------------------------------------------
@ -107,33 +100,33 @@ Item {
color: DefaultStyle.grey_1000
anchors.fill: parent
// Video {
// id: videoThumbnail
// anchors.fill: parent
// position: 100
// source: mainItem.isVideo ? "file:///" + mainItem.filePath : ""
// fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop
EffectImage {
anchors.centerIn: parent
// visible: videoThumbnail.playbackState !== MediaPlayer.PlayingState
width: Utils.getSizeWithScreenRatio(24)
height: Utils.getSizeWithScreenRatio(24)
imageSource: AppIcons.playFill
colorizationColor: DefaultStyle.main2_0
}
// Text {
// z: parent.z + 1
// property int timeDisplayed: videoThumbnail.playbackState === MediaPlayer.PlayingState ? videoThumbnail.position : videoThumbnail.duration
// anchors.bottom: parent.bottom
// anchors.left: parent.left
// anchors.bottomMargin: Utils.getSizeWithScreenRatio(6)
// anchors.leftMargin: Utils.getSizeWithScreenRatio(6)
// text: UtilsCpp.formatDuration(timeDisplayed)
// color: DefaultStyle.grey_0
// font {
// pixelSize: Typography.d1.pixelSize
// weight: Typography.d1.weight
// }
// }
// id: videoThumbnail
// anchors.fill: parent
// position: 100
// source: mainItem.isVideo ? "file:///" + mainItem.filePath : ""
// fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop
EffectImage {
anchors.centerIn: parent
// visible: videoThumbnail.playbackState !== MediaPlayer.PlayingState
width: Utils.getSizeWithScreenRatio(24)
height: Utils.getSizeWithScreenRatio(24)
imageSource: AppIcons.playFill
colorizationColor: DefaultStyle.main2_0
}
// Text {
// z: parent.z + 1
// property int timeDisplayed: videoThumbnail.playbackState === MediaPlayer.PlayingState ? videoThumbnail.position : videoThumbnail.duration
// anchors.bottom: parent.bottom
// anchors.left: parent.left
// anchors.bottomMargin: Utils.getSizeWithScreenRatio(6)
// anchors.leftMargin: Utils.getSizeWithScreenRatio(6)
// text: UtilsCpp.formatDuration(timeDisplayed)
// color: DefaultStyle.grey_0
// font {
// pixelSize: Typography.d1.pixelSize
// weight: Typography.d1.weight
// }
// }
// }
}
}
@ -143,7 +136,7 @@ Item {
AnimatedImage {
id: animatedImageSource
mipmap: false//SettingsModel.mipmapEnabled
source: 'file:/'+ mainItem.filePath
source: 'file:/' + mainItem.filePath
autoTransform: true
fillMode: Image.PreserveAspectFit
}
@ -165,7 +158,7 @@ Item {
anchors.fill: parent
color: FileViewStyle.extension.background.color
radius: FileViewStyle.extension.radius
Rectangle {
color: DefaultStyle.main2_200
anchors.top: parent.top
@ -181,7 +174,7 @@ Item {
}
}
}
contentItem: Item {
Text {
id: fileName
@ -211,26 +204,29 @@ Item {
id: progressBar
anchors.centerIn: parent
to: 100
value: mainItem.contentGui ? (mainItem.fileSize>0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset / mainItem.fileSize) : 0) : to
value: mainItem.contentGui ? (mainItem.fileSize > 0 ? Math.floor(100 * mainItem.contentGui.core.fileOffset
/ mainItem.fileSize) : 0) : to
visible: mainItem.isTransferring && value != 0
/* Change format? Current is %
text: if(mainRow.contentGui){
var mainItem.fileSize = Utils.formatSize(mainRow.contentGui.core.mainItem.fileSize)
return progressBar.visible
? Utils.formatSize(mainRow.contentGui.core.fileOffset) + '/' + mainItem.fileSize
: mainItem.fileSize
}else
return ''
var mainItem.fileSize = Utils.formatSize(mainRow.contentGui.core.mainItem.fileSize)
return progressBar.visible
? Utils.formatSize(mainRow.contentGui.core.fileOffset) + '/' + mainItem.fileSize
: mainItem.fileSize
}else
return ''
*/
}
Rectangle {
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded)
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/
!mainItem.contentGui.core.wasDownloaded)
color: DefaultStyle.grey_0
opacity: 0.5
anchors.fill: parent
}
EffectImage {
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/ !mainItem.contentGui.core.wasDownloaded)
visible: thumbnailProvider.state === 'hovered' && mainItem.contentGui && (/*!mainItem.isOutgoing &&*/
!mainItem.contentGui.core.wasDownloaded)
anchors.centerIn: parent
imageSource: AppIcons.download
width: Utils.getSizeWithScreenRatio(24)
@ -265,7 +261,6 @@ Item {
width: parent.width / 2
height: parent.height
radius: parent.radius
}
EffectImage {
z: parent.z + 1
@ -302,15 +297,8 @@ Item {
Loader {
id: thumbnailProvider
anchors.fill: parent
sourceComponent: mainItem.contentGui
? mainItem.isAnimatedImage
? animatedImage
: mainItem.haveThumbnail
? thumbnailImage
: mainItem.showAsSquare
? defaultSquareView
: defaultView
: undefined
sourceComponent: mainItem.contentGui ? mainItem.isAnimatedImage ? animatedImage : mainItem.haveThumbnail
? thumbnailImage : mainItem.showAsSquare ? defaultSquareView : defaultView : undefined
states: State {
name: 'hovered'
@ -324,33 +312,34 @@ Item {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
thumbnailProvider.state = containsMouse ? 'hovered' : ''
}
onPressed: (mouse) => {
mouse.accepted = false
if(mainItem.isTransferring) {
mainItem.contentGui.core.lCancelDownloadFile()
mouse.accepted = true
}
else if(!mainItem.contentGui.core.wasDownloaded) {
mouse.accepted = true
mainItem.contentGui.core.lDownloadFile()
} else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
mouse.accepted = true
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
} else if (mainItem.contentGui) {
mouse.accepted = true
mainItem.contentGui.core.lOpenFile(true)// Show directory
}
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
thumbnailProvider.state = containsMouse ? 'hovered' : '';
}
onPressed: mouse => {
mouse.accepted = false;
if (mainItem.isTransferring) {
mainItem.contentGui.core.lCancelDownloadFile();
mouse.accepted = true;
} else if (!mainItem.contentGui.core.wasDownloaded) {
mouse.accepted = true;
mainItem.contentGui.core.lDownloadFile();
} else if (Utils.pointIsInItem(this, thumbnailProvider, mouse)) {
mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile();
} else if (mainItem.contentGui) {
mouse.accepted = true;
mainItem.contentGui.core.lOpenFile(true);// Show directory
}
}
}
}
}

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
// ---------------------------------------------------------------------
// Separated file to show a single image bigger in chat message
// The FileView file does not allow that as it is a Loader and the image
@ -33,18 +32,20 @@ Image {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
}
onPressed: (mouse) => {
mouse.accepted = true
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
}
onPressed: mouse => {
mouse.accepted = true;
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile();
}
}
}

View file

@ -5,7 +5,7 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
Rectangle {
@ -60,13 +60,15 @@ Rectangle {
// Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case
onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
else UtilsCpp.restoreGlobalCursor()
}
onPressed: (mouse) => {
mouse.accepted = true
mainItem.contentGui.core.lOpenFile()
if (containsMouse)
UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
}
onPressed: mouse => {
mouse.accepted = true;
mainItem.contentGui.core.lOpenFile();
}
}
EffectImage {
anchors.centerIn: parent
@ -76,4 +78,4 @@ Rectangle {
imageSource: AppIcons.playFill
colorizationColor: DefaultStyle.main2_0
}
}
}

View file

@ -9,412 +9,398 @@ import SettingsCpp
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Flickable {
id: mainItem
id: mainItem
flickableDirection: Flickable.VerticalFlick
flickableDirection: Flickable.VerticalFlick
property bool showInitials: true // Display Initials of Display name.
property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts.
property bool showFavorites: true // Display the favorites in the header
property bool hideSuggestions: false // Hide not stored contacts (not suggestions)
property bool showMe: true // Wether to display current account address or not (disabled for adding participants)
property string highlightText: searchText // Bold characters in Display name.
property var sourceFlags: LinphoneEnums.MagicSearchSource.All
property bool showInitials: true // Display Initials of Display name.
property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts.
property bool showFavorites: true // Display the favorites in the header
property bool hideSuggestions: false // Hide not stored contacts (not suggestions)
property bool showMe: true // Wether to display current account address or not (disabled for adding participants)
property string highlightText: searchText // Bold characters in Display name.
property var sourceFlags: LinphoneEnums.MagicSearchSource.All
property bool displayNameCapitalization: true // Capitalize display name.
property bool displayNameCapitalization: true // Capitalize display name.
property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts
// List of default address on selected contacts.
//property FriendGui selectedContact//: model.getAt(currentIndex) || null
property FriendGui highlightedContact
property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts
// List of default address on selected contacts.
//property FriendGui selectedContact//: model.getAt(currentIndex) || null
property FriendGui highlightedContact
property bool searchOnEmpty: true
property bool loading: false
property bool pauseSearch: false // true = don't search on text change
property bool searchOnEmpty: true
property bool loading: false
property bool pauseSearch: false // true = don't search on text change
// Model properties
// set searchBarText without specifying a model to bold
// matching names
property string searchBarText
property string searchText
// Binding is done on searchBarTextChanged
property ConferenceInfoGui confInfoGui
// Model properties
// set searchBarText without specifying a model to bold
// matching names
property string searchBarText
property string searchText
// Binding is done on searchBarTextChanged
property ConferenceInfoGui confInfoGui
property bool haveFavorites: false
property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool haveFavorites: false
property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property int count: contactsList.count + suggestionsList.count + favoritesList.count
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property int count: contactsList.count + suggestionsList.count + favoritesList.count
contentHeight: contentsLayout.height
rightMargin: itemsRightMargin
contentHeight: contentsLayout.height
rightMargin: itemsRightMargin
signal contactStarredChanged
signal contactDeletionRequested(FriendGui contact)
signal contactAddedToSelection(string address)
signal contactRemovedFromSelection(string address)
signal contactSelected(FriendGui contact)
signal contactStarredChanged
signal contactDeletionRequested(FriendGui contact)
signal contactAddedToSelection(string address)
signal contactRemovedFromSelection(string address)
signal contactSelected(FriendGui contact)
function selectContact(address) {
var index = contactsProxy.loadUntil(address) // Be sure to have this address in proxy if it exists
if (index != -1) {
contactsList.selectIndex(index)
}
return index
}
function addContactToSelection(address) {
if (multiSelectionEnabled) {
var indexInSelection = selectedContacts.indexOf(address)
if (indexInSelection == -1) {
selectedContacts.push(address)
contactAddedToSelection(address)
}
}
}
function removeContactFromSelection(indexInSelection) {
var addressToRemove = selectedContacts[indexInSelection]
if (indexInSelection != -1) {
selectedContacts.splice(indexInSelection, 1)
contactRemovedFromSelection(addressToRemove)
}
}
function removeSelectedContactByAddress(address) {
var index = selectedContacts.indexOf(address)
if (index != -1) {
selectedContacts.splice(index, 1)
contactRemovedFromSelection(address)
}
}
function haveAddress(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address)
return index != -1
}
function selectContact(address) {
var index = contactsProxy.loadUntil(address); // Be sure to have this address in proxy if it exists
if (index != -1) {
contactsList.selectIndex(index);
}
return index;
}
function addContactToSelection(address) {
if (multiSelectionEnabled) {
var indexInSelection = selectedContacts.indexOf(address);
if (indexInSelection == -1) {
selectedContacts.push(address);
contactAddedToSelection(address);
}
}
}
function removeContactFromSelection(indexInSelection) {
var addressToRemove = selectedContacts[indexInSelection];
if (indexInSelection != -1) {
selectedContacts.splice(indexInSelection, 1);
contactRemovedFromSelection(addressToRemove);
}
}
function removeSelectedContactByAddress(address) {
var index = selectedContacts.indexOf(address);
if (index != -1) {
selectedContacts.splice(index, 1);
contactRemovedFromSelection(address);
}
}
function haveAddress(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address);
return index != -1;
}
function getFirstContact() {
if (mainItem.showFavorites) {
var firstContact = favoritesList.itemAtIndex(0)
if (firstContact !== null) return firstContact
}
var firstContact = contactsList.itemAtIndex(0)
if (firstContact !== null) return firstContact
if (!mainItem.hideSuggestions) {
var firstContact = suggestionsList.itemAtIndex(0)
if (firstContact !== null) return firstContact
}
return null
}
function getFirstContact() {
if (mainItem.showFavorites) {
var firstContact = favoritesList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
}
var firstContact = contactsList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
if (!mainItem.hideSuggestions) {
var firstContact = suggestionsList.itemAtIndex(0);
if (firstContact !== null)
return firstContact;
}
return null;
}
function resetSelections() {
mainItem.highlightedContact = null
favoritesList.currentIndex = -1
contactsList.currentIndex = -1
suggestionsList.currentIndex = -1
}
function resetSelections() {
mainItem.highlightedContact = null;
favoritesList.currentIndex = -1;
contactsList.currentIndex = -1;
suggestionsList.currentIndex = -1;
}
function findNextList(item, count, direction) {
if (count == 3)
return null
var nextItem
switch (item) {
case suggestionsList:
nextItem = (direction > 0 ? favoritesList : contactsList)
break
case contactsList:
nextItem = (direction > 0 ? suggestionsList : favoritesList)
break
case favoritesList:
nextItem = (direction > 0 ? contactsList : suggestionsList)
break
default:
return null
}
if (nextItem.model.count > 0)
return nextItem
else
return findNextList(nextItem, count + 1, direction)
}
function findNextList(item, count, direction) {
if (count == 3)
return null;
var nextItem;
switch (item) {
case suggestionsList:
nextItem = (direction > 0 ? favoritesList : contactsList);
break;
case contactsList:
nextItem = (direction > 0 ? suggestionsList : favoritesList);
break;
case favoritesList:
nextItem = (direction > 0 ? contactsList : suggestionsList);
break;
default:
return null;
}
if (nextItem.model.count > 0)
return nextItem;
else
return findNextList(nextItem, count + 1, direction);
}
function updatePosition(list) {
Utils.updatePosition(mainItem, list)
}
function updatePosition(list) {
Utils.updatePosition(mainItem, list);
}
onHighlightedContactChanged: {
favoritesList.highlightedContact = highlightedContact
contactsList.highlightedContact = highlightedContact
suggestionsList.highlightedContact = highlightedContact
}
onHighlightedContactChanged: {
favoritesList.highlightedContact = highlightedContact;
contactsList.highlightedContact = highlightedContact;
suggestionsList.highlightedContact = highlightedContact;
}
onSearchBarTextChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText
}
}
onPauseSearchChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText
}
}
onSearchTextChanged: {
loading = true
}
onSearchBarTextChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText;
}
}
onPauseSearchChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText;
}
}
onSearchTextChanged: {
loading = true;
}
Keys.onPressed: event => {
if (!event.accepted) {
if (event.key == Qt.Key_Up
|| event.key == Qt.Key_Down) {
var newItem
var direction = (event.key == Qt.Key_Up ? -1 : 1)
if (suggestionsList.activeFocus)
newItem = findNextList(suggestionsList, 0,
direction)
else if (contactsList.activeFocus)
newItem = findNextList(contactsList, 0,
direction)
else if (favoritesList.activeFocus)
newItem = findNextList(favoritesList, 0,
direction)
else
newItem = findNextList(suggestionsList, 0,
direction)
if (newItem) {
newItem.selectIndex(
direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason : Qt.TabFocusReason)
event.accepted = true
}
}
}
}
Component.onCompleted: {
if (confInfoGui) {
for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(
confInfoGui.core.getParticipantAddressAt(i))
}
}
}
Keys.onPressed: event => {
if (!event.accepted) {
if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
var newItem;
var direction = (event.key == Qt.Key_Up ? -1 : 1);
if (suggestionsList.activeFocus)
newItem = findNextList(suggestionsList, 0, direction);
else if (contactsList.activeFocus)
newItem = findNextList(contactsList, 0, direction);
else if (favoritesList.activeFocus)
newItem = findNextList(favoritesList, 0, direction);
else
newItem = findNextList(suggestionsList, 0, direction);
if (newItem) {
newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason :
Qt.TabFocusReason);
event.accepted = true;
}
}
}
}
Component.onCompleted: {
if (confInfoGui) {
for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
}
}
}
Connections {
target: SettingsCpp
onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate()
}
}
Connections {
target: SettingsCpp
onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate();
}
}
property MagicSearchProxy mainModel: MagicSearchProxy {
id: magicSearchProxy
searchText: mainItem.searchText
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
sourceFlags: mainItem.sourceFlags
onModelReset: {
mainItem.resetSelections()
}
onResultsProcessed: {
mainItem.loading = false
mainItem.contentY = 0
}
property MagicSearchProxy mainModel: MagicSearchProxy {
id: magicSearchProxy
searchText: mainItem.searchText
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
sourceFlags: mainItem.sourceFlags
onModelReset: {
mainItem.resetSelections();
}
onResultsProcessed: {
mainItem.loading = false;
mainItem.contentY = 0;
}
onInitialized: {
if (mainItem.searchOnEmpty || searchText != '') {
mainItem.loading = true
forceUpdate()
}
}
}
onInitialized: {
if (mainItem.searchOnEmpty || searchText != '') {
mainItem.loading = true;
forceUpdate();
}
}
}
onAtYEndChanged: if (atYEnd) {
if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites)
favoritesProxy.displayMore()
else if (contactsProxy.haveMore && contactsList.expanded) {
contactsProxy.displayMore()
}
else
suggestionsProxy.displayMore()
}
Behavior on contentY {
NumberAnimation {
duration: 500
easing.type: Easing.OutExpo
}
}
onAtYEndChanged: if (atYEnd) {
if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites)
favoritesProxy.displayMore();
else if (contactsProxy.haveMore && contactsList.expanded) {
contactsProxy.displayMore();
} else
suggestionsProxy.displayMore();
}
Behavior on contentY {
NumberAnimation {
duration: 500
easing.type: Easing.OutExpo
}
}
Control.ScrollBar.vertical: ScrollBar {
id: scrollbar
z: 1
topPadding: Utils.getSizeWithScreenRatio(24) // Avoid to be on top of collapse button
active: true
interactive: true
visible: mainItem.contentHeight > mainItem.height
policy: Control.ScrollBar.AsNeeded
}
Control.ScrollBar.vertical: ScrollBar {
id: scrollbar
z: 1
topPadding: Utils.getSizeWithScreenRatio(24) // Avoid to be on top of collapse button
active: true
interactive: true
visible: mainItem.contentHeight > mainItem.height
policy: Control.ScrollBar.AsNeeded
}
ColumnLayout {
id: contentsLayout
width: mainItem.width
spacing: 0
ColumnLayout {
id: contentsLayout
width: mainItem.width
spacing: 0
BusyIndicator {
id: busyIndicator
visible: mainItem.loading
width: mainItem.busyIndicatorSize
height: mainItem.busyIndicatorSize
Layout.preferredWidth: mainItem.busyIndicatorSize
Layout.preferredHeight: mainItem.busyIndicatorSize
Layout.alignment: Qt.AlignCenter | Qt.AlignVCenter
}
BusyIndicator {
id: busyIndicator
visible: mainItem.loading
width: mainItem.busyIndicatorSize
height: mainItem.busyIndicatorSize
Layout.preferredWidth: mainItem.busyIndicatorSize
Layout.preferredHeight: mainItem.busyIndicatorSize
Layout.alignment: Qt.AlignCenter | Qt.AlignVCenter
}
ContactListView {
id: favoritesList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
sectionsWeight: mainItem.sectionsWeight
sectionsPixelSize: mainItem.sectionsPixelSize
interactive: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu
showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
//: "Favoris"
title: qsTr("car_favorites_contacts_title")
itemsRightMargin: mainItem.itemsRightMargin
ContactListView {
id: favoritesList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
sectionsWeight: mainItem.sectionsWeight
sectionsPixelSize: mainItem.sectionsPixelSize
interactive: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu
showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
//: "Favoris"
title: qsTr("car_favorites_contacts_title")
itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
}
onUpdatePosition: mainItem.updatePosition(favoritesList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
}
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(favoritesList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(index);
}
property MagicSearchProxy proxy: MagicSearchProxy {
id: favoritesProxy
parentProxy: mainItem.mainModel
showMe: mainItem.showMe
filterType: MagicSearchProxy.FilteringTypes.Favorites
}
model: mainItem.showFavorites
&& (mainItem.searchBarText == ''
|| mainItem.searchBarText == '*') ? proxy : []
}
property MagicSearchProxy proxy: MagicSearchProxy {
id: favoritesProxy
parentProxy: mainItem.mainModel
showMe: mainItem.showMe
filterType: MagicSearchProxy.FilteringTypes.Favorites
}
model: mainItem.showFavorites && (mainItem.searchBarText == '' || mainItem.searchBarText == '*') ? proxy : []
}
ContactListView {
id: contactsList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.topMargin: favoritesList.height > 0 ? Utils.getSizeWithScreenRatio(4) : 0
interactive: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu
showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
itemsRightMargin: mainItem.itemsRightMargin
//: 'Contacts'
title: qsTr("generic_address_picker_contacts_list_title")
ContactListView {
id: contactsList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.topMargin: favoritesList.height > 0 ? Utils.getSizeWithScreenRatio(4) : 0
interactive: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu
showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
itemsRightMargin: mainItem.itemsRightMargin
//: 'Contacts'
title: qsTr("generic_address_picker_contacts_list_title")
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
}
onUpdatePosition: mainItem.updatePosition(contactsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
}
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(contactsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(index);
}
model: MagicSearchProxy {
id: contactsProxy
parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App
| (mainItem.searchText != '*'
&& mainItem.searchText != ''
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap | MagicSearchProxy.FilteringTypes.CardDAV : 0)
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: 3 * initialDisplayItems / 2
onLocalFriendCreated: (index) => {
contactsList.selectIndex(index)
}
}
}
ContactListView {
id: suggestionsList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.topMargin: (contactsList.height + favoritesList.height) > 0 ? Utils.getSizeWithScreenRatio(4) : 0
interactive: false
showInitials: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showContactMenu: mainItem.showContactMenu
showDefaultAddress: true
showDisplayName: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
//: "Suggestions"
title: qsTr("generic_address_picker_suggestions_list_title")
itemsRightMargin: mainItem.itemsRightMargin
model: MagicSearchProxy {
id: contactsProxy
parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != ''
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap
| MagicSearchProxy.FilteringTypes.CardDAV : 0)
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: 3 * initialDisplayItems / 2
onLocalFriendCreated: index => {
contactsList.selectIndex(index);
}
}
}
ContactListView {
id: suggestionsList
visible: contentHeight > 0
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
Layout.topMargin: (contactsList.height + favoritesList.height) > 0 ? Utils.getSizeWithScreenRatio(4) : 0
interactive: false
showInitials: false
highlightText: mainItem.highlightText
showActions: mainItem.showActions
showContactMenu: mainItem.showContactMenu
showDefaultAddress: true
showDisplayName: false
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
//: "Suggestions"
title: qsTr("generic_address_picker_suggestions_list_title")
itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui)
}
onUpdatePosition: mainItem.updatePosition(suggestionsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(
contact)
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address)
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(
index)
}
model: MagicSearchProxy {
id: suggestionsProxy
parentProxy: mainItem.mainModel
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded
? 0
: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: maxDisplayItems = initialDisplayItems
}
}
}
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => {
mainItem.contactSelected(contactGui);
}
onUpdatePosition: mainItem.updatePosition(suggestionsList)
onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested(contact);
}
onAddContactToSelection: address => {
mainItem.addContactToSelection(address);
}
onRemoveContactFromSelection: index => {
mainItem.removeContactFromSelection(index);
}
model: MagicSearchProxy {
id: suggestionsProxy
parentProxy: mainItem.mainModel
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : Math.max(20, Math.round(2
* mainItem.height / Utils.getSizeWithScreenRatio(63)))
onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: maxDisplayItems = initialDisplayItems
}
}
}
}

View file

@ -11,34 +11,21 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// Fill contact, account or call
// Initials will be displayed if there isn't any avatar.
// TODO : get FriendGui from Call.
Loader{
Loader {
id: mainItem
property AccountGui account: null
property FriendGui contact: null
property CallGui call: null
property bool isConference: false
property bool shadowEnabled: true
property var _address: account
? account.core?.identityAddress || ""
: call
? call.core.remoteAddress
: contact
? contact.core.defaultAddress
: ''
property var _address: account ? account.core?.identityAddress || "" : call ? call.core.remoteAddress : contact
? contact.core.defaultAddress : ''
readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address
property var displayNameObj: UtilsCpp.getDisplayName(_address)
property var displayNameVal: account && account.core.displayName
? account.core.displayName
: contact && contact.core.fullName
? contact.core.fullName
: displayNameObj
? displayNameObj.value
: ""
property bool haveAvatar: account
? account.core.pictureUri
: contact
? contact.core.pictureUri
: computedAvatarUri.length != 0
property var displayNameVal: account && account.core.displayName ? account.core.displayName : contact && contact.core.fullName
? contact.core.fullName : displayNameObj ? displayNameObj.value : ""
property bool haveAvatar: account ? account.core.pictureUri : contact ? contact.core.pictureUri :
computedAvatarUri.length != 0
property var avatarObj: UtilsCpp.findAvatarByAddress(_address)
property string computedAvatarUri: avatarObj ? avatarObj.value : ''
@ -46,25 +33,23 @@ Loader{
// override it as secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
property var friendSecurityLevelObj: UtilsCpp.getFriendSecurityLevel(_address)
property var friendSecurityLevel: friendSecurityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
// To get the secured property for a specific address,
// override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
? call.core.tokenVerified
: contact
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
: false
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? call.core.tokenVerified :
contact ? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount
=== contact.core.devices.length : false
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
property bool displayPresence: true
asynchronous: true
sourceComponent: Component{
sourceComponent: Component {
Item {
anchors.fill: parent
MultiEffect {
visible: mainItem.shadowEnabled
enabled: mainItem.shadowEnabled
@ -77,16 +62,17 @@ Loader{
}
StackView {
id: stackView
initialItem: mainItem.haveAvatar ? avatar : initials
anchors.fill: parent
Connections{
Connections {
target: mainItem
onHaveAvatarChanged: {
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate)}
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate);
}
}
Rectangle {
visible: mainItem.secured || mainItem.securityBreach
anchors.fill: stackView.currentItem
@ -94,7 +80,7 @@ Loader{
z: 1
color: "transparent"
border {
width: Utils.getSizeWithScreenRatio(2)
width: Utils.getSizeWithScreenRatio(2)
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500_main
}
EffectImage {
@ -104,28 +90,22 @@ Loader{
height: width
imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
fillMode: Image.PreserveAspectFit
}
}
Image {
visible: mainItem.displayPresence
width: stackView.width/4.5
width: stackView.width / 4.5
height: width
sourceSize.width: width
sourceSize.height: width
sourceSize.height: width
smooth: false
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: stackView.width / 15
z: 1
source: account
? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok
? account.core?.registrationIcon
: account.core?.presenceIcon)
: (contact
? contact.core?.presenceIcon
: "")
source: account ? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok ? account.core?.registrationIcon :
account.core?.presenceIcon) : (contact ? contact.core?.presenceIcon : "")
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
@ -135,10 +115,9 @@ Loader{
duration: 10000
}
}
}
Component{
Component {
id: initials
Item {
id: avatarItem
@ -146,7 +125,8 @@ Loader{
width: height
Rectangle {
id: initialItem
property string initials: mainItem.isConference || (mainItem.displayNameVal && mainItem.displayNameVal[0] === "+") ? "" : UtilsCpp.getInitials(mainItem.displayNameVal)
property string initials: mainItem.isConference || (mainItem.displayNameVal && mainItem.displayNameVal[0]
=== "+") ? "" : UtilsCpp.getInitials(mainItem.displayNameVal)
radius: width / 2
color: DefaultStyle.main2_200
height: stackView.height
@ -167,7 +147,7 @@ Loader{
EffectImage {
id: initialImg
visible: initialItem.initials === "" || initialItem.initials[0] === "+"
width: stackView.width/2
width: stackView.width / 2
height: width
colorizationColor: DefaultStyle.main2_600
imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile
@ -188,7 +168,7 @@ Loader{
}
}
}
Component{
Component {
id: avatar
Item {
id: avatarItem
@ -204,11 +184,8 @@ Loader{
sourceSize.height: avatarItem.height
fillMode: Image.PreserveAspectCrop
anchors.centerIn: parent
source: mainItem.account
? mainItem.account.core.pictureUri
: mainItem.contact
? mainItem.contact.core.pictureUri
: computedAvatarUri
source: mainItem.account ? mainItem.account.core.pictureUri : mainItem.contact ? mainItem.contact.core.pictureUri :
computedAvatarUri
mipmap: true
layer.enabled: true
}

View file

@ -4,28 +4,27 @@ import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.Control{
Control.Control {
id: mainItem
activeFocusOnTab: true
padding: Utils.getSizeWithScreenRatio(10)
padding: Utils.getSizeWithScreenRatio(10)
property AccountGui account
leftPadding: Utils.getSizeWithScreenRatio(8)
rightPadding: Utils.getSizeWithScreenRatio(8)
leftPadding: Utils.getSizeWithScreenRatio(8)
rightPadding: Utils.getSizeWithScreenRatio(8)
property var style
property bool isSelected
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
readonly property color defaultBackgroundColor: style?.color?.normal ?? DefaultStyle.grey_0
readonly property color defaultBackgroundColor: style?.color?.normal ?? DefaultStyle.grey_0
readonly property color hoveredBackgroundColor: style?.color?.hovered ?? defaultBackgroundColor
readonly property color selectedBackgroundColor: style?.color?.selected ?? defaultBackgroundColor
readonly property color focusedBackgroundColor: style?.color?.keybaordFocused ?? defaultBackgroundColor
@ -37,42 +36,45 @@ Control.Control{
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
signal avatarClicked()
signal backgroundClicked()
signal edit()
signal avatarClicked
signal backgroundClicked
signal edit
background: Rectangle {
radius: Utils.getSizeWithScreenRatio(10)
color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor : mainItem.defaultBackgroundColor
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected ? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
MouseArea{
radius: Utils.getSizeWithScreenRatio(10)
color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor :
mainItem.defaultBackgroundColor
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected
? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: mainItem.backgroundClicked()
}
}
contentItem: RowLayout{
contentItem: RowLayout {
spacing: 0
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
Button {
id: avatarButton
onClicked: mainItem.avatarClicked()
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
color: "transparent"
contentItem: Item{
contentItem: Item {
anchors.fill: parent
width: avatarButton.width
height: avatarButton.height
Avatar{
Avatar {
id: avatar
height: avatarButton.height
width: avatarButton.width
account: mainItem.account
}
Rectangle{
Rectangle {
// Black border for keyboard navigation
visible: avatarButton.keyboardFocus
width: avatarButton.width
@ -82,13 +84,13 @@ Control.Control{
border.width: Utils.getSizeWithScreenRatio(3)
radius: width / 2
}
}
}
}
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(200)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(200)
Layout.fillHeight: true
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
ContactDescription{
Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
ContactDescription {
id: description
anchors.fill: parent
account: mainItem.account
@ -97,10 +99,10 @@ Control.Control{
}
Item {
Layout.minimumWidth: Utils.getSizeWithScreenRatio(86)
Layout.maximumWidth: Utils.getSizeWithScreenRatio(150)
Layout.maximumWidth: Utils.getSizeWithScreenRatio(150)
width: contactStatusPopup.width
height: contactStatusPopup.height
ContactStatusPopup{
ContactStatusPopup {
id: contactStatusPopup
visible: mainItem.account.core.publishEnabled
}
@ -111,32 +113,32 @@ Control.Control{
onClicked: mainItem.account.core.lSetRegisterEnabled(true)
}
}
Item{
Layout.preferredWidth: Utils.getSizeWithScreenRatio(26)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(26)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Layout.fillHeight: true
Layout.leftMargin: Utils.getSizeWithScreenRatio(40)
Layout.leftMargin: Utils.getSizeWithScreenRatio(40)
visible: mainItem.account.core.unreadNotifications > 0
Rectangle{
Rectangle {
id: unreadNotifications
anchors.verticalCenter: parent.verticalCenter
width: Utils.getSizeWithScreenRatio(26)
height: Utils.getSizeWithScreenRatio(26)
radius: width/2
width: Utils.getSizeWithScreenRatio(26)
height: Utils.getSizeWithScreenRatio(26)
radius: width / 2
color: DefaultStyle.danger_500_main
border.color: DefaultStyle.grey_0
border.width: Utils.getSizeWithScreenRatio(2)
Text{
border.width: Utils.getSizeWithScreenRatio(2)
Text {
id: unreadCount
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2)
anchors.margins: Utils.getSizeWithScreenRatio(2)
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0
minimumPixelSize: 5
fontSizeMode: Text.Fit
font.pixelSize: Utils.getSizeWithScreenRatio(11)
font.weight: Utils.getSizeWithScreenRatio(700)
font.pixelSize: Utils.getSizeWithScreenRatio(11)
font.weight: Utils.getSizeWithScreenRatio(700)
text: mainItem.account.core.unreadNotifications >= 100 ? '99+' : mainItem.account.core.unreadNotifications
}
}
@ -149,38 +151,40 @@ Control.Control{
}
}
Voicemail {
Layout.leftMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Layout.leftMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
scaleFactor: 0.7
showMwi: mainItem.account.core.showMwi
visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi
voicemailCount: mainItem.account.core.voicemailCount
onClicked: {
if (mainItem.account.core.voicemailAddress.length > 0)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress);
else
//: Erreur
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: L'URI de messagerie vocale n'est pas définie.
qsTr("information_popup_voicemail_address_undefined_message"), false)
//: Erreur
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: L'URI de messagerie vocale n'est pas définie.
qsTr("information_popup_voicemail_address_undefined_message"), false);
}
}
Item{Layout.fillWidth: true}
Button {
Item {
Layout.fillWidth: true
}
Button {
id: manageAccount
style: ButtonStyle.noBackground
icon.source: AppIcons.manageProfile
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
visible: !SettingsCpp.hideAccountSettings
//: Account settings of %1
Accessible.name: qsTr("account_settings_name_accessible_name")
onClicked: {
mainItem.edit()
mainItem.edit();
}
}
}

View file

@ -11,299 +11,290 @@ import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope {
id: mainItem
implicitHeight: visible ? Utils.getSizeWithScreenRatio(56) : 0
property var searchResultItem
property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below display name.
property bool showDisplayName: true // Display name above address.
property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts.
property string highlightText
property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText, searchResultItem.core.defaultAddress)
id: mainItem
implicitHeight: visible ? Utils.getSizeWithScreenRatio(56) : 0
property var searchResultItem
property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below display name.
property bool showDisplayName: true // Display name above address.
property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts.
property string highlightText
property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText,
searchResultItem.core.defaultAddress)
// Bold characters in Display name.
property bool displayNameCapitalization: true // Capitalize display name.
// Bold characters in Display name.
property bool displayNameCapitalization: true // Capitalize display name.
property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts
// List of default address on selected contacts.
property bool isSelected: false // selected in list => currentIndex == index
property bool isLastHovered: false
property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts
// List of default address on selected contacts.
property bool isSelected: false // selected in list => currentIndex == index
property bool isLastHovered: false
property var previousInitial
// Use directly previous initial
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property var previousInitial
// Use directly previous initial
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property var displayName: searchResultItem? searchResultItem.core.fullName : ""
property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) : ''
property var displayName: searchResultItem ? searchResultItem.core.fullName : ""
property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) :
''
signal clicked(var mouse)
signal contactDeletionRequested(FriendGui contact)
signal containsMouseChanged(bool containsMouse)
Accessible.name: displayName
signal clicked(var mouse)
signal contactDeletionRequested(FriendGui contact)
signal containsMouseChanged(bool containsMouse)
Accessible.name: displayName
MouseArea {
Text {
id: initialText
anchors.left: parent.left
visible: mainItem.showInitials
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
verticalAlignment: Text.AlignVCenter
width: Utils.getSizeWithScreenRatio(20)
opacity: previousInitial != mainItem.initial ? 1 : 0
text: mainItem.initial
textFormat: Text.RichText
color: DefaultStyle.main2_400
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
capitalization: Font.AllUppercase
}
}
RowLayout {
id: contactDelegate
anchors.left: initialText.visible ? initialText.right : parent.left
anchors.right: parent.right
anchors.rightMargin: mainItem.itemsRightMargin
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: Utils.getSizeWithScreenRatio(16)
z: contactArea.z + 1
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.leftMargin: Utils.getSizeWithScreenRatio(5)
contact: searchResultItem
shadowEnabled: false
}
ColumnLayout {
spacing: 0
Text {
id: displayNameText
visible: mainItem.showDisplayName
Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight: 0
text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)),
mainItem.highlightText)
textFormat: Text.RichText
font {
pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize
capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
weight: mainItem.showDefaultAddress ? Typography.h4.weight : Typography.p1.weight
}
maximumLineCount: 1
}
Text {
Layout.topMargin: Utils.getSizeWithScreenRatio(2)
Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight: 0
visible: mainItem.showDefaultAddress
property string address: SettingsCpp.hideSipAddresses
? UtilsCpp.getUsername(mainItem.addressFromFilter)
: mainItem.addressFromFilter
text: UtilsCpp.boldTextPart(address, mainItem.highlightText)
textFormat: Text.AutoText
maximumLineCount: 1
elide: Text.ElideRight
font {
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
}
}
}
Item {
Layout.fillWidth: true
}
RowLayout {
id: actionsRow
z: contactArea.z + 1
visible: mainItem.showActions || actionButtons.visible || mainItem.showContactMenu || mainItem.multiSelectionEnabled
spacing: visible ? Utils.getSizeWithScreenRatio(16) : 0
enabled: visible
Layout.rightMargin: Utils.getSizeWithScreenRatio(5)
EffectImage {
id: isSelectedCheck
visible: mainItem.multiSelectionEnabled
&& (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageSource: AppIcons.check
colorizationColor: DefaultStyle.main1_500_main
}
RowLayout {
id: actionButtons
visible: mainItem.showActions
spacing: visible ? Utils.getSizeWithScreenRatio(10) : 0
IconButton {
id: callButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.phone
focus: visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter)
KeyNavigation.left: chatButton
KeyNavigation.right: videoCallButton
//: "Call %1"
Accessible.name: qsTr("call_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
IconButton {
id: videoCallButton
visible: SettingsCpp.videoEnabled
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.videoCamera
focus: visible && !callButton.visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {"localVideoEnabled": true})
KeyNavigation.left: callButton
KeyNavigation.right: chatButton
//: "Video call %1"
Accessible.name: qsTr("video_call_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
IconButton {
id: chatButton
visible: actionButtons.visible
&& !SettingsCpp.disableChatFeature
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.chatTeardropText
focus: visible && !callButton.visible
&& !videoCallButton.visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
KeyNavigation.left: videoCallButton
KeyNavigation.right: callButton
onClicked: {
console.debug("[ContactListItem.qml] Open conversation")
mainWindow.displayChatPage(mainItem.addressFromFilter)
}
//: "Message %1"
Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
}
PopupButton {
id: friendPopup
z: contactArea.z + 1
popup.x: 0
popup.padding: Utils.getSizeWithScreenRatio(10)
visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered || popup.opened)
enabled: visible
MouseArea {
id: contactArea
Text {
id: initialText
anchors.left: parent.left
visible: mainItem.showInitials
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
verticalAlignment: Text.AlignVCenter
width: Utils.getSizeWithScreenRatio(20)
opacity: previousInitial != mainItem.initial ? 1 : 0
text: mainItem.initial
textFormat: Text.RichText
color: DefaultStyle.main2_400
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
capitalization: Font.AllUppercase
}
}
RowLayout {
id: contactDelegate
anchors.left: initialText.visible ? initialText.right : parent.left
anchors.right: parent.right
anchors.rightMargin: mainItem.itemsRightMargin
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: Utils.getSizeWithScreenRatio(16)
z: contactArea.z + 1
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.leftMargin: Utils.getSizeWithScreenRatio(5)
contact: searchResultItem
shadowEnabled: false
}
ColumnLayout {
spacing: 0
Text {
id: displayNameText
visible: mainItem.showDisplayName
Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight : 0
text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)), mainItem.highlightText)
textFormat: Text.RichText
font {
pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize
capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
weight: mainItem.showDefaultAddress ? Typography.h4.weight : Typography.p1.weight
}
maximumLineCount: 1
}
Text {
Layout.topMargin: Utils.getSizeWithScreenRatio(2)
Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight : 0
visible: mainItem.showDefaultAddress
property string address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(mainItem.addressFromFilter) :
mainItem.addressFromFilter
text: UtilsCpp.boldTextPart(address, mainItem.highlightText)
textFormat: Text.AutoText
maximumLineCount: 1
elide: Text.ElideRight
font {
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
}
}
}
Item {
Layout.fillWidth: true
}
RowLayout {
id: actionsRow
z: contactArea.z + 1
visible: mainItem.showActions || actionButtons.visible || mainItem.showContactMenu || mainItem.multiSelectionEnabled
spacing: visible ? Utils.getSizeWithScreenRatio(16) : 0
enabled: visible
Layout.rightMargin: Utils.getSizeWithScreenRatio(5)
EffectImage {
id: isSelectedCheck
visible: mainItem.multiSelectionEnabled && (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageSource: AppIcons.check
colorizationColor: DefaultStyle.main1_500_main
}
RowLayout {
id: actionButtons
visible: mainItem.showActions
spacing: visible ? Utils.getSizeWithScreenRatio(10) : 0
IconButton {
id: callButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.phone
focus: visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter)
KeyNavigation.left: chatButton
KeyNavigation.right: videoCallButton
//: "Call %1"
Accessible.name: qsTr("call_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
IconButton {
id: videoCallButton
visible: SettingsCpp.videoEnabled
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.videoCamera
focus: visible && !callButton.visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {
"localVideoEnabled": true
})
KeyNavigation.left: callButton
KeyNavigation.right: chatButton
//: "Video call %1"
Accessible.name: qsTr("video_call_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
IconButton {
id: chatButton
visible: actionButtons.visible && !SettingsCpp.disableChatFeature
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
icon.source: AppIcons.chatTeardropText
focus: visible && !callButton.visible && !videoCallButton.visible
radius: Utils.getSizeWithScreenRatio(40)
style: ButtonStyle.grey
KeyNavigation.left: videoCallButton
KeyNavigation.right: callButton
onClicked: {
console.debug("[ContactListItem.qml] Open conversation");
mainWindow.displayChatPage(mainItem.addressFromFilter);
}
//: "Message %1"
Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
}
}
PopupButton {
id: friendPopup
z: contactArea.z + 1
popup.x: 0
popup.padding: Utils.getSizeWithScreenRatio(10)
visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered
|| popup.opened)
enabled: visible
popup.contentItem: ColumnLayout {
IconLabelButton {
Layout.fillWidth: true
visible: searchResultItem && searchResultItem.core.isStored
&& !searchResultItem.core.readOnly
//: "Enlever des favoris"
text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites")
//: "Ajouter aux favoris"
: qsTr("contact_details_add_to_favourites")
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main
hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700
contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
onClicked: {
searchResultItem.core.lSetStarred(
!searchResultItem.core.starred)
friendPopup.close()
}
style: ButtonStyle.noBackground
}
IconLabelButton {
text: qsTr("Partager")
Layout.fillWidth: true
icon.source: AppIcons.shareNetwork
spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main
onClicked: {
var vcard = searchResultItem.core.getVCard()
var username = searchResultItem.core.givenName
+ searchResultItem.core.familyName
var filepath = UtilsCpp.createVCardFile(
username, vcard)
if (filepath == "")
UtilsCpp.showInformationPopup(
qsTr("information_popup_error_title"),
//: La création du fichier vcard a échoué
qsTr("information_popup_vcard_creation_error"),
false)
else
//: VCard créée
mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"),
//: "VCard du contact enregistrée dans %1"
qsTr("information_popup_vcard_creation_success").arg(filepath))
//: Partage de contact
UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"),vcard, filepath)
}
style: ButtonStyle.noBackground
}
IconLabelButton {
//: "Supprimer"
text: qsTr("contact_details_delete")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
Layout.fillWidth: true
onClicked: {
mainItem.contactDeletionRequested(searchResultItem)
friendPopup.close()
}
style: ButtonStyle.noBackgroundRed
}
}
}
}
}
id: contactArea
enabled: mainItem.selectionEnabled
anchors.fill: parent
//height: mainItem.height
hoverEnabled: true
acceptedButtons: Qt.AllButtons
focus: !actionButtons.visible
onContainsMouseChanged: {
mainItem.containsMouseChanged(containsMouse)
}
Rectangle {
anchors.fill: contactArea
radius: Utils.getSizeWithScreenRatio(8)
opacity: 0.7
color: mainItem.isSelected ? DefaultStyle.main2_200 : DefaultStyle.main2_100
visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space
|| event.key == Qt.Key_Enter
|| event.key == Qt.Key_Return) {
contactArea.clicked(undefined)
event.accepted = true
}
}
onClicked: mouse => {
forceActiveFocus()
if (mouse && mouse.button == Qt.RightButton
&& mainItem.showContactMenu) {
if (friendPopup) friendPopup.open()
} else {
mainItem.clicked(mouse)
}
}
}
popup.contentItem: ColumnLayout {
IconLabelButton {
Layout.fillWidth: true
visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
//: "Enlever des favoris"
text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") :
//: "Ajouter aux favoris"
qsTr("contact_details_add_to_favourites")
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main
hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700
contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
onClicked: {
searchResultItem.core.lSetStarred(!searchResultItem.core.starred);
friendPopup.close();
}
style: ButtonStyle.noBackground
}
IconLabelButton {
text: qsTr("Partager")
Layout.fillWidth: true
icon.source: AppIcons.shareNetwork
spacing: Utils.getSizeWithScreenRatio(10)
textColor: DefaultStyle.main2_500_main
onClicked: {
var vcard = searchResultItem.core.getVCard();
var username = searchResultItem.core.givenName + searchResultItem.core.familyName;
var filepath = UtilsCpp.createVCardFile(username, vcard);
if (filepath == "")
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: La création du fichier vcard a échoué
qsTr("information_popup_vcard_creation_error"), false);
else
//: VCard créée
mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"),
//: "VCard du contact enregistrée dans %1"
qsTr("information_popup_vcard_creation_success").arg(filepath));
//: Partage de contact
UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"), vcard, filepath);
}
style: ButtonStyle.noBackground
}
IconLabelButton {
//: "Supprimer"
text: qsTr("contact_details_delete")
icon.source: AppIcons.trashCan
spacing: Utils.getSizeWithScreenRatio(10)
visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
Layout.fillWidth: true
onClicked: {
mainItem.contactDeletionRequested(searchResultItem);
friendPopup.close();
}
style: ButtonStyle.noBackgroundRed
}
}
}
}
}
enabled: mainItem.selectionEnabled
anchors.fill: parent
//height: mainItem.height
hoverEnabled: true
acceptedButtons: Qt.AllButtons
focus: !actionButtons.visible
onContainsMouseChanged: {
mainItem.containsMouseChanged(containsMouse);
}
Rectangle {
anchors.fill: contactArea
radius: Utils.getSizeWithScreenRatio(8)
opacity: 0.7
color: mainItem.isSelected ? DefaultStyle.main2_200 : DefaultStyle.main2_100
visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
contactArea.clicked(undefined);
event.accepted = true;
}
}
onClicked: mouse => {
forceActiveFocus();
if (mouse && mouse.button == Qt.RightButton && mainItem.showContactMenu) {
if (friendPopup)
friendPopup.open();
} else {
mainItem.clicked(mouse);
}
}
}
}

View file

@ -6,8 +6,8 @@ import Linphone
import UtilsCpp 1.0
import ConstantsCpp 1.0
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ListView {
id: mainItem
@ -15,16 +15,16 @@ ListView {
property string title
property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below display name.
property bool showDisplayName: true // Display name above address.
property bool showDisplayName: true // Display name above address.
property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts.
property bool showFavorites: true // Display the favorites in the header
property bool hideSuggestions: false // Hide not stored contacts (not suggestions)
property string highlightText: searchText // Bold characters in Display name.
property var sourceFlags: LinphoneEnums.MagicSearchSource.All
property bool displayNameCapitalization: true // Capitalize display name.
property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts // List of default address on selected contacts.
@ -35,126 +35,132 @@ ListView {
// matching names
property string searchText
property ConferenceInfoGui confInfoGui
property bool haveFavorites: false
property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property bool expanded: true
property real headerHeight: headerItem?.height
property real headerHeight: headerItem?.height
signal contactDeletionRequested(FriendGui contact)
signal contactSelected(FriendGui contact) // Click/Space/Enter
signal addContactToSelection(var address)
signal removeContactFromSelection(var indexInSelection)
signal updatePosition()
signal updatePosition
clip: true
highlightFollowsCurrentItem: false
cacheBuffer: 400
implicitHeight: contentHeight
spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0
spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0
onVisibleChanged: if (visible && !expanded)
expanded = true
onVisibleChanged: if (visible && !expanded) expanded = true
onYChanged: updatePosition()
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea.
// So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1
property bool _moveToIndex: false
function selectIndex(index, focusReason = Qt.OtherFocusReason){
if(mainItem.expanded && index >= 0){
mainItem.currentIndex = index
var item = itemAtIndex(mainItem.currentIndex)
if(item){// Item is ready and available
mainItem.highlightedContact = item.searchResultItem
item.forceActiveFocus(focusReason)
updatePosition()
_moveToIndex = false
}else{// Move on the next items load.
function selectIndex(index, focusReason = Qt.OtherFocusReason) {
if (mainItem.expanded && index >= 0) {
mainItem.currentIndex = index;
var item = itemAtIndex(mainItem.currentIndex);
if (item) {
// Item is ready and available
mainItem.highlightedContact = item.searchResultItem;
item.forceActiveFocus(focusReason);
updatePosition();
_moveToIndex = false;
} else {
// Move on the next items load.
// If visible, try to wait loading
_moveToIndex = visible
_moveToIndex = visible;
}
}else{
mainItem.currentIndex = -1
mainItem.highlightedContact = null
if(headerItem) {
headerItem.forceActiveFocus(focusReason)
} else {
mainItem.currentIndex = -1;
mainItem.highlightedContact = null;
if (headerItem) {
headerItem.forceActiveFocus(focusReason);
}
_moveToIndex = false
_moveToIndex = false;
}
}
onContactSelected: updatePosition()
onExpandedChanged: if(!expanded) updatePosition()
onExpandedChanged: if (!expanded)
updatePosition()
keyNavigationEnabled: false
Keys.onPressed: (event)=> {
if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){
if(event.key == Qt.Key_Up && !headerItem.activeFocus) {
if(currentIndex >= 0 ) {
selectIndex(mainItem.currentIndex-1, Qt.BacktabFocusReason)
event.accepted = true;
}
}else if(event.key == Qt.Key_Down && mainItem.expanded){
if(currentIndex < model.count - 1) {
selectIndex(mainItem.currentIndex+1, Qt.TabFocusReason)
event.accepted = true;
}
}
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
if (event.key == Qt.Key_Up && !headerItem.activeFocus) {
if (currentIndex >= 0) {
selectIndex(mainItem.currentIndex - 1, Qt.BacktabFocusReason);
event.accepted = true;
}
} else if (event.key == Qt.Key_Down && mainItem.expanded) {
if (currentIndex < model.count - 1) {
selectIndex(mainItem.currentIndex + 1, Qt.TabFocusReason);
event.accepted = true;
}
}
}
}
Component.onCompleted: {
if (confInfoGui) {
for(var i = 0; i < confInfoGui.core.participants.length; ++i) {
for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
}
}
}
Connections {
target: SettingsCpp
function onLdapConfigChanged() {
if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate()
magicSearchProxy.forceUpdate();
}
function onCardDAVAddressBookSynchronized() {
console.log("card dav synchro update")
magicSearchProxy.forceUpdate()
console.log("card dav synchro update");
magicSearchProxy.forceUpdate();
}
}
// Workaround: itemAtIndex and count are decorellated and are not enough to know when the ListView has load all its children.
// So when itemAtIndex is not available, start this timer along count changed signal.
Timer{
Timer {
id: delaySelection
interval: 100
running: _moveToIndex
onTriggered: {
_moveToIndex = false
if(count > mainItem.currentIndex) selectIndex(mainItem.currentIndex)
else{
_moveToIndex = true
_moveToIndex = false;
if (count > mainItem.currentIndex)
selectIndex(mainItem.currentIndex);
else {
_moveToIndex = true;
}
}
}
header: FocusScope{
header: FocusScope {
id: headerItem
width: mainItem.width
height: headerContents.implicitHeight
ColumnLayout {
id: headerContents
width: parent.width
spacing: 0
Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible
Item// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible
{
Layout.fillWidth: true
Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0
Layout.bottomMargin: Utils.getSizeWithScreenRatio(4)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(4)
RowLayout {
id: headerTitleLayout
anchors.fill: parent
@ -175,28 +181,28 @@ ListView {
id: headerExpandButton
style: ButtonStyle.noBackground
icon.source: mainItem.expanded ? AppIcons.upArrow : AppIcons.downArrow
Layout.rightMargin: mainItem.itemsRightMargin
Layout.rightMargin: mainItem.itemsRightMargin
focus: true
onClicked: mainItem.expanded = !mainItem.expanded
Rectangle {
anchors.fill: headerExpandButton
radius: headerExpandButton.width/2
radius: headerExpandButton.width / 2
visible: headerExpandButton.activeFocus
opacity: 0.5
color: DefaultStyle.main2_200
}
Accessible.name: (mainItem.expanded ?
//: Shrink %1
qsTr("shrink_accessible_name") :
//: Expand %1
qsTr("expand_accessible_name")).arg(mainItem.title)
//: Shrink %1
qsTr("shrink_accessible_name") :
//: Expand %1
qsTr("expand_accessible_name")).arg(mainItem.title)
}
}
}
}
}
delegate: ContactListItem{
delegate: ContactListItem {
id: contactItem
width: mainItem.width
focus: true
@ -209,41 +215,41 @@ ListView {
showContactMenu: mainItem.showContactMenu && searchResultItem.core.isStored
highlightText: mainItem.highlightText
displayNameCapitalization: mainItem.displayNameCapitalization
selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts
isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core
isLastHovered: mainItem.lastMouseContainsIndex == index
previousInitial: mainItem.itemAtIndex(index-1)?.initial
previousInitial: mainItem.itemAtIndex(index - 1)?.initial
itemsRightMargin: mainItem.itemsRightMargin
onIsSelectedChanged: if(isSelected) mainItem.currentIndex = index
onContactDeletionRequested: (contact) => mainItem.contactDeletionRequested(contact)
onClicked: (mouse) => {
if (mouse && mouse.button == Qt.RightButton) {
friendPopup.open()
} else {
forceActiveFocus()
mainItem.highlightedContact = contactItem.searchResultItem
if (mainItem.multiSelectionEnabled) {
var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress)
if (indexInSelection == -1) {
mainItem.addContactToSelection(searchResultItem.core.defaultAddress)
}
else {
mainItem.removeContactFromSelection(indexInSelection)
}
}
mainItem.contactSelected(searchResultItem)
}
}
onContainsMouseChanged: (containsMouse) => {
if(containsMouse)
mainItem.lastMouseContainsIndex = index
else if( mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1
}
onIsSelectedChanged: if (isSelected)
mainItem.currentIndex = index
onContactDeletionRequested: contact => mainItem.contactDeletionRequested(contact)
onClicked: mouse => {
if (mouse && mouse.button == Qt.RightButton) {
friendPopup.open();
} else {
forceActiveFocus();
mainItem.highlightedContact = contactItem.searchResultItem;
if (mainItem.multiSelectionEnabled) {
var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress);
if (indexInSelection == -1) {
mainItem.addContactToSelection(searchResultItem.core.defaultAddress);
} else {
mainItem.removeContactFromSelection(indexInSelection);
}
}
mainItem.contactSelected(searchResultItem);
}
}
onContainsMouseChanged: containsMouse => {
if (containsMouse)
mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1;
}
}
}

View file

@ -4,93 +4,94 @@ import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
PopupButton {
id: presenceAndRegistrationItem
width: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50)
height: Utils.getSizeWithScreenRatio(24)
enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok
onEnabledChanged: if(!enabled) close()
property bool editCustomStatus : false
contentItem: Rectangle {
id: presenceBar
property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
RowLayout {
anchors.fill: parent
Image {
id: registrationImage
sourceSize.width: Utils.getSizeWithScreenRatio(11)
sourceSize.height: Utils.getSizeWithScreenRatio(11)
smooth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(11)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(11)
source: presenceBar.isRegistered
? mainItem.account.core.presenceIcon
: mainItem.account?.core.registrationIcon || ""
Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
from: 0
to: 360
loops: Animation.Infinite
duration: 10000
}
}
Text {
id: presenceOrRegistrationText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: mainItem.account
font.weight: Utils.getSizeWithScreenRatio(300)
font.pixelSize: Utils.getSizeWithScreenRatio(12)
color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor
text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.downArrow
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
Layout.rightMargin: Utils.getSizeWithScreenRatio(8)
}
}
}
popup.contentItem: Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(280)
implicitHeight: Utils.getSizeWithScreenRatio(20) + (setCustomStatus.visible ? Utils.getSizeWithScreenRatio(240) : setPresence.implicitHeight)
Presence {
id: setPresence
visible: !presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(20)
accountGui: mainItem.account
onSetCustomStatusClicked: {
presenceAndRegistrationItem.editCustomStatus = true
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
PresenceSetCustomStatus {
id: setCustomStatus
visible: presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(20)
accountGui: mainItem.account
onVisibleChanged: {
if (!visible) {
presenceAndRegistrationItem.editCustomStatus = false
}
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
}
}
id: presenceAndRegistrationItem
width: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50)
height: Utils.getSizeWithScreenRatio(24)
enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok
onEnabledChanged: if (!enabled)
close()
property bool editCustomStatus: false
contentItem: Rectangle {
id: presenceBar
property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
RowLayout {
anchors.fill: parent
Image {
id: registrationImage
sourceSize.width: Utils.getSizeWithScreenRatio(11)
sourceSize.height: Utils.getSizeWithScreenRatio(11)
smooth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(11)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(11)
source: presenceBar.isRegistered ? mainItem.account.core.presenceIcon : mainItem.account?.core.registrationIcon
|| ""
Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
from: 0
to: 360
loops: Animation.Infinite
duration: 10000
}
}
Text {
id: presenceOrRegistrationText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: mainItem.account
font.weight: Utils.getSizeWithScreenRatio(300)
font.pixelSize: Utils.getSizeWithScreenRatio(12)
color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor
text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account
?.core.humaneReadableRegistrationState
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.downArrow
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
Layout.rightMargin: Utils.getSizeWithScreenRatio(8)
}
}
}
popup.contentItem: Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(280)
implicitHeight: Utils.getSizeWithScreenRatio(20) + (setCustomStatus.visible ? Utils.getSizeWithScreenRatio(240) :
setPresence.implicitHeight)
Presence {
id: setPresence
visible: !presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(20)
accountGui: mainItem.account
onSetCustomStatusClicked: {
presenceAndRegistrationItem.editCustomStatus = true;
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
PresenceSetCustomStatus {
id: setCustomStatus
visible: presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(20)
accountGui: mainItem.account
onVisibleChanged: {
if (!visible) {
presenceAndRegistrationItem.editCustomStatus = false;
}
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
}
}

View file

@ -2,22 +2,42 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout {
id: mainItem
property var accountGui
signal setCustomStatusClicked
signal isSet
spacing: Utils.getSizeWithScreenRatio(8)
PresenceStatusItem { presence: LinphoneEnums.Presence.Online; accountGui: mainItem.accountGui; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.Away; accountGui: mainItem.accountGui; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.Busy; accountGui: mainItem.accountGui; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.DoNotDisturb; accountGui: mainItem.accountGui; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.Offline; accountGui: mainItem.accountGui; onClick: mainItem.isSet()}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Online
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Away
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Busy
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.DoNotDisturb
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
PresenceStatusItem {
presence: LinphoneEnums.Presence.Offline
accountGui: mainItem.accountGui
onClick: mainItem.isSet()
}
RowLayout {
spacing: 0
@ -31,7 +51,7 @@ ColumnLayout {
color: DefaultStyle.main2_600
}
Item {
Layout.fillWidth: true
Layout.fillWidth: true
}
Button {
id: resetStatusItem
@ -53,20 +73,21 @@ ColumnLayout {
Layout.alignment: Qt.AlignLeft
Text {
font: Typography.p1
text: accountGui.core.presenceNote.length > 0 ? accountGui.core.presenceNote : qsTr("contact_presence_custom_status")
text: accountGui.core.presenceNote.length > 0 ? accountGui.core.presenceNote : qsTr(
"contact_presence_custom_status")
color: DefaultStyle.main2_600
wrapMode: Text.WordWrap
Layout.preferredWidth: Utils.getSizeWithScreenRatio(accountGui.core.presenceNote.length == 0 ? 175 : 230)
}
Item {
Layout.fillWidth: true
Layout.fillWidth: true
}
SmallButton {
visible: accountGui.core.presenceNote.length == 0
style: ButtonStyle.secondary
text: qsTr("contact_presence_button_set_custom_status")
onClicked: {
mainItem.setCustomStatusClicked()
mainItem.setCustomStatusClicked();
}
}
}
@ -74,13 +95,13 @@ ColumnLayout {
visible: accountGui.core.presenceNote.length > 0
spacing: Utils.getSizeWithScreenRatio(10)
Item {
Layout.fillWidth: true
Layout.fillWidth: true
}
SmallButton {
style: ButtonStyle.secondary
text: qsTr("contact_presence_button_edit_custom_status")
onClicked: {
mainItem.setCustomStatusClicked()
mainItem.setCustomStatusClicked();
}
}
SmallButton {
@ -88,7 +109,7 @@ ColumnLayout {
visible: accountGui.core.presenceNote.length > 0
text: qsTr("contact_presence_button_delete_custom_status")
onClicked: {
mainItem.accountGui.core.presenceNote = ""
mainItem.accountGui.core.presenceNote = "";
}
}
}

View file

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts
import Linphone
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Column {
@ -42,15 +42,15 @@ Column {
text: mainItem.accountGui.core.presenceNote
onTextChanged: {
if (statusMessage.text.length > accountGui.core.maxPresenceNoteSize) {
statusMessage.text = previoustext
statusMessage.cursorPosition = statusMessage.text.length
statusMessage.text = previoustext;
statusMessage.cursorPosition = statusMessage.text.length;
} else {
previoustext = statusMessage.text
previoustext = statusMessage.text;
}
}
}
Item {
Layout.fillHeight: true
Layout.fillHeight: true
}
Text {
Layout.fillWidth: true
@ -71,8 +71,8 @@ Column {
text: qsTr("contact_presence_button_save_custom_status")
enabled: statusMessage.text.length > 0
onClicked: {
mainItem.accountGui.core.presenceNote = statusMessage.text
mainItem.isSet()
mainItem.accountGui.core.presenceNote = statusMessage.text;
mainItem.isSet();
}
}
}

View file

@ -3,20 +3,19 @@ import QtQuick.Controls
import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
IconLabelButton {
id: mainItem
property var accountGui
property var presence
signal click()
signal click
style: ButtonStyle.hoveredBackgroundBis
height: Utils.getSizeWithScreenRatio(22)
radius: Utils.getSizeWithScreenRatio(5)
height: Utils.getSizeWithScreenRatio(22)
radius: Utils.getSizeWithScreenRatio(5)
text: UtilsCpp.getPresenceStatus(presence)
textSize: Typography.p1.pixelSize
textColor: UtilsCpp.getPresenceColor(mainItem.presence)
@ -29,7 +28,7 @@ IconLabelButton {
padding: 0
onClicked: {
mainItem.accountGui.core.presence = mainItem.presence
mainItem.click()
mainItem.accountGui.core.presence = mainItem.presence;
mainItem.click();
}
}

View file

@ -7,21 +7,21 @@ import UtilsCpp
import SettingsCpp
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle{
Rectangle {
id: mainItem
property int voicemailCount: 0
property bool showMwi: false
width: Utils.getSizeWithScreenRatio(42 * scaleFactor)
height: Utils.getSizeWithScreenRatio(36 * scaleFactor)
width: Utils.getSizeWithScreenRatio(42 * scaleFactor)
height: Utils.getSizeWithScreenRatio(36 * scaleFactor)
property real scaleFactor: 1.0
signal clicked()
signal clicked
color: 'transparent'
Button {
anchors.bottom: parent.bottom
anchors.left: parent.left
icon.source: AppIcons.voicemail
icon.color: DefaultStyle.main2_600
width: Utils.getSizeWithScreenRatio(33 * scaleFactor)
width: Utils.getSizeWithScreenRatio(33 * scaleFactor)
height: width
icon.width: width
icon.height: width
@ -30,17 +30,17 @@ Rectangle{
anchors.fill: parent
}
onClicked: {
mainItem.clicked()
mainItem.clicked();
}
}
Text {
anchors.top: parent.top
anchors.right: parent.right
width: Utils.getSizeWithScreenRatio(14 * scaleFactor)
width: Utils.getSizeWithScreenRatio(14 * scaleFactor)
height: width
horizontalAlignment: Text.AlignHCenter
font.weight: Typography.p2.weight
font.pixelSize: Typography.p2.pixelSize * scaleFactor
font.weight: Typography.p2.weight
font.pixelSize: Typography.p2.pixelSize * scaleFactor
color: DefaultStyle.danger_500_main
text: voicemailCount >= 100 ? '99+' : voicemailCount
visible: showMwi && voicemailCount > 0
@ -52,15 +52,14 @@ Rectangle{
anchors.right: parent.right
color: DefaultStyle.danger_500_main
visible: showMwi && voicemailCount == 0
width: Utils.getSizeWithScreenRatio(14 * scaleFactor)
width: Utils.getSizeWithScreenRatio(14 * scaleFactor)
height: width
radius: width / 2
EffectImage {
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(1.5 * scaleFactor)
anchors.margins: Utils.getSizeWithScreenRatio(1.5 * scaleFactor)
imageSource: AppIcons.bell
colorizationColor: DefaultStyle.grey_0
}
}
}

View file

@ -52,24 +52,24 @@ Item {
source: effect
maskSource: effect
colorizationColor: effectEnabled && mainItem.colorizationColor ? mainItem.colorizationColor : 'black'
colorization: effectEnabled ? 1.0: 0.0
colorization: effectEnabled ? 1.0 : 0.0
}
/* Alernative to shadow for no blackcolors
MultiEffect {
visible: mainItem.shadowEnabled
source: image
width: image.width
height: image.height
x: image.x
y: image.y + 6
z: -1
blurEnabled: true
blurMax: 12
blur: 1.0
contrast: -1.0
brightness: 1.0
colorizationColor: DefaultStyle.grey_400
colorization: 1.0
visible: mainItem.shadowEnabled
source: image
width: image.width
height: image.height
x: image.x
y: image.y + 6
z: -1
blurEnabled: true
blurMax: 12
blur: 1.0
contrast: -1.0
brightness: 1.0
colorizationColor: DefaultStyle.grey_400
colorization: 1.0
}*/
MultiEffect {
id: shadow

View file

@ -6,5 +6,5 @@ Flickable {
contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height
clip: true
flickableDirection: Flickable.VerticalFlick
flickableDirection: Flickable.VerticalFlick
}

View file

@ -4,25 +4,31 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Item {
id: mainItem
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property alias borderGradient: border.gradient
property alias gradient: fill.gradient
property alias color: fill.color
property real radius
property real radius
Rectangle {
id: border
radius: mainItem.radius
anchors.fill: parent
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 }
GradientStop { position: 1.0; color: DefaultStyle.grey_100 }
GradientStop {
position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
}
Rectangle {
id: fill
anchors.fill: parent
anchors.margins: mainItem.borderWidth
radius: mainItem.radius
radius: mainItem.radius
}
}
}

View file

@ -2,10 +2,10 @@ import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Rectangle{
height: 1
Layout.fillWidth: true
color: DefaultStyle.main2_500_main
}
Rectangle {
height: 1
Layout.fillWidth: true
color: DefaultStyle.main2_500_main
}

View file

@ -7,14 +7,14 @@ import QtQuick.Effects
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
// =============================================================================
ProgressBar {
id: mainItem
property bool stopAtEnd: true
property bool resetAtEnd: true
property int progressDuration // Max duration
@ -24,22 +24,22 @@ ProgressBar {
property bool recording: false
padding: 0
clip: true
function start(){
mainItem.value = 0
animationTest.start()
function start() {
mainItem.value = 0;
animationTest.start();
}
function resume(){
function resume() {
if (mainItem.value >= 100)
mainItem.value = 0
animationTest.start()
mainItem.value = 0;
animationTest.start();
}
function stop(){
animationTest.stop()
function stop() {
animationTest.stop();
}
signal playStopButtonToggled()
signal endReached()
signal refreshPositionRequested()
signal playStopButtonToggled
signal endReached
signal refreshPositionRequested
signal seekRequested(int ms)
Timer {
id: animationTest
@ -49,21 +49,21 @@ ProgressBar {
}
to: 101
value: progressPosition * to / progressDuration
onValueChanged:{
if(value > 100) {
if( mainItem.stopAtEnd)
stop()
if(mainItem.resetAtEnd) {
mainItem.value = 0
progressPosition = 0
} else if(mainItem.blockValueAtEnd){
mainItem.value = 100// Stay at 100
progressPosition = progressDuration
onValueChanged: {
if (value > 100) {
if (mainItem.stopAtEnd)
stop();
if (mainItem.resetAtEnd) {
mainItem.value = 0;
progressPosition = 0;
} else if (mainItem.blockValueAtEnd) {
mainItem.value = 100;// Stay at 100
progressPosition = progressDuration;
}
mainItem.endReached()
mainItem.endReached();
}
}
background: Item {
anchors.fill: parent
Rectangle {
@ -71,8 +71,14 @@ ProgressBar {
anchors.fill: parent
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: "#FF9E79" }
GradientStop { position: 1.0; color: "#FE5E00" }
GradientStop {
position: 0.0
color: "#FF9E79"
}
GradientStop {
position: 1.0
color: "#FE5E00"
}
}
radius: Utils.getSizeWithScreenRatio(70)
}
@ -83,8 +89,8 @@ ProgressBar {
radius: backgroundArea.radius
}
Item {
anchors.fill: parent
id: progressRectangle
anchors.fill: parent
visible: false
Rectangle {
color: DefaultStyle.grey_0
@ -96,12 +102,10 @@ ProgressBar {
ShaderEffect {
id: opacityEffect
anchors.fill: progressRectangle
property var source: ShaderEffectSource
{
property var source: ShaderEffectSource {
sourceItem: progressRectangle
}
property var maskSource: ShaderEffectSource
{
property var maskSource: ShaderEffectSource {
sourceItem: mask
}
fragmentShader: 'qrc:/data/shaders/opacityMask.frag.qsb'
@ -109,13 +113,12 @@ ProgressBar {
MouseArea {
id: progression
anchors.fill: parent
onClicked: (mouse) => {
mainItem.seekRequested(mouse.x * mainItem.progressDuration/width)
}
onClicked: mouse => {
mainItem.seekRequested(mouse.x * mainItem.progressDuration / width);
}
}
}
contentItem: Item {
id: contentRect
@ -126,13 +129,9 @@ ProgressBar {
anchors.verticalCenter: parent.verticalCenter
icon.width: Utils.getSizeWithScreenRatio(14)
icon.height: Utils.getSizeWithScreenRatio(14)
icon.source: animationTest.running
? mainItem.recording
? AppIcons.stopFill
: AppIcons.pauseFill
: AppIcons.playFill
icon.source: animationTest.running ? mainItem.recording ? AppIcons.stopFill : AppIcons.pauseFill : AppIcons.playFill
onClicked: {
mainItem.playStopButtonToggled()
mainItem.playStopButtonToggled();
}
style: ButtonStyle.player
}
@ -160,7 +159,8 @@ ProgressBar {
}
Text {
id: durationText
text: mainItem.progressPosition > 0 ? UtilsCpp.formatElapsedTime(mainItem.progressPosition / 1000 ) : UtilsCpp.formatElapsedTime(mainItem.progressDuration/1000)
text: mainItem.progressPosition > 0 ? UtilsCpp.formatElapsedTime(mainItem.progressPosition / 1000) : UtilsCpp.formatElapsedTime(
mainItem.progressDuration / 1000)
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight

View file

@ -7,64 +7,64 @@ import Linphone
import QtQml
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ListView {
id: mainItem
property string searchBarText
property bool hoverEnabled: true
property bool hoverEnabled: true
property var delegateButtons
property ConferenceInfoGui selectedConference
property ConferenceInfoGui confToBeSelected: null
property bool _moveToIndex: false
property bool loading: false
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool loading: false
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
clip: true
cacheBuffer: height/2
spacing: Utils.getSizeWithScreenRatio(8)
cacheBuffer: height / 2
spacing: Utils.getSizeWithScreenRatio(8)
highlightFollowsCurrentItem: false
onCurrentIndexChanged: if(currentIndex === -1) {
resetSelections()
}
onCurrentIndexChanged: if (currentIndex === -1) {
resetSelections();
}
signal meetingDeletionRequested(ConferenceInfoGui confInfo, bool canCancel)
function selectIndex(index){
mainItem.currentIndex = index
function selectIndex(index) {
mainItem.currentIndex = index;
}
function resetSelections(){
mainItem.selectedConference = null
mainItem.currentIndex = -1
function resetSelections() {
mainItem.selectedConference = null;
mainItem.currentIndex = -1;
}
function scrollToCurrentDate() {
currentIndex = -1
confInfoProxy.selectData(confInfoProxy.getCurrentDateConfInfo())
moveToCurrentItem()
currentIndex = -1;
confInfoProxy.selectData(confInfoProxy.getCurrentDateConfInfo());
moveToCurrentItem();
}
//----------------------------------------------------------------
function moveToCurrentItem(){
if(mainItem.currentIndex >= 0)
mainItem.positionViewAtIndex(mainItem.currentIndex, ListView.Contain)
//----------------------------------------------------------------
function moveToCurrentItem() {
if (mainItem.currentIndex >= 0)
mainItem.positionViewAtIndex(mainItem.currentIndex, ListView.Contain);
}
onCurrentItemChanged: {
moveToCurrentItem()
if(currentItem) {
mainItem.selectedConference = currentItem.itemGui
moveToCurrentItem();
if (currentItem) {
mainItem.selectedConference = currentItem.itemGui;
}
}
// Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){
moveToCurrentItem()
}
Behavior on contentY{
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem();
}
Behavior on contentY {
NumberAnimation {
id: moveAnimation
duration: 500
@ -72,76 +72,81 @@ ListView {
alwaysRunToEnd: true
}
}
//----------------------------------------------------------------
onAtYEndChanged: if(atYEnd) confInfoProxy.displayMore()
//----------------------------------------------------------------
onAtYEndChanged: if (atYEnd)
confInfoProxy.displayMore()
Component.onCompleted: {
confInfoProxy.invalidate()
confInfoProxy.invalidate();
}
Keys.onPressed: (event)=> {
if(event.key == Qt.Key_Up) {
if(currentIndex > 0 ) {
selectIndex(mainItem.currentIndex-1)
event.accepted = true
} else {
selectIndex(model.count - 1)
event.accepted = true
}
}else if(event.key == Qt.Key_Down){
if(currentIndex < model.count - 1) {
selectIndex(currentIndex+1)
event.accepted = true
} else {
selectIndex(0)
event.accepted = true
}
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Up) {
if (currentIndex > 0) {
selectIndex(mainItem.currentIndex - 1);
event.accepted = true;
} else {
selectIndex(model.count - 1);
event.accepted = true;
}
} else if (event.key == Qt.Key_Down) {
if (currentIndex < model.count - 1) {
selectIndex(currentIndex + 1);
event.accepted = true;
} else {
selectIndex(0);
event.accepted = true;
}
}
}
// Let some space for better UI
footer: Item{height: Utils.getSizeWithScreenRatio(38)}
footer: Item {
height: Utils.getSizeWithScreenRatio(38)
}
model: ConferenceInfoProxy {
id: confInfoProxy
filterText: searchBarText
filterType: ConferenceInfoProxy.None
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: initialDisplayItems/2
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
displayItemsStep: initialDisplayItems / 2
onModelAboutToBeReset: {
mainItem.confToBeSelected = mainItem.selectedConference
mainItem.loading = true
}
mainItem.confToBeSelected = mainItem.selectedConference;
mainItem.loading = true;
}
onModelReset: {
mainItem.loading = false
if (mainItem.confToBeSelected) selectData(mainItem.confToBeSelected)
else selectData(getCurrentDateConfInfo())
mainItem.loading = false;
if (mainItem.confToBeSelected)
selectData(mainItem.confToBeSelected);
else
selectData(getCurrentDateConfInfo());
}
function selectData(confInfoGui){
mainItem.currentIndex = loadUntil(confInfoGui)
}
onConferenceInfoCreated: (confInfoGui) => {
selectData(confInfoGui)
}
onConferenceInfoUpdated: (confInfoGui) => {
selectData(confInfoGui)
function selectData(confInfoGui) {
mainItem.currentIndex = loadUntil(confInfoGui);
}
onConferenceInfoCreated: confInfoGui => {
selectData(confInfoGui);
}
onConferenceInfoUpdated: confInfoGui => {
selectData(confInfoGui);
}
}
BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main
}
ScrollBar.vertical: ScrollBar {
id: scrollbar
rightPadding: Utils.getSizeWithScreenRatio(8)
rightPadding: Utils.getSizeWithScreenRatio(8)
active: true
interactive: true
policy: mainItem.contentHeight > mainItem.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
@ -150,81 +155,82 @@ ListView {
section {
criteria: ViewSection.FullString
delegate: Text {
topPadding: Utils.getSizeWithScreenRatio(24)
bottomPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(24)
bottomPadding: Utils.getSizeWithScreenRatio(16)
text: section
height: Utils.getSizeWithScreenRatio(29) + topPadding + bottomPadding
height: Utils.getSizeWithScreenRatio(29) + topPadding + bottomPadding
wrapMode: Text.NoWrap
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(800)
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(800)
capitalization: Font.Capitalize
}
}
property: '$sectionMonth'
}
delegate: FocusScope {
id: itemDelegate
visible: !mainItem.loading
height: Utils.getSizeWithScreenRatio(63) + (!isFirst && dateDay.visible ? topOffset : 0)
height: Utils.getSizeWithScreenRatio(63) + (!isFirst && dateDay.visible ? topOffset : 0)
width: mainItem.width
enabled: haveModel
property var itemGui: $modelData
// Do not use itemAtIndex because of caching items. Using getAt ensure to have a GUI
property var previousConfInfoGui : mainItem.model.getAt(index-1)
property var previousConfInfoGui: mainItem.model.getAt(index - 1)
property var dateTime: itemGui.core ? itemGui.core.dateTime : UtilsCpp.getCurrentDateTime()
property string day : UtilsCpp.toDateDayNameString(dateTime)
property string dateString: UtilsCpp.toDateString(dateTime)
property string previousDateString: previousConfInfoGui ? UtilsCpp.toDateString(previousConfInfoGui.core ? previousConfInfoGui.core.dateTime : UtilsCpp.getCurrentDateTime()) : ''
property bool isFirst : ListView.previousSection !== ListView.section
property real topOffset: (dateDay.visible && !isFirst) ? Utils.getSizeWithScreenRatio(8) : 0
property string day: UtilsCpp.toDateDayNameString(dateTime)
property string dateString: UtilsCpp.toDateString(dateTime)
property string previousDateString: previousConfInfoGui ? UtilsCpp.toDateString(previousConfInfoGui.core
? previousConfInfoGui.core.dateTime : UtilsCpp.getCurrentDateTime()) : ''
property bool isFirst: ListView.previousSection !== ListView.section
property real topOffset: (dateDay.visible && !isFirst) ? Utils.getSizeWithScreenRatio(8) : 0
property var endDateTime: itemGui.core ? itemGui.core.endDateTime : UtilsCpp.getCurrentDateTime()
property bool haveModel: itemGui.core ? itemGui.core.haveModel : false
property bool isCanceled: itemGui.core ? itemGui.core.state === LinphoneEnums.ConferenceInfoState.Cancelled : false
property bool isSelected: itemGui.core == mainItem.selectedConference?.core
RowLayout{
RowLayout {
id: delegateIn
anchors.fill: parent
anchors.topMargin: !itemDelegate.isFirst && dateDay.visible ? itemDelegate.topOffset : 0
spacing: 0
Item{
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
visible: !dateDay.visible
}
ColumnLayout {
id: dateDay
Layout.fillWidth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.minimumWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(51)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.minimumWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(51)
visible: previousDateString.length == 0 || previousDateString != dateString
spacing: 0
Text {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(19)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(19)
Layout.alignment: Qt.AlignCenter
text: day.substring(0,3) + '.'
text: day.substring(0, 3) + '.'
color: DefaultStyle.main2_500_main
wrapMode: Text.NoWrap
elide: Text.ElideNone
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
capitalization: Font.Capitalize
}
}
Rectangle {
id: dayNum
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
Layout.alignment: Qt.AlignCenter
radius: height/2
radius: height / 2
property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime)
color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent"
Text {
anchors.centerIn: parent
verticalAlignment: Text.AlignVCenter
@ -233,58 +239,62 @@ ListView {
color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500_main
wrapMode: Text.NoWrap
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(800)
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(800)
}
}
}
Item{Layout.fillHeight:true;Layout.fillWidth: true}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
}
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(265)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(63)
Layout.leftMargin: Utils.getSizeWithScreenRatio(23)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(265)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(63)
Layout.leftMargin: Utils.getSizeWithScreenRatio(23)
Rectangle {
id: conferenceInfoDelegate
anchors.fill: parent
anchors.rightMargin: 5 // margin to avoid clipping shadows at right
radius: Utils.getSizeWithScreenRatio(10)
radius: Utils.getSizeWithScreenRatio(10)
visible: itemDelegate.haveModel || mainItem.currentIndex === itemDelegate.index
color: itemDelegate.isSelected ? DefaultStyle.main2_200 : DefaultStyle.grey_0 // mainItem.currentIndex === index
ColumnLayout {
anchors.fill: parent
anchors.left: parent.left
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(16)
anchors.topMargin: Utils.getSizeWithScreenRatio(10)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(2)
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(16)
anchors.topMargin: Utils.getSizeWithScreenRatio(10)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(2)
visible: itemDelegate.haveModel
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.videoconference
colorizationColor: DefaultStyle.main2_600
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
text: itemGui.core? itemGui.core.subject : ""
text: itemGui.core ? itemGui.core.subject : ""
Layout.fillWidth: true
maximumLineCount: 1
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
}
Text {
//: "Réunion annulée"
text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime)
//: "Réunion annulée"
text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - "
+ UtilsCpp.toDateHourString(endDateTime)
color: itemDelegate.isCanceled ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
}
@ -299,17 +309,17 @@ ListView {
}
Text {
anchors.fill: parent
anchors.rightMargin: Utils.getSizeWithScreenRatio(5) // margin to avoid clipping shadows at right
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
anchors.rightMargin: Utils.getSizeWithScreenRatio(5) // margin to avoid clipping shadows at right
anchors.leftMargin: Utils.getSizeWithScreenRatio(16)
verticalAlignment: Text.AlignVCenter
visible: !itemDelegate.haveModel
//: "Aucune réunion aujourd'hui"
text: qsTr("meetings_list_no_meeting_for_today")
//: "Aucune réunion aujourd'hui"
text: qsTr("meetings_list_no_meeting_for_today")
lineHeightMode: Text.FixedHeight
lineHeight: Utils.getSizeWithScreenRatio(18)
lineHeight: Utils.getSizeWithScreenRatio(18)
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
MouseArea {
@ -319,33 +329,33 @@ ListView {
cursorShape: itemDelegate.isCanceled ? Qt.ArrowCursor : Qt.PointingHandCursor
visible: itemDelegate.haveModel
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: (mouse) => {
if (mouse.button === Qt.RightButton) {
deletePopup.x = mouse.x
deletePopup.y = mouse.y
deletePopup.open()
}
else if (!itemDelegate.isCanceled) mainItem.selectIndex(index)
}
onClicked: mouse => {
if (mouse.button === Qt.RightButton) {
deletePopup.x = mouse.x;
deletePopup.y = mouse.y;
deletePopup.open();
} else if (!itemDelegate.isCanceled)
mainItem.selectIndex(index);
}
Popup {
id: deletePopup
parent: mouseArea
padding: Utils.getSizeWithScreenRatio(10)
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape
padding: Utils.getSizeWithScreenRatio(10)
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape
contentItem: IconLabelButton {
style: ButtonStyle.hoveredBackgroundRed
property var isMeObj: UtilsCpp.isMe(itemDelegate.itemGui?.core?.organizerAddress)
property bool canCancel: isMeObj && isMeObj.value
&& itemDelegate.itemGui?.core?.state !== LinphoneEnums.ConferenceInfoState.Cancelled
&& UtilsCpp.daysOffset(new Date(), itemDelegate.itemGui?.core?.endDateTime) >= 0
property bool canCancel: isMeObj && isMeObj.value && itemDelegate.itemGui?.core?.state
!== LinphoneEnums.ConferenceInfoState.Cancelled && UtilsCpp.daysOffset(new Date(), itemDelegate.itemGui
?.core?.endDateTime) >= 0
icon.source: AppIcons.trashCan
//: "Supprimer la réunion"
text: qsTr("meeting_info_delete")
onClicked: {
if (itemDelegate.itemGui) {
mainItem.meetingDeletionRequested(itemDelegate.itemGui, canCancel)
deletePopup.close()
mainItem.meetingDeletionRequested(itemDelegate.itemGui, canCancel);
deletePopup.close();
}
}
}

View file

@ -11,8 +11,8 @@ ListView {
height: contentHeight
visible: contentHeight > 0
clip: true
rightMargin: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(5)
rightMargin: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(5)
property string searchBarText
@ -32,28 +32,28 @@ ListView {
}
delegate: Item {
height: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
width: mainItem.width
RowLayout {
id: participantDelegate
anchors.left: parent.left
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
anchors.verticalCenter: parent.verticalCenter
spacing: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
z: 1
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
_address: modelData.core.address
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
shadowEnabled: false
}
Text {
text: modelData.core.displayName
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
maximumLineCount: 1
Layout.fillWidth: true

View file

@ -8,7 +8,7 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
clip: true
spacing: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(5)
property bool hoverEnabled: true
property bool displayNameCapitalization: true
@ -48,7 +48,9 @@ ListView {
maximumLineCount: 1
Layout.fillWidth: true
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
}
MouseArea {
id: mousearea

View file

@ -4,15 +4,15 @@ import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
visible: contentHeight > 0
clip: true
rightMargin: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(8)
rightMargin: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(8)
property string searchBarText
@ -26,7 +26,7 @@ ListView {
property ConferenceInfoGui confInfoGui
signal addParticipantRequested()
signal addParticipantRequested
Control.ScrollBar.vertical: ScrollBar {
id: scrollbar
@ -44,37 +44,40 @@ ListView {
}
delegate: Item {
height: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
width: mainItem.width
RowLayout {
id: participantDelegate
anchors.fill: parent
anchors.rightMargin: (scrollbar.width + Utils.getSizeWithScreenRatio(5))
spacing: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
z: 1
Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
_address: modelData.core.sipAddress
secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
shadowEnabled: false
}
Text {
text: modelData.core.displayName
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
maximumLineCount: 1
Layout.fillWidth: true
}
Item{Layout.fillWidth: true}
Item {
Layout.fillWidth: true
}
RowLayout {
Layout.alignment: Qt.AlignRight
property bool isMe: modelData.core.isMe
onIsMeChanged: if (isMe) mainItem.me = modelData
spacing: Utils.getSizeWithScreenRatio(26)
onIsMeChanged: if (isMe)
mainItem.me = modelData
spacing: Utils.getSizeWithScreenRatio(26)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10)
Text {
visible: mainItem.isMeAdmin || modelData.core.isAdmin
Layout.alignment: Qt.AlignRight
@ -88,20 +91,21 @@ ListView {
}
Switch {
opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0
Component.onCompleted: if (modelData.core.isAdmin) toggle()
Component.onCompleted: if (modelData.core.isAdmin)
toggle()
//TODO : Utilser checked et onToggled (pas compris)
onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1)
}
}
SmallButton {
opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
color: DefaultStyle.main2_100
leftPadding: Utils.getSizeWithScreenRatio(3)
rightPadding: Utils.getSizeWithScreenRatio(3)
topPadding: Utils.getSizeWithScreenRatio(3)
bottomPadding: Utils.getSizeWithScreenRatio(3)
leftPadding: Utils.getSizeWithScreenRatio(3)
rightPadding: Utils.getSizeWithScreenRatio(3)
topPadding: Utils.getSizeWithScreenRatio(3)
bottomPadding: Utils.getSizeWithScreenRatio(3)
style: ButtonStyle.hoveredBackground
icon.source: AppIcons.closeX
onClicked: participantModel.removeParticipant(modelData.core)

View file

@ -6,29 +6,29 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ProgressBar {
id: mainItem
padding: Utils.getSizeWithScreenRatio(3)
padding: Utils.getSizeWithScreenRatio(3)
property color backgroundColor: DefaultStyle.main2_100
property color innerColor: DefaultStyle.info_500_main
property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0
property bool innerTextVisible: true
property string innerText: Number.parseFloat(value*100).toFixed(0) + "%"
property real barWidth: mainItem.visualPosition * mainItem.width
property string innerText: Number.parseFloat(value * 100).toFixed(0) + "%"
property real barWidth: mainItem.visualPosition * mainItem.width
property bool centeredText: textSize.width >= barWidth
TextMetrics{
id: textSize
text: mainItem.innerText
font {
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700)
TextMetrics {
id: textSize
text: mainItem.innerText
font {
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700)
bold: true
}
}
}
}
background: Rectangle {
color: mainItem.backgroundColor
radius: Utils.getSizeWithScreenRatio(50)
radius: Utils.getSizeWithScreenRatio(50)
anchors.fill: mainItem
width: mainItem.width
height: mainItem.height
@ -38,7 +38,7 @@ Control.ProgressBar {
Rectangle {
id: bar
color: mainItem.innerColor
radius: Utils.getSizeWithScreenRatio(50)
radius: Utils.getSizeWithScreenRatio(50)
width: mainItem.barWidth
height: parent.height
}
@ -52,9 +52,9 @@ Control.ProgressBar {
color: mainItem.innerTextColor
maximumLineCount: 1
font {
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700)
}
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700)
}
}
}
}

View file

@ -4,7 +4,7 @@ import QtQuick.Shapes
import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ProgressBar{
ProgressBar {
id: mainItem
property string text: value + '%'
implicitHeight: 35
@ -12,32 +12,33 @@ ProgressBar{
to: 100
value: 0
background: Item {}
Timer{
Timer {
id: animationTest
repeat: true
onTriggered: value = (value + 1) % to
interval: 5
}
contentItem: Item{
contentItem: Item {
Shape {
id: shape
anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2)
property real progressionRadius : Math.round(Math.min(shape.width / 2, shape.height / 2) - Utils.getSizeWithScreenRatio(3) / 2)
property real progressionRadius: Math.round(Math.min(shape.width / 2, shape.height / 2)
- Utils.getSizeWithScreenRatio(3) / 2)
layer.enabled: true
layer.samples: 8
layer.smooth: true
vendorExtensionsEnabled: false
ShapePath {
id: pathDial
strokeColor: DefaultStyle.main1_100
fillColor: 'transparent'
strokeWidth: Utils.getSizeWithScreenRatio(3)
capStyle: Qt.RoundCap
PathAngleArc {
radiusX: shape.progressionRadius
radiusY: shape.progressionRadius
@ -47,25 +48,25 @@ ProgressBar{
sweepAngle: 360
}
}
ShapePath {
id: pathProgress
strokeColor: DefaultStyle.main1_500_main
fillColor: 'transparent'
strokeWidth: Utils.getSizeWithScreenRatio(3)
capStyle: Qt.RoundCap
PathAngleArc {
radiusX: shape.progressionRadius
radiusY: shape.progressionRadius
centerX: Math.round(shape.width / 2)
centerY: Math.round(shape.height / 2)
startAngle: -90 // top start
sweepAngle: (360/ mainItem.to * mainItem.value)
sweepAngle: (360 / mainItem.to * mainItem.value)
}
}
}
Text{
Text {
anchors.centerIn: parent
text: mainItem.text
color: DefaultStyle.main1_500_main

View file

@ -5,12 +5,12 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Control {
id: mainItem
// width: Utils.getSizeWithScreenRatio(360)
// width: Utils.getSizeWithScreenRatio(360)
property color backgroundColor: DefaultStyle.grey_0
padding: Utils.getSizeWithScreenRatio(10)
padding: Utils.getSizeWithScreenRatio(10)
background: Rectangle {
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(15)
radius: Utils.getSizeWithScreenRatio(15)
color: mainItem.backgroundColor
}
}

View file

@ -4,29 +4,29 @@ import QtQuick.Layouts
import QtQuick.Effects
import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Item {
id: mainItem
height: visible ? Utils.getSizeWithScreenRatio(50) : 0
height: visible ? Utils.getSizeWithScreenRatio(50) : 0
anchors.right: parent.right
anchors.left: parent.left
property bool keyboardOtherFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
property string titleText
property bool isSelected: false
signal selected()
signal selected
//: %1 settings
Accessible.name: qsTr("setting_tab_accessible_name").arg(titleText)
Accessible.role: Accessible.ListItem
Keys.onPressed: (event)=>{
if(event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter){
mainItem.selected()
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) {
mainItem.selected();
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
@ -35,7 +35,7 @@ Item {
id: background
anchors.fill: parent
color: mainItem.isSelected ? DefaultStyle.main2_200 : parent.containsMouse ? DefaultStyle.main2_100 : "transparent"
radius: mainItem.height / 2
radius: mainItem.height / 2
bottomRightRadius: 0
topRightRadius: 0
visible: parent.containsMouse || mainItem.isSelected || mainItem.keyboardOtherFocus
@ -43,7 +43,7 @@ Item {
border.width: mainItem.keyboardOtherFocus ? Utils.getSizeWithScreenRatio(3) : 0
}
onClicked: {
mainItem.selected()
mainItem.selected();
}
}
Text {
@ -54,5 +54,4 @@ Item {
text: mainItem.titleText
font: Typography.h4
}
}

View file

@ -23,51 +23,30 @@ Item {
property var callState: call && call.core.state || undefined
property AccountGui account: null
property ParticipantDeviceGui participantDevice: null
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false
property bool displayBorder: participantDevice && participantDevice.core.isSpeaking || false
property alias displayPresence: avatar.displayPresence
property color color: DefaultStyle.grey_600
property real radius: Utils.getSizeWithScreenRatio(15)
property bool remoteIsPaused: participantDevice
? participantDevice.core.isPaused
: previewEnabled
? callState === LinphoneEnums.CallState.Paused
: callState === LinphoneEnums.CallState.PausedByRemote
property real radius: Utils.getSizeWithScreenRatio(15)
property bool remoteIsPaused: participantDevice ? participantDevice.core.isPaused : previewEnabled ? callState
=== LinphoneEnums.CallState.Paused : callState === LinphoneEnums.CallState.PausedByRemote
property string remoteAddress: account
? account.core.identityAddress
: participantDevice
? participantDevice.core.address
: call
? call.core.remoteAddress
: ""
property var localNameObj: previewEnabled && call
? UtilsCpp.getDisplayName(call.core.localAddress)
: null
property string remoteAddress: account ? account.core.identityAddress : participantDevice
? participantDevice.core.address : call ? call.core.remoteAddress : ""
property var localNameObj: previewEnabled && call ? UtilsCpp.getDisplayName(call.core.localAddress) : null
property string localName: localNameObj ? localNameObj.value : ""
property string displayName: account
? account.core.displayName
: participantDevice
? participantDevice.core.displayName
: call
? previewEnabled
? localName
: call.core.remoteName
: ""
property string displayName: account ? account.core.displayName : participantDevice
? participantDevice.core.displayName : call ? previewEnabled ? localName : call.core.remoteName : ""
property var contactObj: call ? UtilsCpp.findFriendByAddress(call.core.remoteAddress) : null
property var contact: contactObj && contactObj.value || null
property var identityAddress: account ? UtilsCpp.getDisplayName(account.core.identityAddress) : null
property bool videoEnabled: (previewEnabled && call && call.core.cameraEnabled)
|| (!previewEnabled && call && call.core.remoteVideoEnabled)
|| (participantDevice && participantDevice.core.videoEnabled)
property bool videoEnabled: (previewEnabled && call && call.core.cameraEnabled) || (!previewEnabled && call
&& call.core.remoteVideoEnabled) || (participantDevice && participantDevice.core.videoEnabled)
property string qmlName
property bool displayAll : !!mainItem.call
property bool mutedStatus: participantDevice
? participantDevice.core.isMuted
: account && call
? call.core.conference && call.core.microphoneMuted
: false
property bool displayAll: !!mainItem.call
property bool mutedStatus: participantDevice ? participantDevice.core.isMuted : account && call ? call.core.conference
&& call.core.microphoneMuted : false
clip: false
Rectangle {
id: background
@ -75,78 +54,79 @@ Item {
radius: mainItem.radius
anchors.fill: parent
border.color: DefaultStyle.main2_200
border.width: mainItem.displayBorder ? Utils.getSizeWithScreenRatio(3) : 0
property real minSize: Math.min(height, width)
border.width: mainItem.displayBorder ? Utils.getSizeWithScreenRatio(3) : 0
property real minSize: Math.min(height, width)
Item {
id: noCameraLayout
anchors.fill: parent
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
ColumnLayout {
anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(81)
anchors.topMargin: Utils.getSizeWithScreenRatio(81)
anchors.horizontalCenter: parent.horizontalCenter
// Layout.alignment: Qt.AlignHCenter |Qt.AlignTop
spacing: 0
visible: !mainItem.account && (mainItem.callState === LinphoneEnums.CallState.OutgoingInit
|| mainItem.callState === LinphoneEnums.CallState.OutgoingProgress
|| mainItem.callState === LinphoneEnums.CallState.OutgoingRinging
|| mainItem.callState === LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainItem.callState === LinphoneEnums.CallState.IncomingReceived)
visible: !mainItem.account && (mainItem.callState === LinphoneEnums.CallState.OutgoingInit || mainItem.callState
=== LinphoneEnums.CallState.OutgoingProgress || mainItem.callState
=== LinphoneEnums.CallState.OutgoingRinging || mainItem.callState
=== LinphoneEnums.CallState.OutgoingEarlyMedia || mainItem.callState
=== LinphoneEnums.CallState.IncomingReceived)
BusyIndicator {
indicatorColor: DefaultStyle.main2_100
Layout.alignment: Qt.AlignHCenter
indicatorHeight: Utils.getSizeWithScreenRatio(42)
indicatorWidth: Utils.getSizeWithScreenRatio(42)
indicatorHeight: Utils.getSizeWithScreenRatio(42)
indicatorWidth: Utils.getSizeWithScreenRatio(42)
}
}
Item{
Item {
id: centerItem
visible: !mainItem.remoteIsPaused
anchors.centerIn: parent
height: mainItem.conference
? background.minSize * 142 / 372
: Utils.getSizeWithScreenRatio(120)
height: mainItem.conference ? background.minSize * 142 / 372 : Utils.getSizeWithScreenRatio(120)
width: height
Avatar{
Avatar {
id: avatar
anchors.fill: parent
visible: !joiningView.visible
account: mainItem.account
call: !mainItem.previewEnabled ? mainItem.call : null
displayNameVal: mainItem.displayName
securityBreach: mainItem.securityBreach ? mainItem.securityBreach : securityLevel === LinphoneEnums.SecurityLevel.Unsafe
securityBreach: mainItem.securityBreach ? mainItem.securityBreach : securityLevel
=== LinphoneEnums.SecurityLevel.Unsafe
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
}
ColumnLayout{
ColumnLayout {
id: joiningView
anchors.centerIn: parent
spacing: 0
visible: mainItem.participantDevice && (mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state == LinphoneEnums.ParticipantDeviceState.Alerting) || false
visible: mainItem.participantDevice && (mainItem.participantDevice.core.state
== LinphoneEnums.ParticipantDeviceState.Joining || mainItem.participantDevice.core.state
== LinphoneEnums.ParticipantDeviceState.Alerting) || false
BusyIndicator {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(42)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(42)
indicatorColor: DefaultStyle.main2_100
Layout.alignment: Qt.AlignHCenter
indicatorHeight: Utils.getSizeWithScreenRatio(42)
indicatorWidth: Utils.getSizeWithScreenRatio(42)
indicatorHeight: Utils.getSizeWithScreenRatio(42)
indicatorWidth: Utils.getSizeWithScreenRatio(42)
}
Text {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(27)
Layout.topMargin: Utils.getSizeWithScreenRatio(15) // (84-27)-42
//: "rejoint"
text: qsTr("conference_participant_joining_text")
Layout.preferredHeight: Utils.getSizeWithScreenRatio(27)
Layout.topMargin: Utils.getSizeWithScreenRatio(15) // (84-27)-42
//: "rejoint"
text: qsTr("conference_participant_joining_text")
color: DefaultStyle.grey_0
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
}
ColumnLayout {
anchors.centerIn: parent
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
visible: mainItem.remoteIsPaused
EffectImage {
imageSource: AppIcons.pause
@ -158,11 +138,11 @@ Item {
Text {
color: DefaultStyle.grey_0
Layout.alignment: Qt.AlignHCenter
//: "En pause"
text: qsTr("conference_participant_paused_text")
//: "En pause"
text: qsTr("conference_participant_paused_text")
font {
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
@ -170,7 +150,7 @@ Item {
spacing: 0
visible: mainItem.displayAll && !mainItem.remoteIsPaused && !mainItem.conference
anchors.top: centerItem.bottom
anchors.topMargin: Utils.getSizeWithScreenRatio(21)
anchors.topMargin: Utils.getSizeWithScreenRatio(21)
anchors.left: parent.left
anchors.right: parent.right
@ -180,8 +160,8 @@ Item {
text: mainItem.displayName
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(22)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(22)
weight: Utils.getSizeWithScreenRatio(300)
capitalization: Font.Capitalize
}
}
@ -192,37 +172,37 @@ Item {
text: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_text) : _text
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
}
Loader{
Loader {
id: cameraLoader
anchors.fill: parent
property bool reset: false
Timer{
Timer {
id: resetTimer
interval: 1
triggeredOnStart: true
onTriggered: {cameraLoader.reset = !cameraLoader.reset}
onTriggered: {
cameraLoader.reset = !cameraLoader.reset;
}
}
active: mainItem.visible && !mainItem.remoteIsPaused
&& mainItem.videoEnabled
&& mainItem.callState !== LinphoneEnums.CallState.End
&& mainItem.callState !== LinphoneEnums.CallState.Released
&& !cameraLoader.reset
onActiveChanged: console.log("("+mainItem.qmlName+") Camera active " + active +", visible="+mainItem.visible +", videoEnabled="+mainItem.videoEnabled +", reset="+cameraLoader.reset)
active: mainItem.visible && !mainItem.remoteIsPaused && mainItem.videoEnabled && mainItem.callState
!== LinphoneEnums.CallState.End && mainItem.callState !== LinphoneEnums.CallState.Released && !cameraLoader.reset
onActiveChanged: console.log("(" + mainItem.qmlName + ") Camera active " + active + ", visible=" + mainItem.visible
+ ", videoEnabled=" + mainItem.videoEnabled + ", reset=" + cameraLoader.reset)
sourceComponent: cameraComponent
}
Component{
Component {
id: cameraComponent
Item {
height: cameraLoader.height
width: cameraLoader.width
property alias isReady: cameraItem.isReady
CameraGui{
CameraGui {
id: cameraItem
anchors.fill: parent
visible: false
@ -230,10 +210,10 @@ Item {
isPreview: mainItem.previewEnabled
call: mainItem.call
participantDevice: mainItem.participantDevice
onRequestNewRenderer: {
console.log("Request new renderer for " +mainItem.qmlName)
resetTimer.restart()
console.log("Request new renderer for " + mainItem.qmlName);
resetTimer.restart();
}
layer.enabled: true
}
@ -256,21 +236,18 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
anchors.rightMargin: Utils.getSizeWithScreenRatio(10)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
width: implicitWidth
maximumLineCount: 1
property string _text: mainItem.displayName != ''
? mainItem.displayName
: mainItem.account && mainItem.identityAddress
? mainItem.identityAddress.value
: ""
property string _text: mainItem.displayName != '' ? mainItem.displayName : mainItem.account
&& mainItem.identityAddress ? mainItem.identityAddress.value : ""
text: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_text) : _text
color: DefaultStyle.grey_0
font {
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(14)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
@ -284,25 +261,25 @@ Item {
shadowScale: 1.05
shadowOpacity: 0.5
}
RowLayout{
RowLayout {
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: Utils.getSizeWithScreenRatio(8)
anchors.topMargin: Utils.getSizeWithScreenRatio(8)
height: Utils.getSizeWithScreenRatio(18)
anchors.rightMargin: Utils.getSizeWithScreenRatio(8)
anchors.topMargin: Utils.getSizeWithScreenRatio(8)
height: Utils.getSizeWithScreenRatio(18)
spacing: 0
Rectangle {
id: muteIcon
Layout.preferredWidth: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
Layout.preferredHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
Layout.preferredWidth: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
Layout.preferredHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
visible: mainItem.mutedStatus
color: DefaultStyle.grey_0
radius: width /2
radius: width / 2
EffectImage {
anchors.centerIn: parent
imageWidth: Math.min(Math.round(mainItem.width / 16),Utils.getSizeWithScreenRatio(20))
imageHeight: Math.min(Math.round(mainItem.width / 16),Utils.getSizeWithScreenRatio(20))
imageWidth: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
imageHeight: Math.min(Math.round(mainItem.width / 16), Utils.getSizeWithScreenRatio(20))
imageSource: AppIcons.microphoneSlash
colorizationColor: DefaultStyle.main2_500_main
}

View file

@ -9,27 +9,28 @@ Text {
color: DefaultStyle.danger_500_main
property bool isVisible: text.length > 0
function clear() {
autoHideErrorMessage.stop()
text = ""
autoHideErrorMessage.stop();
text = "";
}
function setText(text) {
if (text.length === 0) {
clear()
clear();
} else {
mainItem.text = text
mainItem.text = text;
}
}
font {
pixelSize: Typography.b3.pixelSize
weight: Typography.b3.weight
pixelSize: Typography.b3.pixelSize
weight: Typography.b3.weight
}
Timer {
id: autoHideErrorMessage
interval: 5000
onTriggered: {
mainItem.clear()
mainItem.clear();
}
}
onTextChanged: if (mainItem.text.length > 0) autoHideErrorMessage.restart()
onTextChanged: if (mainItem.text.length > 0)
autoHideErrorMessage.restart()
}

View file

@ -9,7 +9,7 @@ Quick.Text {
width: txtMeter.advanceWidth
property alias tooltip: tooltip
property alias mouseArea: mouseArea
Quick.MouseArea {
Quick.MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
@ -23,15 +23,15 @@ Quick.Text {
}
font {
family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Typography.p1.weight
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Typography.p1.weight
}
color: DefaultStyle.main2_600
textFormat: Text.PlainText
wrapMode: Quick.Text.Wrap
elide: Quick.Text.ElideRight
transformOrigin: Quick.Item.TopLeft
transform: Quick.Scale {
transform: Quick.Scale {
yScale: scaleLettersFactor
}

View file

@ -11,7 +11,7 @@ Control.ToolTip {
id: tooltipBackground
opacity: 0.7
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
radius: Utils.getSizeWithScreenRatio(15)
}
contentItem: Quick.Text {
text: mainItem.text

View file

@ -5,38 +5,38 @@ import QtQuick.Effects
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Control {
id: mainItem
property int unread: 0
width: Utils.getSizeWithScreenRatio(14)
height: Utils.getSizeWithScreenRatio(14)
visible: unread > 0
background: Item {
anchors.fill: parent
Rectangle {
id: background
anchors.fill: parent
radius: width/2
color: DefaultStyle.danger_500_main
}
MultiEffect {
id: shadow
anchors.fill: background
source: background
// Crash : https://bugreports.qt.io/browse/QTBUG-124730?
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowOpacity: 0.15
z: mainItem.z - 1
}
}
contentItem: Text {
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0
fontSizeMode: Text.Fit
font.pixelSize: Utils.getSizeWithScreenRatio(10)
text: mainItem.unread > 100 ? '99+' : mainItem.unread
}
}
id: mainItem
property int unread: 0
width: Utils.getSizeWithScreenRatio(14)
height: Utils.getSizeWithScreenRatio(14)
visible: unread > 0
background: Item {
anchors.fill: parent
Rectangle {
id: background
anchors.fill: parent
radius: width / 2
color: DefaultStyle.danger_500_main
}
MultiEffect {
id: shadow
anchors.fill: background
source: background
// Crash : https://bugreports.qt.io/browse/QTBUG-124730?
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowOpacity: 0.15
z: mainItem.z - 1
}
}
contentItem: Text {
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0
fontSizeMode: Text.Fit
font.pixelSize: Utils.getSizeWithScreenRatio(10)
text: mainItem.unread > 100 ? '99+' : mainItem.unread
}
}

View file

@ -13,11 +13,11 @@ FocusScope {
ColumnLayout {
anchors.fill: parent
anchors.topMargin: Utils.getSizeWithScreenRatio(16)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(16)
anchors.leftMargin: Utils.getSizeWithScreenRatio(17)
anchors.rightMargin: Utils.getSizeWithScreenRatio(17)
spacing: Utils.getSizeWithScreenRatio(12)
anchors.topMargin: Utils.getSizeWithScreenRatio(16)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(16)
anchors.leftMargin: Utils.getSizeWithScreenRatio(17)
anchors.rightMargin: Utils.getSizeWithScreenRatio(17)
spacing: Utils.getSizeWithScreenRatio(12)
RoundedPane {
Layout.fillWidth: true
@ -25,32 +25,40 @@ FocusScope {
spacing: 0
Repeater {
model: [
{text: qsTr("conference_layout_grid"), imgUrl: AppIcons.layout},
{text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip},
{text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform}
{
text: qsTr("conference_layout_grid"),
imgUrl: AppIcons.layout
},
{
text: qsTr("conference_layout_active_speaker"),
imgUrl: AppIcons.pip
},
{
text: qsTr("conference_layout_audio_only"),
imgUrl: AppIcons.waveform
}
]
RadioButton {
id: radiobutton
enabled: mainItem.call && !mainItem.call.core.paused
checkOnClick: false
color: DefaultStyle.main1_500_main
indicatorSize: Utils.getSizeWithScreenRatio(20)
indicatorSize: Utils.getSizeWithScreenRatio(20)
leftPadding: indicator.width + spacing
spacing: Utils.getSizeWithScreenRatio(8)
checkable: false // Qt Documentation is wrong: It is true by default. We don't want to change the checked state if the layout change is not effective.
checked: index == 0
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid
: index == 1
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker
: mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.AudioOnly
spacing: Utils.getSizeWithScreenRatio(8)
checkable:
false // Qt Documentation is wrong: It is true by default. We don't want to change the checked state if the layout change is not effective.
checked: index == 0 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid : index == 1
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker : mainItem.conferenceLayout
=== LinphoneEnums.ConferenceLayout.AudioOnly
onClicked: mainItem.changeLayoutRequested(index)
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(5)
EffectImage {
id: radioButtonImg
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
imageSource: modelData.imgUrl
colorizationColor: DefaultStyle.main2_500_main
}
@ -58,7 +66,7 @@ FocusScope {
text: modelData.text
color: DefaultStyle.main2_500_main
verticalAlignment: Text.AlignVCenter
font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.pixelSize: Utils.getSizeWithScreenRatio(14)
Layout.fillWidth: true
}
}
@ -66,6 +74,8 @@ FocusScope {
}
}
}
Item {Layout.fillHeight: true}
Item {
Layout.fillHeight: true
}
}
}

View file

@ -3,24 +3,24 @@ import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import ConstantsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout {
id: mainItem
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
FormItemLayout {
id: username
Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
//: Nom d'utilisateur : username
label: qsTr("username")
Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
//: Nom d'utilisateur : username
label: qsTr("username")
mandatory: true
enableErrorText: true
contentItem: TextField {
id: usernameEdit
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: username.errorTextVisible || (errorText.isVisible && text.length > 0)
onAccepted: passwordEdit.forceActiveFocus()
//: "%1 mandatory"
@ -31,15 +31,15 @@ ColumnLayout {
Layout.preferredHeight: password.implicitHeight
FormItemLayout {
id: password
width: Utils.getSizeWithScreenRatio(346)
//: Mot de passe
label: qsTr("password")
width: Utils.getSizeWithScreenRatio(346)
//: Mot de passe
label: qsTr("password")
mandatory: true
enableErrorText: true
contentItem: TextField {
id: passwordEdit
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: password.errorTextVisible || (errorText.isVisible && text.length > 0)
hidden: true
onAccepted: connectionButton.trigger()
@ -52,32 +52,31 @@ ColumnLayout {
target: LoginPageCpp
function onErrorMessageChanged() {
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
errorText.setText(LoginPageCpp.errorMessage)
errorText.setText(LoginPageCpp.errorMessage);
}
}
}
}
}
RowLayout {
Layout.topMargin: Utils.getSizeWithScreenRatio(7)
spacing: Utils.getSizeWithScreenRatio(29)
Layout.topMargin: Utils.getSizeWithScreenRatio(7)
spacing: Utils.getSizeWithScreenRatio(29)
BigButton {
id: connectionButton
style: ButtonStyle.main
Accessible.name: qsTr("assistant_account_login")
Accessible.name: qsTr("assistant_account_login")
contentItem: StackLayout {
id: connectionButtonContent
currentIndex: 0
Text {
//: "Connexion"
text: qsTr("assistant_account_login")
//: "Connexion"
text: qsTr("assistant_account_login")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font {
pixelSize: Typography.b1.pixelSize
weight: Typography.b1.weight
pixelSize: Typography.b1.pixelSize
weight: Typography.b1.weight
}
color: DefaultStyle.grey_0
}
@ -92,34 +91,34 @@ ColumnLayout {
target: LoginPageCpp
function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) {
connectionButton.enabled = true
connectionButtonContent.currentIndex = 0
connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0;
}
}
function onErrorMessageChanged() {
connectionButton.enabled = true
connectionButtonContent.currentIndex = 0
connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0;
}
}
}
function trigger() {
username.errorMessage = ""
password.errorMessage = ""
errorText.text = ""
username.errorMessage = "";
password.errorMessage = "";
errorText.text = "";
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
if (usernameEdit.text.length == 0)
//: "Veuillez saisir un nom d'utilisateur"
username.errorMessage = qsTr("assistant_account_login_missing_username")
//: "Veuillez saisir un nom d'utilisateur"
username.errorMessage = qsTr("assistant_account_login_missing_username");
if (passwordEdit.text.length == 0)
//: "Veuillez saisir un mot de passe"
password.errorMessage = qsTr("assistant_account_login_missing_password")
return
//: "Veuillez saisir un mot de passe"
password.errorMessage = qsTr("assistant_account_login_missing_password");
return;
}
LoginPageCpp.login(usernameEdit.text, passwordEdit.text)
connectionButton.enabled = false
connectionButtonContent.currentIndex = 1
LoginPageCpp.login(usernameEdit.text, passwordEdit.text);
connectionButton.enabled = false;
connectionButtonContent.currentIndex = 1;
}
onPressed: connectionButton.trigger()
@ -127,11 +126,10 @@ ColumnLayout {
SmallButton {
id: forgottenButton
style: ButtonStyle.noBackground
//: "Mot de passe oublié ?"
text: qsTr("assistant_forgotten_password")
//: "Mot de passe oublié ?"
text: qsTr("assistant_forgotten_password")
underline: true
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
}
}
}

View file

@ -3,104 +3,110 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
import SettingsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
signal encryptionValidationRequested()
signal encryptionValidationRequested
property var call
RoundedPane {
Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
leftPadding: Utils.getSizeWithScreenRatio(16)
rightPadding: Utils.getSizeWithScreenRatio(16)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
contentItem: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
Text {
//: "Encryption :"
text: qsTr("call_stats_media_encryption_title")
//: "Encryption :"
text: qsTr("call_stats_media_encryption_title")
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Typography.p2.weight
}
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(7)
spacing: Utils.getSizeWithScreenRatio(7)
Text {
property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp && mainItem.call.core.zrtpStats.isPostQuantum
//: Media encryption : %1
text: qsTr("call_stats_media_encryption").arg(mainItem.call.core.encryptionString)
property bool isPostQuantum: mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
&& mainItem.call.core.zrtpStats.isPostQuantum
//: Media encryption : %1
text: qsTr("call_stats_media_encryption").arg(mainItem.call.core.encryptionString)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
ColumnLayout {
visible: mainItem.call && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
Text {
//: "Algorithme de chiffrement : %1"
text: qsTr("call_stats_zrtp_cipher_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo)
//: "Algorithme de chiffrement : %1"
text: qsTr("call_stats_zrtp_cipher_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.cipherAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
//: "Algorithme d'accord de clé : %1"
text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.keyAgreementAlgo)
//: "Algorithme d'accord de clé : %1"
text: qsTr("call_stats_zrtp_key_agreement_algo").arg(mainItem.call
&& mainItem.call.core.zrtpStats.keyAgreementAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
//: "Algorithme de hachage : %1"
text: qsTr("call_stats_zrtp_hash_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo)
//: "Algorithme de hachage : %1"
text: qsTr("call_stats_zrtp_hash_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.hashAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
//: "Algorithme d'authentification : %1"
text: qsTr("call_stats_zrtp_auth_tag_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo)
//: "Algorithme d'authentification : %1"
text: qsTr("call_stats_zrtp_auth_tag_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.authenticationAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
Text {
//: "Algorithme SAS : %1"
text: qsTr("call_stats_zrtp_sas_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo)
//: "Algorithme SAS : %1"
text: qsTr("call_stats_zrtp_sas_algo").arg(mainItem.call && mainItem.call.core.zrtpStats.sasAlgo)
Layout.alignment: Qt.AlignHCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(500)
}
}
}
}
}
}
Item{Layout.fillHeight: true}
Item {
Layout.fillHeight: true
}
Button {
visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
visible: mainItem.call && !mainItem.call.core.conference && mainItem.call.core.encryption
=== LinphoneEnums.MediaEncryption.Zrtp
Layout.fillWidth: true
//: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label")
//: "Validation chiffrement"
text: qsTr("call_zrtp_validation_button_label")
onClicked: mainItem.encryptionValidationRequested()
Layout.bottomMargin: Utils.getSizeWithScreenRatio(13)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
Layout.bottomMargin: Utils.getSizeWithScreenRatio(13)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
Layout.rightMargin: Utils.getSizeWithScreenRatio(16)
style: ButtonStyle.main
}
}

View file

@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
id: mainItem
@ -14,35 +14,35 @@ ColumnLayout {
property string microDevice: inputAudioDeviceCBox.currentText
property bool ringerDevicesVisible: false
property bool backgroundVisible: true
spacing: Utils.getSizeWithScreenRatio(40)
spacing: Utils.getSizeWithScreenRatio(40)
RoundedPane {
background.visible: mainItem.backgroundVisible
Layout.alignment: Qt.AlignHCenter
height: contentItem.implicitHeight + topPadding + bottomPadding
Layout.fillWidth: true
topPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
bottomPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
leftPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
rightPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
topPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
bottomPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
leftPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
rightPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
contentItem: ColumnLayout {
spacing: mainItem.spacing
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
visible: mainItem.ringerDevicesVisible
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.bellRinger
colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
//: Ringtone - Incoming calls
text: qsTr("multimedia_settings_ringer_title")
//: Ringtone - Incoming calls
text: qsTr("multimedia_settings_ringer_title")
font: Typography.p2l
color: DefaultStyle.main2_600
Layout.fillWidth: true
@ -50,7 +50,7 @@ ColumnLayout {
}
ComboSetting {
Layout.fillWidth: true
Layout.topMargin: Utils.getSizeWithScreenRatio(12)
Layout.topMargin: Utils.getSizeWithScreenRatio(12)
Layout.preferredWidth: parent.width
entries: SettingsCpp.ringerDevices
propertyName: "ringerDevice"
@ -64,20 +64,20 @@ ColumnLayout {
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.speaker
colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
//: "Haut-parleurs"
text: qsTr("multimedia_settings_speaker_title")
//: "Haut-parleurs"
text: qsTr("multimedia_settings_speaker_title")
font: Typography.p2l
Layout.fillWidth: true
}
@ -86,7 +86,7 @@ ColumnLayout {
id: outputAudioDeviceCBox
Layout.fillWidth: true
Layout.preferredWidth: parent.width
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.playbackDevices
propertyName: "playbackDevice"
propertyOwner: SettingsCpp
@ -95,7 +95,7 @@ ColumnLayout {
enabled: mainItem.call
target: outputAudioDeviceCBox
function onCurrentValueChanged() {
SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue)
SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue);
}
}
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
@ -107,28 +107,30 @@ ColumnLayout {
to: 1.0
value: SettingsCpp.playbackGain
onMoved: {
if (mainItem.call) SettingsCpp.lSetPlaybackGain(value)
else SettingsCpp.playbackGain = value
if (mainItem.call)
SettingsCpp.lSetPlaybackGain(value);
else
SettingsCpp.playbackGain = value;
}
//: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.microphone
colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
//: "Microphone"
text: qsTr("multimedia_settings_microphone_title")
//: "Microphone"
text: qsTr("multimedia_settings_microphone_title")
font: Typography.p2l
Layout.fillWidth: true
}
@ -137,7 +139,7 @@ ColumnLayout {
id: inputAudioDeviceCBox
Layout.fillWidth: true
Layout.preferredWidth: parent.width
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.captureDevices
propertyName: "captureDevice"
propertyOwner: SettingsCpp
@ -146,7 +148,7 @@ ColumnLayout {
enabled: mainItem.call
target: inputAudioDeviceCBox
function onCurrentValueChanged() {
SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue)
SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue);
}
}
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
@ -158,8 +160,10 @@ ColumnLayout {
to: 1.0
value: SettingsCpp.captureGain
onMoved: {
if (mainItem.call) SettingsCpp.lSetCaptureGain(value)
else SettingsCpp.captureGain = value
if (mainItem.call)
SettingsCpp.lSetCaptureGain(value);
else
SettingsCpp.captureGain = value;
}
//: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
@ -170,23 +174,23 @@ ColumnLayout {
repeat: true
running: false
onTriggered: {
SettingsCpp.updateMicVolume()
SettingsCpp.updateMicVolume();
}
}
Slider {
id: audioTestSlider
Layout.fillWidth: true
enabled: false
Layout.preferredHeight: Utils.getSizeWithScreenRatio(10)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(10)
background: Rectangle {
x: audioTestSlider.leftPadding
y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2
implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Utils.getSizeWithScreenRatio(10)
implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Utils.getSizeWithScreenRatio(10)
width: audioTestSlider.availableWidth
height: implicitHeight
radius: Utils.getSizeWithScreenRatio(2)
radius: Utils.getSizeWithScreenRatio(2)
color: DefaultStyle.grey_850
Rectangle {
@ -194,40 +198,48 @@ ColumnLayout {
height: parent.height
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.vue_meter_light_green }
GradientStop { position: 1.0; color: DefaultStyle.vue_meter_dark_green}
GradientStop {
position: 0.0
color: DefaultStyle.vue_meter_light_green
}
GradientStop {
position: 1.0
color: DefaultStyle.vue_meter_dark_green
}
}
radius: Utils.getSizeWithScreenRatio(2)
radius: Utils.getSizeWithScreenRatio(2)
}
}
handle: Item {visible: false}
handle: Item {
visible: false
}
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
visible: SettingsCpp.videoEnabled
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.videoCamera
colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
//: "Caméra"
text: qsTr("multimedia_settings_camera_title")
font: Typography.p2l
Layout.fillWidth: true
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
visible: SettingsCpp.videoEnabled
RowLayout {
spacing: Utils.getSizeWithScreenRatio(8)
EffectImage {
imageSource: AppIcons.videoCamera
colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Utils.getSizeWithScreenRatio(24)
}
Text {
//: "Caméra"
text: qsTr("multimedia_settings_camera_title")
font: Typography.p2l
Layout.fillWidth: true
}
}
ComboSetting {
id: videoDevicesCbox
Layout.fillWidth: true
Layout.preferredWidth: parent.width
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.videoDevices
propertyName: "videoDevice"
propertyOwner: SettingsCpp
@ -235,7 +247,7 @@ ColumnLayout {
enabled: mainItem.call
target: videoDevicesCbox
function onCurrentValueChanged() {
SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue)
SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue);
}
}
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_camera_title"))
@ -243,17 +255,17 @@ ColumnLayout {
}
Connections {
target: SettingsCpp
onMicVolumeChanged: (value) => {
audioTestSlider.value = value
}
onMicVolumeChanged: value => {
audioTestSlider.value = value;
}
}
Component.onCompleted: {
SettingsCpp.accessCallSettings()
audioTestSliderTimer.running = true
SettingsCpp.accessCallSettings();
audioTestSliderTimer.running = true;
}
Component.onDestruction: {
audioTestSliderTimer.running = false
SettingsCpp.closeCallSettings()
audioTestSliderTimer.running = false;
SettingsCpp.closeCallSettings();
}
}
}

View file

@ -4,7 +4,7 @@ import QtQuick.Effects
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout {
@ -12,88 +12,91 @@ ColumnLayout {
property CallGui call
property ConferenceGui conference: call.core.conference
property var desc: call.core.videoSourceDescriptor
property bool isLocalScreenSharing : conference?.core.isLocalScreenSharing || false
property bool isLocalScreenSharing: conference?.core.isLocalScreenSharing || false
property bool screenSharingAvailable: !!conference && (!conference.core.isScreenSharingEnabled || isLocalScreenSharing)
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
onIsLocalScreenSharingChanged: {if(isLocalScreenSharing) mainItem.call.core.videoSourceDescriptor = mainItem.desc }
onIsLocalScreenSharingChanged: {
if (isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
Text {
Layout.fillWidth: true
//: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants"
text: qsTr("screencast_settings_choose_window_text")
font.pixelSize: Utils.getSizeWithScreenRatio(14)
//: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants"
text: qsTr("screencast_settings_choose_window_text")
font.pixelSize: Utils.getSizeWithScreenRatio(14)
color: DefaultStyle.main2_500_main
}
TabBar {
Layout.fillWidth: true
id: bar
spacing: Utils.getSizeWithScreenRatio(40)
pixelSize: Utils.getSizeWithScreenRatio(16)
//: "Ecran entier"
model: [qsTr("screencast_settings_all_screen_label"),
//: "Fenêtre"
qsTr("screencast_settings_one_window_label")]
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(40)
pixelSize: Utils.getSizeWithScreenRatio(16)
//: "Ecran entier"
model: [qsTr("screencast_settings_all_screen_label"),
//: "Fenêtre"
qsTr("screencast_settings_one_window_label")]
}
component ScreenPreviewLayout: Control.Control {
id: screenPreview
signal clicked()
signal clicked
property var screenSource
property int screenIndex
property bool selected: false
property bool displayScreen: true
property real horizontalMargin: 0
leftPadding: Utils.getSizeWithScreenRatio(18)
rightPadding: Utils.getSizeWithScreenRatio(18)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
property bool displayScreen: true
property real horizontalMargin: 0
leftPadding: Utils.getSizeWithScreenRatio(18)
rightPadding: Utils.getSizeWithScreenRatio(18)
topPadding: Utils.getSizeWithScreenRatio(13)
bottomPadding: Utils.getSizeWithScreenRatio(13)
background: Rectangle {
anchors.fill: parent
anchors.leftMargin: screenPreview.horizontalMargin
anchors.rightMargin: screenPreview.horizontalMargin
color: screenPreview.selected ? DefaultStyle.main2_100 : DefaultStyle.grey_0
border.width: Utils.getSizeWithScreenRatio(2)
border.width: Utils.getSizeWithScreenRatio(2)
border.color: screenPreview.selected ? DefaultStyle.main2_400 : DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(10)
radius: Utils.getSizeWithScreenRatio(10)
MouseArea {
anchors.fill: parent
onClicked: {
screenPreview.clicked()
screenPreview.clicked();
}
}
}
contentItem: ColumnLayout {
spacing: 0
Item{
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Image {
anchors.centerIn: parent
//Layout.preferredHeight: Utils.getSizeWithScreenRatio(170)
source: $modelData?.windowId ? "image://window/"+ $modelData.windowId : "image://screen/"+ $modelData.screenIndex
//Layout.preferredHeight: Utils.getSizeWithScreenRatio(170)
source: $modelData?.windowId ? "image://window/" + $modelData.windowId : "image://screen/" + $modelData.screenIndex
sourceSize.width: parent.width
sourceSize.height: parent.height
cache: false
}
}
RowLayout{
Layout.topMargin: Utils.getSizeWithScreenRatio(6)
spacing: Utils.getSizeWithScreenRatio(5)
Image{
Layout.preferredHeight: Utils.getSizeWithScreenRatio(15)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(15)
RowLayout {
Layout.topMargin: Utils.getSizeWithScreenRatio(6)
spacing: Utils.getSizeWithScreenRatio(5)
Image {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(15)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(15)
visible: !!$modelData?.windowId
source: visible ? "image://window_icon/"+ $modelData.windowId : ''
source: visible ? "image://window_icon/" + $modelData.windowId : ''
sourceSize.width: width
sourceSize.height: height
cache: false
}
Text {
Layout.fillWidth: true
//: "Ecran %1"
text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex+1)
//: "Ecran %1"
text: !!$modelData?.windowId ? $modelData.name : qsTr("screencast_settings_screen").arg(screenIndex + 1)
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Utils.getSizeWithScreenRatio(displayScreen ? 14 : 10)
font.pixelSize: Utils.getSizeWithScreenRatio(displayScreen ? 14 : 10)
elide: Text.ElideRight
maximumLineCount: 1
}
@ -103,52 +106,57 @@ ColumnLayout {
StackLayout {
id: stacklayout
currentIndex: bar.currentIndex
ListView{
ListView {
id: screensLayout
spacing: Utils.getSizeWithScreenRatio(16)
spacing: Utils.getSizeWithScreenRatio(16)
clip: true
Layout.fillWidth: true
height: visible ? contentHeight : 0
currentIndex: -1
model: ScreenProxy{
model: ScreenProxy {
id: screensList
mode: ScreenList.SCREENS
}
onVisibleChanged: {
if(visible) screensList.update()
else currentIndex = -1
if (visible)
screensList.update();
else
currentIndex = -1;
}
delegate: ScreenPreviewLayout {
horizontalMargin: Utils.getSizeWithScreenRatio(28 - 20 ) // 20 coming from CallsWindow panel
horizontalMargin: Utils.getSizeWithScreenRatio(28 - 20) // 20 coming from CallsWindow panel
width: screensLayout.width
height: Utils.getSizeWithScreenRatio(219)
screenIndex: index
onClicked: {//screensLayout.selectedIndex = index
screensLayout.currentIndex = index
mainItem.desc.core.screenSharingIndex = index
if( mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc
onClicked: {
//screensLayout.selectedIndex = index
screensLayout.currentIndex = index;
mainItem.desc.core.screenSharingIndex = index;
if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
selected: mainItem.desc.core.screenSharingIndex === index
}
}
GridView{
GridView {
id: windowsLayout
//property int selectedIndex
Layout.preferredHeight: visible ? contentHeight : 0
Layout.fillWidth: true
model: ScreenProxy{
model: ScreenProxy {
id: windowsList
mode: ScreenList.WINDOWS
}
currentIndex: -1
onVisibleChanged: {
if(visible) windowsList.update()
else currentIndex = -1
if (visible)
windowsList.update();
else
currentIndex = -1;
}
cellWidth: width / 2
cellHeight: Utils.getSizeWithScreenRatio(112 + 15)
cellHeight: Utils.getSizeWithScreenRatio(112 + 15)
clip: true
delegate: Item {
width: windowsLayout.cellWidth
@ -159,10 +167,10 @@ ColumnLayout {
displayScreen: false
screenIndex: index
onClicked: {
windowsLayout.currentIndex = index
mainItem.desc.core.windowId = $modelData.windowId
if( mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc
windowsLayout.currentIndex = index;
mainItem.desc.core.windowId = $modelData.windowId;
if (mainItem.conference.core.isLocalScreenSharing)
mainItem.call.core.videoSourceDescriptor = mainItem.desc;
}
selected: mainItem.desc.core.windowId == $modelData.windowId
}
@ -172,15 +180,15 @@ ColumnLayout {
BigButton {
Layout.preferredHeight: height
height: implicitHeight
visible: mainItem.screenSharingAvailable$
visible: mainItem.screenSharingAvailable$
enabled: mainItem.isLocalScreenSharing || windowsLayout.currentIndex !== -1 || screensLayout.currentIndex !== -1
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing
//: "Stop
? qsTr("stop")
//: "Partager"
: qsTr("share")
text: mainItem.conference && mainItem.conference.core.isLocalScreenSharing ?
//: "Stop
qsTr("stop") :
//: "Partager"
qsTr("share")
onClicked: {
mainItem.conference.core.lToggleScreenSharing()
mainItem.conference.core.lToggleScreenSharing();
}
style: ButtonStyle.main
}

View file

@ -6,7 +6,7 @@ import QtQuick.Effects
import Linphone
import ConstantsCpp 1.0
import UtilsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
@ -32,24 +32,27 @@ ListView {
from: new Date()
to: UtilsCpp.addYears(new Date(), 5)
}
delegate: FocusScope{
delegate: FocusScope {
width: mainItem.width
height: mainItem.height
property bool isCurrentIndex: index == mainItem.currentIndex
onIsCurrentIndexChanged: if( isCurrentIndex) monthGrid.forceActiveFocus()
onIsCurrentIndexChanged: if (isCurrentIndex)
monthGrid.forceActiveFocus()
ColumnLayout {
anchors.fill: parent
property int currentMonth: model.month
spacing: Utils.getSizeWithScreenRatio(18)
spacing: Utils.getSizeWithScreenRatio(18)
RowLayout {
Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(38)
spacing: Utils.getSizeWithScreenRatio(38)
Text {
text: UtilsCpp.toDateMonthAndYearString(new Date(model.year, model.month, 15))// 15 because of timezones that can change the date for localeString
text: UtilsCpp.toDateMonthAndYearString(new Date(model.year, model.month,
15))// 15 because of timezones that can change the date for localeString
font {
pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight
pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight
capitalization: Font.Capitalize
}
}
@ -58,28 +61,30 @@ ListView {
}
Button {
id: previousButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow
onClicked: if (mainItem.currentIndex > 0) mainItem.currentIndex = mainItem.currentIndex - 1
onClicked: if (mainItem.currentIndex > 0)
mainItem.currentIndex = mainItem.currentIndex - 1
}
Button {
id: nextButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
style: ButtonStyle.noBackground
icon.source: AppIcons.rightArrow
onClicked: if (mainItem.currentIndex < mainItem.count) mainItem.currentIndex = mainItem.currentIndex + 1
onClicked: if (mainItem.currentIndex < mainItem.count)
mainItem.currentIndex = mainItem.currentIndex + 1
}
}
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(12)
spacing: Utils.getSizeWithScreenRatio(12)
Control.DayOfWeekRow {
locale: monthGrid.locale
Layout.column: 1
@ -90,12 +95,12 @@ ListView {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
Control.MonthGrid {
id: monthGrid
Layout.fillWidth: true
@ -106,73 +111,71 @@ ListView {
locale: Qt.locale(ConstantsCpp.DefaultLocale)
delegate: FocusScope {
id: focusDay
property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) : false
property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) :
false
property var d: model.date
objectName: 'focusDay'
activeFocusOnTab: true
focus: UtilsCpp.isCurrentMonth(model.date) && UtilsCpp.isCurrentDay(model.date) || index == 0
Keys.onPressed: (event)=> {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
monthGrid.clicked(model.date)
event.accepted = true;
}else if(event.key == Qt.Key_Left){
var previous = nextItemInFocusChain(false)
if( previous.objectName != 'focusDay'){
previousButton.clicked(undefined)
}else{
if (UtilsCpp.daysOffset(new Date(), model.date) >= 0) previous.forceActiveFocus()
}
}else if(event.key == Qt.Key_Right){
var next = nextItemInFocusChain()
if( next.objectName != 'focusDay'){
nextButton.clicked(undefined)
} else {
next.forceActiveFocus()
}
}
}
MouseArea{
Keys.onPressed: event => {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
monthGrid.clicked(model.date);
event.accepted = true;
} else if (event.key == Qt.Key_Left) {
var previous = nextItemInFocusChain(false);
if (previous.objectName != 'focusDay') {
previousButton.clicked(undefined);
} else {
if (UtilsCpp.daysOffset(new Date(), model.date) >= 0)
previous.forceActiveFocus();
}
} else if (event.key == Qt.Key_Right) {
var next = nextItemInFocusChain();
if (next.objectName != 'focusDay') {
nextButton.clicked(undefined);
} else {
next.forceActiveFocus();
}
}
}
MouseArea {
id: hoveringArea
anchors.fill: parent
hoverEnabled: true
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton
// onEntered: focusDay.forceActiveFocus()
onPressed: (event) =>{
focusDay.forceActiveFocus()
event.accepted = false
}
onPressed: event => {
focusDay.forceActiveFocus();
event.accepted = false;
}
}
Rectangle {
anchors.centerIn: parent
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
radius: Utils.getSizeWithScreenRatio(50)
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
radius: Utils.getSizeWithScreenRatio(50)
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
border.width: focusDay.activeFocus || hoveringArea.containsMouse ? 1 : 0
}
Text {
anchors.centerIn: parent
text: UtilsCpp.toDateDayString(model.date)
color: isSelectedDay
? DefaultStyle.grey_0
: UtilsCpp.isCurrentDay(model.date)
? DefaultStyle.main1_500_main
: UtilsCpp.dateisInMonth(model.date, mainItem.currentMonth, mainItem.currentYear)
? DefaultStyle.main2_700
: DefaultStyle.main2_400
color: isSelectedDay ? DefaultStyle.grey_0 : UtilsCpp.isCurrentDay(model.date) ? DefaultStyle.main1_500_main : UtilsCpp.dateisInMonth(
model.date, mainItem.currentMonth, mainItem.currentYear) ? DefaultStyle.main2_700 :
DefaultStyle.main2_400
font {
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300)
}
}
}
onClicked: (date) => {
if (UtilsCpp.daysOffset(new Date(), date) >= 0) mainItem.selectedDate = date
}
onClicked: date => {
if (UtilsCpp.daysOffset(new Date(), date) >= 0)
mainItem.selectedDate = date;
}
}
}
}

View file

@ -5,51 +5,51 @@ import QtQuick.Layouts
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Control {
id: mainItem
// property alias placeholderText: sendingTextArea.placeholderText
property string text
property var textArea
property int selectedFilesCount: 0
// property alias cursorPosition: sendingTextArea.cursorPosition
property bool dropEnabled: true
property bool isEphemeral : false
property bool isEphemeral: false
property bool emojiVisible: false
// disable record button if call ongoing
property bool callOngoing: false
property bool isEditing: false
property ChatGui chat
property ChatGui chat
signal focusTextArea()
// ---------------------------------------------------------------------------
signal dropped (var files)
signal validText (string text)
signal sendMessage()
signal emojiClicked()
signal composing()
signal focusTextArea
// ---------------------------------------------------------------------------
function _emitFiles (files) {
signal dropped(var files)
signal validText(string text)
signal sendMessage
signal emojiClicked
signal composing
// ---------------------------------------------------------------------------
function _emitFiles(files) {
// Filtering files, other urls are forbidden.
files = files.reduce(function (files, file) {
if (file.toString().startsWith("file:")) {
files.push(Utils.getSystemPathFromUri(file))
files.push(Utils.getSystemPathFromUri(file));
}
return files
}, [])
return files;
}, []);
if (files.length > 0) {
dropped(files)
dropped(files);
}
}
@ -65,7 +65,7 @@ Control.Control {
rightPadding: Utils.getSizeWithScreenRatio(15)
topPadding: Utils.getSizeWithScreenRatio(16)
bottomPadding: Utils.getSizeWithScreenRatio(16)
background: Rectangle {
anchors.fill: parent
color: DefaultStyle.grey_100
@ -74,7 +74,7 @@ Control.Control {
id: sendingAreaStackView
initialItem: textAreaComp
onHeightChanged: {
mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding
mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding;
}
Component {
id: textAreaComp
@ -95,7 +95,7 @@ Control.Control {
style: ButtonStyle.noBackground
icon.source: AppIcons.paperclip
onClicked: {
fileDialog.open()
fileDialog.open();
}
}
Control.Control {
@ -129,21 +129,23 @@ Control.Control {
contentWidth: width
onContentHeightChanged: {
if (sendingTextArea.contentHeight > mainItem.height - (mainItem.topPadding + mainItem.bottomPadding + sendingControl.topPadding + sendingControl.bottomPadding)
&& sendingTextArea.contentHeight < Utils.getSizeWithScreenRatio(100)) {
mainItem.height = sendingTextArea.contentHeight + mainItem.topPadding + mainItem.bottomPadding + sendingControl.topPadding + sendingControl.bottomPadding
if (sendingTextArea.contentHeight > mainItem.height - (mainItem.topPadding + mainItem.bottomPadding
+ sendingControl.topPadding + sendingControl.bottomPadding) && sendingTextArea.contentHeight
< Utils.getSizeWithScreenRatio(100)) {
mainItem.height = sendingTextArea.contentHeight + mainItem.topPadding + mainItem.bottomPadding
+ sendingControl.topPadding + sendingControl.bottomPadding;
}
}
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
else if (contentX + width <= r.x + r.width)
contentX = r.x + r.width - width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
else if (contentY + height <= r.y + r.height)
contentY = r.y + r.height - height;
}
TextArea {
@ -152,12 +154,12 @@ Control.Control {
height: implicitHeight// sendingAreaFlickable.height
textFormat: TextEdit.PlainText
onTextChanged: {
mainItem.text = text
mainItem.text = text;
}
Component.onCompleted: {
mainItem.textArea = sendingTextArea
sendingTextArea.text = mainItem.text
mainItem.textArea = sendingTextArea;
sendingTextArea.text = mainItem.text;
}
//: Say something : placeholder text for sending message text area
placeholderText: qsTr("chat_view_send_area_placeholder_text")
@ -170,23 +172,23 @@ Control.Control {
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
wrapMode: TextEdit.WordWrap
KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton
Keys.onPressed: (event) => {
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
if(!(event.modifiers & Qt.ShiftModifier)) {
mainItem.sendMessage()
event.accepted = true
}
}
Keys.onPressed: event => {
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
if (!(event.modifiers & Qt.ShiftModifier)) {
mainItem.sendMessage();
event.accepted = true;
}
}
Connections {
target: mainItem
function onTextChanged() {
sendingTextArea.text = mainItem.text
sendingTextArea.text = mainItem.text;
}
function onSendMessage() {
sendingTextArea.clear()
sendingTextArea.clear();
}
function onFocusTextArea() {
sendingTextArea.forceActiveFocus()
sendingTextArea.forceActiveFocus();
}
}
}
@ -201,12 +203,13 @@ Control.Control {
//: Cannot record a message while a call is ongoing
ToolTip.text: qsTr("cannot_record_while_in_call_tooltip")
enabled: !mainItem.callOngoing
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0 && !mainItem.isEditing
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0 &&
!mainItem.isEditing
style: ButtonStyle.noBackground
hoverEnabled: true
icon.source: AppIcons.microphone
onClicked: {
sendingAreaStackView.push(voiceMessageRecordComp)
sendingAreaStackView.push(voiceMessageRecordComp);
}
}
BigButton {
@ -216,7 +219,7 @@ Control.Control {
style: ButtonStyle.noBackgroundOrange
icon.source: mainItem.isEditing ? AppIcons.pencil : AppIcons.paperPlaneRight
onClicked: {
mainItem.sendMessage()
mainItem.sendMessage();
}
}
}
@ -239,22 +242,23 @@ Control.Control {
Layout.preferredWidth: width
Layout.preferredHeight: height
onClicked: {
if (voiceMessage.chatMessage) mainItem.chat.core.lDeleteMessage(voiceMessage.chatMessage)
sendingAreaStackView.pop()
if (voiceMessage.chatMessage)
mainItem.chat.core.lDeleteMessage(voiceMessage.chatMessage);
sendingAreaStackView.pop();
}
}
ChatAudioContent {
id: voiceMessage
onHeightChanged: {
sendingAreaStackView.height = height
sendingAreaStackView.height = height;
}
recording: true
Layout.fillWidth: true
Layout.preferredHeight: Utils.getSizeWithScreenRatio(48)
chatMessageContentGui: chatMessage ? chatMessage.core.getVoiceRecordingContent() : null
onVoiceRecordingMessageCreationRequested: (recorderGui) => {
chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderGui, mainItem.chat)
}
onVoiceRecordingMessageCreationRequested: recorderGui => {
chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderGui, mainItem.chat);
}
}
BigButton {
id: sendButton
@ -267,21 +271,20 @@ Control.Control {
property bool sendVoiceRecordingOnCreated: false
onClicked: {
if (voiceMessage.chatMessage) {
voiceMessage.chatMessage.core.lSend()
sendingAreaStackView.pop()
}
else {
sendVoiceRecordingOnCreated = true
voiceMessage.stopRecording()
voiceMessage.chatMessage.core.lSend();
sendingAreaStackView.pop();
} else {
sendVoiceRecordingOnCreated = true;
voiceMessage.stopRecording();
}
}
Connections {
target: voiceMessage
function onChatMessageChanged() {
if (sendButton.sendVoiceRecordingOnCreated) {
voiceMessage.chatMessage.core.lSend()
sendButton.sendVoiceRecordingOnCreated = false
sendingAreaStackView.pop()
voiceMessage.chatMessage.core.lSend();
sendButton.sendVoiceRecordingOnCreated = false;
sendingAreaStackView.pop();
}
}
}
@ -316,21 +319,24 @@ Control.Control {
}
DropArea {
anchors.fill: parent
keys: [ 'text/uri-list' ]
keys: ['text/uri-list']
visible: mainItem.dropEnabled
onDropped: (drop) => {
state = ''
if (drop.hasUrls) {
_emitFiles(drop.urls)
}
}
onDropped: drop => {
state = '';
if (drop.hasUrls) {
_emitFiles(drop.urls);
}
}
onEntered: state = 'hover'
onExited: state = ''
states: State {
name: 'hover'
PropertyChanges { target: hoverContent; visible: true }
PropertyChanges {
target: hoverContent
visible: true
}
}
}
}

View file

@ -20,33 +20,34 @@ FormItemLayout {
property bool canBeEmpty: true
property bool toValidate: false
property alias text: textField.text
property var value: propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName]
function value() {
return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName]
return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName];
}
property alias hidden: textField.hidden
property alias hidden: textField.hidden
property alias validator: textField.validator
property alias customButtonIcon: textField.customButtonIcon
property alias customCallback: textField.customCallback
property alias customButtonAccessibleName: textField.customButtonAccessibleName
property alias customCallback: textField.customCallback
property alias customButtonAccessibleName: textField.customButtonAccessibleName
property var isValid: function(text) {
return true
}
function empty() {
textField.text = ""
property var isValid: function (text) {
return true;
}
function empty() {
textField.text = "";
}
contentItem: TextField {
id: textField
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder
initialText: (mainItem.propertyOwnerGui ? mainItem.propertyOwnerGui.core[mainItem.propertyName] : mainItem.propertyOwner[mainItem.propertyName]) || ''
initialText: (mainItem.propertyOwnerGui ? mainItem.propertyOwnerGui.core[mainItem.propertyName] :
mainItem.propertyOwner[mainItem.propertyName]) || ''
customWidth: mainItem.parent.width
propertyName: mainItem.propertyName
propertyOwner: mainItem.propertyOwner
@ -54,18 +55,18 @@ FormItemLayout {
canBeEmpty: mainItem.canBeEmpty
isValid: mainItem.isValid
toValidate: mainItem.toValidate
onValidationChecked: (isValid) => {
if (isValid) return
if (!canBeEmpty && empty) {
//: "ne peut être vide"
mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty")
} else {
//: "Format non reconnu"
mainItem.errorMessage = qsTr("textfield_error_message_unknown_format")
}
}
onValidationChecked: isValid => {
if (isValid)
return;
if (!canBeEmpty && empty) {
//: "ne peut être vide"
mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty");
} else {
//: "Format non reconnu"
mainItem.errorMessage = qsTr("textfield_error_message_unknown_format");
}
}
onTextChanged: mainItem.clearErrorText()
Accessible.name: mainItem.title
}
}

View file

@ -5,10 +5,13 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TextField {
id: mainItem
property real inputSize: Utils.getSizeWithScreenRatio(100)
property real inputSize: Utils.getSizeWithScreenRatio(100)
property bool isError: false
color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
validator: IntValidator{bottom: 0; top: 9}
validator: IntValidator {
bottom: 0
top: 9
}
width: inputSize * 0.9
height: inputSize
@ -21,12 +24,12 @@ Control.TextField {
placeholderTextColor: "transparent"
// cursorVisible is overwritten on focus change so useless to hide the cursor
cursorDelegate: Item{}
cursorDelegate: Item {}
// horizontalAlignment: Control.TextField.AlignHCenter
font.family: DefaultStyle.defaultFont
font.pixelSize: inputSize / 2
font.weight: Utils.getSizeWithScreenRatio(300)
font.weight: Utils.getSizeWithScreenRatio(300)
background: Item {
anchors.fill: parent
@ -34,12 +37,9 @@ Control.TextField {
// height: mainItem.inputSize
Rectangle {
id: background
border.width: Utils.getSizeWithScreenRatio(1)
border.color: mainItem.isError
? DefaultStyle.danger_500_main
: mainItem.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.main2_500_main
border.width: Utils.getSizeWithScreenRatio(1)
border.color: mainItem.isError ? DefaultStyle.danger_500_main : mainItem.activeFocus ? DefaultStyle.main1_500_main :
DefaultStyle.main2_500_main
radius: mainItem.inputSize * 0.15
width: mainItem.inputSize * 0.9
height: mainItem.inputSize
@ -48,11 +48,11 @@ Control.TextField {
id: indicator
visible: mainItem.activeFocus
color: DefaultStyle.main1_500_main
height : Utils.getSizeWithScreenRatio(1)
height: Utils.getSizeWithScreenRatio(1)
width: mainItem.inputSize * 0.67
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Utils.getSizeWithScreenRatio(mainItem.inputSize / 8)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(mainItem.inputSize / 8)
}
}
}

View file

@ -4,7 +4,7 @@ import QtQuick.Layouts as Layout
import QtQuick.Effects
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope {
@ -15,19 +15,21 @@ FocusScope {
property var currentCall
property bool lastRowVisible: true
onButtonPressed: (text) => {
if (currentCall) currentCall.core.lSendDtmf(text)
else UtilsCpp.playDtmf(text)
}
onButtonPressed: text => {
if (currentCall)
currentCall.core.lSendDtmf(text);
else
UtilsCpp.playDtmf(text);
}
signal buttonPressed(string text)
signal launchCall()
signal wipe()
signal launchCall
signal wipe
function keypadKeyPressedAtIndex(index) {
var button = numPadGrid.getButtonAt(index)
button.shadowEnabled = true
button.clicked()
removeButtonsShadow.restart()
var button = numPadGrid.getButtonAt(index);
button.shadowEnabled = true;
button.clicked();
removeButtonsShadow.restart();
}
Timer {
@ -36,93 +38,93 @@ FocusScope {
repeat: false
onTriggered: {
for (var i = 0; i < 12; i++) {
numPadGrid.getButtonAt(i).shadowEnabled = false
numPadGrid.getButtonAt(i).shadowEnabled = false;
}
}
}
function handleKeyPadEvent(event) {
if (event.key === Qt.Key_0) {
keypadKeyPressedAtIndex(10)
event.accepted = true
keypadKeyPressedAtIndex(10);
event.accepted = true;
}
if (event.key === Qt.Key_1) {
keypadKeyPressedAtIndex(0)
event.accepted = true
keypadKeyPressedAtIndex(0);
event.accepted = true;
}
if (event.key === Qt.Key_2) {
keypadKeyPressedAtIndex(1)
event.accepted = true
keypadKeyPressedAtIndex(1);
event.accepted = true;
}
if (event.key === Qt.Key_3) {
keypadKeyPressedAtIndex(2)
event.accepted = true
keypadKeyPressedAtIndex(2);
event.accepted = true;
}
if (event.key === Qt.Key_4) {
keypadKeyPressedAtIndex(3)
event.accepted = true
keypadKeyPressedAtIndex(3);
event.accepted = true;
}
if (event.key === Qt.Key_5) {
keypadKeyPressedAtIndex(4)
event.accepted = true
keypadKeyPressedAtIndex(4);
event.accepted = true;
}
if (event.key === Qt.Key_6) {
keypadKeyPressedAtIndex(5)
event.accepted = true
keypadKeyPressedAtIndex(5);
event.accepted = true;
}
if (event.key === Qt.Key_7) {
keypadKeyPressedAtIndex(6)
event.accepted = true
keypadKeyPressedAtIndex(6);
event.accepted = true;
}
if (event.key === Qt.Key_8) {
keypadKeyPressedAtIndex(7)
event.accepted = true
keypadKeyPressedAtIndex(7);
event.accepted = true;
}
if (event.key === Qt.Key_9) {
keypadKeyPressedAtIndex(8)
event.accepted = true
keypadKeyPressedAtIndex(8);
event.accepted = true;
}
if (event.key === Qt.Key_Asterisk) {
keypadKeyPressedAtIndex(9)
event.accepted = true
keypadKeyPressedAtIndex(9);
event.accepted = true;
}
if (event.key === Qt.Key_Plus) {
mainItem.buttonPressed("+")
event.accepted = true
mainItem.buttonPressed("+");
event.accepted = true;
}
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.launchCall()
event.accepted = true
mainItem.launchCall();
event.accepted = true;
}
}
Keys.onPressed: (event) => {
event.accepted = false
if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) {
handleKeyPadEvent(event)
}
if (event.key === Qt.Key_Backspace) {
mainItem.wipe()
event.accepted = true
}
}
Keys.onPressed: event => {
event.accepted = false;
if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) {
handleKeyPadEvent(event);
}
if (event.key === Qt.Key_Backspace) {
mainItem.wipe();
event.accepted = true;
}
}
Layout.GridLayout {
id: numPadGrid
columns: 3
columnSpacing: Utils.getSizeWithScreenRatio(40)
rowSpacing: Utils.getSizeWithScreenRatio(10)
function getButtonAt(index){
index = (index+15) % 15
if(index >= 0){
if( index < 9){
return numPadRepeater.itemAt(index)
}else if( index < 12){
return digitRepeater.itemAt(index-9)
}else if (index < 14){
return launchCallButton
}else if( index < 15){
return eraseButton
columnSpacing: Utils.getSizeWithScreenRatio(40)
rowSpacing: Utils.getSizeWithScreenRatio(10)
function getButtonAt(index) {
index = (index + 15) % 15;
if (index >= 0) {
if (index < 9) {
return numPadRepeater.itemAt(index);
} else if (index < 12) {
return digitRepeater.itemAt(index - 9);
} else if (index < 14) {
return launchCallButton;
} else if (index < 15) {
return eraseButton;
}
}
}
@ -133,47 +135,55 @@ FocusScope {
id: numPadButton
Layout.Layout.alignment: Qt.AlignHCenter
required property int index
implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60)
implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60)
onClicked: {
mainItem.buttonPressed(text)
mainItem.buttonPressed(text);
}
KeyNavigation.left: numPadGrid.getButtonAt(index - 1)
KeyNavigation.right: numPadGrid.getButtonAt(index + 1)
KeyNavigation.up: numPadGrid.getButtonAt(index - 3)
KeyNavigation.down: numPadGrid.getButtonAt(index + 3)
style: ButtonStyle.numericPad
radius: Utils.getSizeWithScreenRatio(71)
radius: Utils.getSizeWithScreenRatio(71)
text: index + 1
textSize: Utils.getSizeWithScreenRatio(32)
textWeight: Utils.getSizeWithScreenRatio(400)
textSize: Utils.getSizeWithScreenRatio(32)
textWeight: Utils.getSizeWithScreenRatio(400)
}
}
Repeater {
id: digitRepeater
model: [
{pressText: "*"},
{pressText: "0", longPressText: "+"},
{pressText: "#"}
{
pressText: "*"
},
{
pressText: "0",
longPressText: "+"
},
{
pressText: "#"
}
]
BigButton {
id: digitButton
Layout.Layout.alignment: Qt.AlignHCenter
implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60)
implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60)
onClicked: mainItem.buttonPressed(pressText.text)
onPressAndHold: mainItem.buttonPressed(longPressText.text)
KeyNavigation.left: numPadGrid.getButtonAt((index - 1)+9)
KeyNavigation.right: numPadGrid.getButtonAt((index + 1)+9)
KeyNavigation.up: numPadGrid.getButtonAt((index - 3)+9)
KeyNavigation.down: numPadGrid.getButtonAt((index + 3)+9)
radius: Utils.getSizeWithScreenRatio(71)
KeyNavigation.left: numPadGrid.getButtonAt((index - 1) + 9)
KeyNavigation.right: numPadGrid.getButtonAt((index + 1) + 9)
KeyNavigation.up: numPadGrid.getButtonAt((index - 3) + 9)
KeyNavigation.down: numPadGrid.getButtonAt((index + 3) + 9)
radius: Utils.getSizeWithScreenRatio(71)
style: ButtonStyle.numericPad
//: %1 longpress %2
Accessible.name: longPressText.text ? qsTr("numpad_longpress_accessible_name").arg(pressText.text).arg(longPressText.text) : pressText.text
Accessible.name: longPressText.text ? qsTr("numpad_longpress_accessible_name").arg(pressText.text).arg(
longPressText.text) : pressText.text
contentItem: Item {
anchors.fill: parent
@ -184,9 +194,12 @@ FocusScope {
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
Component.onCompleted: {if (modelData.longPressText === undefined) anchors.centerIn= parent}
Component.onCompleted: {
if (modelData.longPressText === undefined)
anchors.centerIn = parent;
}
text: modelData.pressText
font.pixelSize: Utils.getSizeWithScreenRatio(32)
font.pixelSize: Utils.getSizeWithScreenRatio(32)
}
Text {
id: longPressText
@ -194,11 +207,11 @@ FocusScope {
anchors.left: parent.left
anchors.right: parent.right
color: digitButton.pressed ? digitButton.pressedTextColor : digitButton.textColor
y: digitButton.height/2
y: digitButton.height / 2
horizontalAlignment: Text.AlignHCenter
visible: modelData.longPressText ? modelData.longPressText.length > 0 : false
text: modelData.longPressText ? modelData.longPressText : ""
font.pixelSize: Utils.getSizeWithScreenRatio(22)
font.pixelSize: Utils.getSizeWithScreenRatio(22)
}
}
}
@ -210,19 +223,19 @@ FocusScope {
Button {
id: launchCallButton
visible: mainItem.lastRowVisible
implicitWidth: Utils.getSizeWithScreenRatio(75)
implicitHeight: Utils.getSizeWithScreenRatio(55)
implicitWidth: Utils.getSizeWithScreenRatio(75)
implicitHeight: Utils.getSizeWithScreenRatio(55)
Layout.Layout.alignment: Qt.AlignHCenter
icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Utils.getSizeWithScreenRatio(32)
radius: Utils.getSizeWithScreenRatio(71)
icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Utils.getSizeWithScreenRatio(32)
radius: Utils.getSizeWithScreenRatio(71)
style: ButtonStyle.phoneGreen
//: Call
//: Call
Accessible.name: qsTr("call_accessible_name")
onClicked: mainItem.launchCall()
KeyNavigation.left: eraseButton
KeyNavigation.right: eraseButton
KeyNavigation.up: numPadGrid.getButtonAt(10)
@ -231,35 +244,35 @@ FocusScope {
Button {
id: eraseButton
visible: mainItem.lastRowVisible
leftPadding: Utils.getSizeWithScreenRatio(5)
rightPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
leftPadding: Utils.getSizeWithScreenRatio(5)
rightPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
Layout.Layout.alignment: Qt.AlignHCenter
icon.source: AppIcons.backspaceFill
style: ButtonStyle.noBackground
icon.width: Utils.getSizeWithScreenRatio(38)
icon.height: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredHeight: Utils.getSizeWithScreenRatio(38)
icon.width: Utils.getSizeWithScreenRatio(38)
icon.height: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredHeight: Utils.getSizeWithScreenRatio(38)
//: Erase
Accessible.name: qsTr("erase_accessible_name")
onClicked: mainItem.wipe()
KeyNavigation.left: launchCallButton
KeyNavigation.right: launchCallButton
KeyNavigation.up: numPadGrid.getButtonAt(11)
KeyNavigation.down: numPadGrid.getButtonAt(1)
background: Rectangle {
width: eraseButton.width
height: eraseButton.height
color: "transparent"
color: "transparent"
border.color: eraseButton.keyboardFocus ? eraseButton.keyboardFocusedBorderColor : "transparent"
border.width: eraseButton.keyboardFocus ? eraseButton.keyboardFocusedBorderWidth : eraseButton.borderWidth
border.width: eraseButton.keyboardFocus ? eraseButton.keyboardFocusedBorderWidth : eraseButton.borderWidth
}
}
}

View file

@ -10,10 +10,10 @@ ColumnLayout {
property string label: ""
property alias errorMessage: errorText.text
property string placeholderText : ""
property string placeholderText: ""
property bool mandatory: false
property bool enableErrorText: true
property real textInputWidth: width
property real textInputWidth: width
property string initialPhoneNumber
readonly property string phoneNumber: textField.text
readonly property string countryCode: combobox.text
@ -31,8 +31,8 @@ ColumnLayout {
text: mainItem.label + (mainItem.mandatory ? "*" : "")
color: (combobox.activeFocus || textField.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
}
}
@ -42,14 +42,11 @@ ColumnLayout {
background: Rectangle {
id: contentBackground
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63)
radius: Utils.getSizeWithScreenRatio(63)
color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: (textField.activeFocus || combobox.activeFocus)
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
border.width: mainItem.borderWidth
border.color: mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : (textField.activeFocus
|| combobox.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.grey_200
border.width: mainItem.borderWidth
}
contentItem: RowLayout {
CountryIndicatorCombobox {
@ -74,13 +71,15 @@ ColumnLayout {
placeholderText: mainItem.placeholderText
background: Rectangle {
visible: textField.keyboardFocus
radius: Utils.getSizeWithScreenRatio(63)
radius: Utils.getSizeWithScreenRatio(63)
color: "transparent"
border.color: mainItem.keyboardFocusedBorderColor
border.width: mainItem.keyboardFocusedBorderWidth
border.width: mainItem.keyboardFocusedBorderWidth
}
initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
validator: RegularExpressionValidator {
regularExpression: /[0-9]+/
}
//: %1 number
Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name)
}

View file

@ -3,20 +3,20 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope {
id: mainItem
property bool magnifierVisible: true
property var validator: RegularExpressionValidator{}
property var validator: RegularExpressionValidator {}
property var numericPadPopup
property alias numericPadButton: dialerButton
readonly property bool hasActiveFocus: textField.activeFocus
property alias color: backgroundItem.color
property bool delaySearch: true // Wait some idle time after typing to start searching
property bool handleNumericPadPopupButtonsPressed: true
// Border properties
// Border properties
property color borderColor: "transparent"
property color focusedBorderColor: DefaultStyle.main2_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
@ -24,35 +24,37 @@ FocusScope {
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Text properties
property string placeholderText: ""
property color placeholderTextColor: DefaultStyle.main2_400
property real textInputWidth: Utils.getSizeWithScreenRatio(350)
property color placeholderTextColor: DefaultStyle.main2_400
property real textInputWidth: Utils.getSizeWithScreenRatio(350)
property string text: textField.searchText
signal openNumericPadRequested()// Useful for redirection before displaying numeric pad.
signal openNumericPadRequested// Useful for redirection before displaying numeric pad.
function clearText() {
textField.text = ""
textField.text = "";
}
Connections {
enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed
target: numericPadPopup ? numericPadPopup : null
function onButtonPressed(text) {
textField.text += text
textField.text += text;
}
function onWipe() {
textField.text = textField.text.slice(0, -1);
}
function onWipe(){ textField.text = textField.text.slice(0, -1)}
}
implicitWidth: mainItem.textInputWidth
implicitHeight: Utils.getSizeWithScreenRatio(50)
Rectangle{
implicitHeight: Utils.getSizeWithScreenRatio(50)
Rectangle {
id: backgroundItem
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(28)
radius: Utils.getSizeWithScreenRatio(28)
color: DefaultStyle.grey_100
border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor
border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus
? mainItem.focusedBorderColor : mainItem.borderColor
border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
EffectImage {
@ -61,19 +63,19 @@ FocusScope {
colorizationColor: DefaultStyle.main2_500_main
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
imageSource: AppIcons.magnifier
width: Utils.getSizeWithScreenRatio(20)
height: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(20)
height: Utils.getSizeWithScreenRatio(20)
}
Control.TextField {
id: textField
anchors.left: magnifier.visible ? magnifier.right : parent.left
anchors.leftMargin: magnifier.visible ? 0 : Utils.getSizeWithScreenRatio(10)
anchors.leftMargin: magnifier.visible ? 0 : Utils.getSizeWithScreenRatio(10)
anchors.right: clearTextButton.left
anchors.verticalCenter: parent.verticalCenter
property bool keyboardFocus: FocusHelper.keyboardFocus
property string searchText
focus: true
@ -82,8 +84,8 @@ FocusScope {
width: mainItem.width - dialerButton.width
echoMode: (mainItem.hidden && !dialerButton.checked) ? TextInput.Password : TextInput.Normal
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
family: DefaultStyle.defaultFont
}
color: DefaultStyle.main2_600
@ -96,21 +98,22 @@ FocusScope {
cursorDelegate: Rectangle {
visible: textField.cursorVisible
color: DefaultStyle.main2_500_main
width: Utils.getSizeWithScreenRatio(1)
width: Utils.getSizeWithScreenRatio(1)
}
Timer{
Timer {
id: delayTimer
interval: 300
repeat: false
onTriggered: textField.searchText = textField.text
}
Keys.onPressed: (event) => {
event.accepted = false
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return)) {
mainItem.numericPadPopup.keyPadKeyPressed(event)
event.accepted = true
}
}
Keys.onPressed: event => {
event.accepted = false;
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier
|| event.key === Qt.Key_Return)) {
mainItem.numericPadPopup.keyPadKeyPressed(event);
event.accepted = true;
}
}
}
Button {
id: dialerButton
@ -118,39 +121,40 @@ FocusScope {
checked: numericPadPopup?.visible || false
style: ButtonStyle.noBackground
icon.source: AppIcons.dialer
contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
hoveredImageColor: contentImageColor
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
//: "Open dialer"
Accessible.name: qsTr("open_dialer_acccessibility_label")
onClicked: {
if(!checked){
mainItem.openNumericPadRequested()
mainItem.numericPadPopup.open()
} else mainItem.numericPadPopup.close()
if (!checked) {
mainItem.openNumericPadRequested();
mainItem.numericPadPopup.open();
} else
mainItem.numericPadPopup.close();
}
}
Button {
id: clearTextButton
visible: textField.text.length > 0 && mainItem.enabled
width: Utils.getSizeWithScreenRatio(24)
height: Utils.getSizeWithScreenRatio(24)
width: Utils.getSizeWithScreenRatio(24)
height: Utils.getSizeWithScreenRatio(24)
style: ButtonStyle.noBackground
icon.source: AppIcons.closeX
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
//: "Clear text input"
Accessible.name: qsTr("clear_text_input_acccessibility_label")
onClicked: {
textField.clear()
textField.clear();
}
}
}

View file

@ -7,33 +7,32 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
TextEdit {
id: mainItem
property string placeholderText
property real placeholderPixelSize: Typography.p1.pixelSize
property real placeholderWeight: Typography.p1.weight
property real placeholderPixelSize: Typography.p1.pixelSize
property real placeholderWeight: Typography.p1.weight
property color placeholderTextColor: color
property alias background: background.data
property bool hoverEnabled: true
property bool hovered: mouseArea.hoverEnabled && mouseArea.containsMouse
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5)
activeFocusOnTab: true
KeyNavigation.priority: KeyNavigation.BeforeItem
KeyNavigation.priority: KeyNavigation.BeforeItem
property bool displayAsRichText: false
property var encodeTextObj: UtilsCpp.encodeTextToQmlRichFormat(text)
property string richFormatText: encodeTextObj && encodeTextObj.value || ""
property color textAreaColor
Component.onCompleted: {
mainItem.textAreaColor = mainItem.color // backup original color
mainItem.textAreaColor = mainItem.color; // backup original color
if (displayAsRichText)
mainItem.color = 'transparent'
mainItem.color = 'transparent';
}
onTextChanged: {
encodeTextObj = UtilsCpp.encodeTextToQmlRichFormat(text)
encodeTextObj = UtilsCpp.encodeTextToQmlRichFormat(text);
}
MouseArea {
@ -62,7 +61,7 @@ TextEdit {
weight: mainItem.placeholderWeight
}
}
Text {
Text {
id: formattedText
visible: mainItem.displayAsRichText && mainItem.richFormatText !== ""
text: mainItem.richFormatText
@ -75,13 +74,13 @@ TextEdit {
anchors.fill: parent
focus: false
onHoveredLinkChanged: {
mainItem.hovered = mainItem.displayAsRichText && hoveredLink !== ""
mainItem.hovered = mainItem.displayAsRichText && hoveredLink !== "";
}
onLinkActivated: {
if (link.startsWith('sip'))
UtilsCpp.createCall(link)
UtilsCpp.createCall(link);
else
Qt.openUrlExternally(link)
Qt.openUrlExternally(link);
}
}
}
}

View file

@ -3,232 +3,230 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.TextField {
id: mainItem
property var customWidth
width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360)
height: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible
? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin
: Utils.getSizeWithScreenRatio(15)
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
id: mainItem
property var customWidth
width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360)
height: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin :
Utils.getSizeWithScreenRatio(15)
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
// Workaround for Windows slowness when first typing a password
// due to Qt not initializing the Password echo mode before the first letter is typed
Component.onCompleted: {
text = "workaround"
resetText()
}
// Workaround for Windows slowness when first typing a password
// due to Qt not initializing the Password echo mode before the first letter is typed
Component.onCompleted: {
text = "workaround";
resetText();
}
verticalAlignment: TextInput.AlignVCenter
color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
placeholderTextColor: DefaultStyle.placeholders
font {
family: DefaultStyle.defaultFont
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
selectByMouse: true
activeFocusOnTab: true
KeyNavigation.right: eyeButton
text: initialText
verticalAlignment: TextInput.AlignVCenter
color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
placeholderTextColor: DefaultStyle.placeholders
font {
family: DefaultStyle.defaultFont
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
selectByMouse: true
activeFocusOnTab: true
KeyNavigation.right: eyeButton
text: initialText
property bool controlIsDown: false
property bool hidden: false
property bool isError: false
property bool controlIsDown: false
property bool hidden: false
property bool isError: false
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
property bool backgroundVisible: true
property color backgroundColor: DefaultStyle.grey_100
property color disabledBackgroundColor: DefaultStyle.grey_200
// Border properties
property color backgroundBorderColor: DefaultStyle.grey_200
property color activeBorderColor: DefaultStyle.main1_500_main
// Background properties
property bool backgroundVisible: true
property color backgroundColor: DefaultStyle.grey_100
property color disabledBackgroundColor: DefaultStyle.grey_200
// Border properties
property color backgroundBorderColor: DefaultStyle.grey_200
property color activeBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property color errorBorderColor: DefaultStyle.danger_500_main
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Text properties
property string initialText
property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight
// Text properties
property string initialText
property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight
// Custom button on the right
property string customButtonIcon
property var customCallback
property string customButtonAccessibleName
// Custom button on the right
property string customButtonIcon
property var customCallback
property string customButtonAccessibleName
// fill propertyName and propertyOwner to check text validity
property string propertyName
property var propertyOwner
property var propertyOwnerGui
property var initialReading: true
property var isValid: function (text) {
return true
}
property bool toValidate: false
property int idleTimeOut: 200
property bool empty: propertyOwnerGui
? mainItem.propertyOwnerGui.core != undefined && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0
: mainItem.propertyOwner != undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true
// fill propertyName and propertyOwner to check text validity
property string propertyName
property var propertyOwner
property var propertyOwnerGui
property var initialReading: true
property var isValid: function (text) {
return true;
}
property bool toValidate: false
property int idleTimeOut: 200
property bool empty: propertyOwnerGui ? mainItem.propertyOwnerGui.core != undefined
&& mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 : mainItem.propertyOwner != undefined
&& mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true
signal validationChecked(bool valid)
signal validationChecked(bool valid)
function resetText() {
text = initialText
}
function resetText() {
text = initialText;
}
signal enterPressed
signal enterPressed
onAccepted: {
// No need to process changing focus because of TextEdited callback.
idleTimer.stop()
updateText()
}
onTextChanged: {
if (mainItem.toValidate) {
idleTimer.restart()
}
}
function updateText() {
mainItem.empty = text.length == 0
if (initialReading) {
initialReading = false
}
if (mainItem.empty && !mainItem.canBeEmpty) {
mainItem.validationChecked(false)
return
}
if (mainItem.propertyName && isValid(text)) {
if (mainItem.propertyOwnerGui) {
if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) {
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text
}
} else {
if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text
}
mainItem.validationChecked(true)
} else
mainItem.validationChecked(false)
}
// Validation textfield functions
Timer {
id: idleTimer
running: false
interval: mainItem.idleTimeOut
repeat: false
onTriggered: {
mainItem.accepted()
}
}
onAccepted: {
// No need to process changing focus because of TextEdited callback.
idleTimer.stop();
updateText();
}
onTextChanged: {
if (mainItem.toValidate) {
idleTimer.restart();
}
}
function updateText() {
mainItem.empty = text.length == 0;
if (initialReading) {
initialReading = false;
}
if (mainItem.empty && !mainItem.canBeEmpty) {
mainItem.validationChecked(false);
return;
}
if (mainItem.propertyName && isValid(text)) {
if (mainItem.propertyOwnerGui) {
if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) {
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text;
}
} else {
if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text;
}
mainItem.validationChecked(true);
} else
mainItem.validationChecked(false);
}
// Validation textfield functions
Timer {
id: idleTimer
running: false
interval: mainItem.idleTimeOut
repeat: false
onTriggered: {
mainItem.accepted();
}
}
background: Rectangle {
id: inputBackground
visible: mainItem.backgroundVisible
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(79)
color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor
border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor : mainItem.backgroundBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
background: Rectangle {
id: inputBackground
visible: mainItem.backgroundVisible
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(79)
color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor
border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor :
mainItem.backgroundBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
cursorDelegate: Rectangle {
id: cursor
color: DefaultStyle.main1_500_main
width: Utils.getSizeWithScreenRatio(1)
anchors.verticalCenter: mainItem.verticalCenter
cursorDelegate: Rectangle {
id: cursor
color: DefaultStyle.main1_500_main
width: Utils.getSizeWithScreenRatio(1)
anchors.verticalCenter: mainItem.verticalCenter
SequentialAnimation {
loops: Animation.Infinite
running: mainItem.cursorVisible
SequentialAnimation {
loops: Animation.Infinite
running: mainItem.cursorVisible
PropertyAction {
target: cursor
property: 'visible'
value: true
}
PropertyAction {
target: cursor
property: 'visible'
value: true
}
PauseAnimation {
duration: 600
}
PauseAnimation {
duration: 600
}
PropertyAction {
target: cursor
property: 'visible'
value: false
}
PropertyAction {
target: cursor
property: 'visible'
value: false
}
PauseAnimation {
duration: 600
}
PauseAnimation {
duration: 600
}
onStopped: {
cursor.visible = false
}
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Control)
mainItem.controlIsDown = true
if (event.key === Qt.Key_Enter
|| event.key === Qt.Key_Return) {
enterPressed()
if (mainItem.controlIsDown) {
onStopped: {
cursor.visible = false;
}
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Control)
mainItem.controlIsDown = true;
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
enterPressed();
if (mainItem.controlIsDown) {}
}
}
Keys.onReleased: event => {
if (event.jey == Qt.Key_Control)
mainItem.controlIsDown = false;
}
}
}
}
Keys.onReleased: event => {
if (event.jey == Qt.Key_Control)
mainItem.controlIsDown = false
}
Button {
id: eyeButton
KeyNavigation.left: mainItem
property real rightMargin: Utils.getSizeWithScreenRatio(15)
z: 1
visible: mainItem.hidden
checkable: true
style: ButtonStyle.noBackground
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide
width: Utils.getSizeWithScreenRatio(20)
height: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: rightMargin
Button {
id: eyeButton
KeyNavigation.left: mainItem
property real rightMargin: Utils.getSizeWithScreenRatio(15)
z: 1
visible: mainItem.hidden
checkable: true
style: ButtonStyle.noBackground
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide
width: Utils.getSizeWithScreenRatio(20)
height: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: rightMargin
Accessible.name: (eyeButton.checked ?
//: Hide %1
qsTr("hide_accessible_name") :
//: Show %1
qsTr("show_accessible_name")
).arg(mainItem.Accessible.name)
}
Button {
id: customButton
KeyNavigation.left: mainItem
z: 1
visible: mainItem.customButtonIcon !== undefined && mainItem.customButtonIcon !== ""
style: ButtonStyle.noBackground
icon.source: mainItem.customButtonIcon
width: visible ? Utils.getSizeWithScreenRatio(20) : 0
height: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
onClicked: mainItem.customCallback()
//: %1 button of %2
Accessible.name: qsTr("textfield_custom_button_accessible_name").arg(mainItem.customButtonAccessibleName).arg(mainItem.Accessible.name)
}
Accessible.name: (eyeButton.checked ?
//: Hide %1
qsTr("hide_accessible_name") :
//: Show %1
qsTr("show_accessible_name")).arg(mainItem.Accessible.name)
}
Button {
id: customButton
KeyNavigation.left: mainItem
z: 1
visible: mainItem.customButtonIcon !== undefined && mainItem.customButtonIcon !== ""
style: ButtonStyle.noBackground
icon.source: mainItem.customButtonIcon
width: visible ? Utils.getSizeWithScreenRatio(20) : 0
height: Utils.getSizeWithScreenRatio(20)
icon.width: width
icon.height: height
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
onClicked: mainItem.customCallback()
//: %1 button of %2
Accessible.name: qsTr("textfield_custom_button_accessible_name").arg(mainItem.customButtonAccessibleName).arg(
mainItem.Accessible.name)
}
}

View file

@ -10,33 +10,33 @@ ComboBox {
onSelectedDateTimeChanged: {
if (minTime != undefined) {
if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0)
selectedDateTime = minTime
selectedDateTime = minTime;
}
if (maxTime != undefined) {
if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0)
selectedDateTime = maxTime
selectedDateTime = maxTime;
}
}
readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm")
property int selectedHour: input.hour*1
property int selectedMin: input.min*1
property int selectedHour: input.hour * 1
property int selectedMin: input.min * 1
property alias contentText: input
property var minTime
property var maxTime
popup.width: Utils.getSizeWithScreenRatio(73)
popup.width: Utils.getSizeWithScreenRatio(73)
listView.model: 48
listView.height: Math.min(Utils.getSizeWithScreenRatio(204), listView.contentHeight)
popup.height: Math.min(Utils.getSizeWithScreenRatio(204), listView.contentHeight)
listView.height: Math.min(Utils.getSizeWithScreenRatio(204), listView.contentHeight)
popup.height: Math.min(Utils.getSizeWithScreenRatio(204), listView.contentHeight)
editable: true
popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside
onCurrentTextChanged: input.text = currentText
popup.onOpened: {
input.forceActiveFocus()
input.forceActiveFocus();
}
contentItem: TextInput {
id: input
validator: IntValidator{}
validator: IntValidator {}
// activeFocusOnPress: false
inputMask: "00:00"
verticalAlignment: TextInput.AlignVCenter
@ -46,41 +46,41 @@ ComboBox {
color: DefaultStyle.main2_600
onActiveFocusChanged: {
if (activeFocus) {
selectAll()
selectAll();
} else {
listView.currentIndex = -1
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
listView.currentIndex = -1;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
}
}
font {
pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight
pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight
}
text: mainItem.selectedTimeString
Keys.onPressed: (event) => {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
focus = false
}
}
Keys.onPressed: event => {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
focus = false;
}
}
onFocusChanged: if (!focus) {
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
console.log("set time", hour, min)
}
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
console.log("set time", hour, min);
}
}
listView.delegate: Text {
id: hourDelegate
property int hour: modelData /2
property int min: modelData%2 === 0 ? 0 : 30
property int hour: modelData / 2
property int min: modelData % 2 === 0 ? 0 : 30
property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min)
text: Qt.formatDateTime(currentDateTime, "hh:mm")
width: mainItem.width
visible: mainItem.minTime == undefined || UtilsCpp.timeOffset(mainItem.minTime, currentDateTime) > 0
height: visible ? Utils.getSizeWithScreenRatio(25) : 0
height: visible ? Utils.getSizeWithScreenRatio(25) : 0
verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
MouseArea {
anchors.fill: parent
@ -88,9 +88,9 @@ ComboBox {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
// mainItem.text = parent.text
mainItem.listView.currentIndex = index
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min)
mainItem.popup.close()
mainItem.listView.currentIndex = index;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
mainItem.popup.close();
}
Rectangle {
visible: parent.containsMouse

View file

@ -6,84 +6,84 @@ import QtQuick.Layouts
import Qt.labs.platform
Window {
id: mainItem
id: mainItem
// ---------------------------------------------------------------------------
color: "transparent"
property bool requestActivate: false
//property int flags: Qt.SplashScreen
default property alias _content: content.data
property bool _isOpen: false
signal isOpened()
signal isClosed()
signal dataChanged()
signal isOpened
signal isClosed
signal dataChanged
on_ContentChanged: dataChanged(_content)
// ---------------------------------------------------------------------------
function open () {
function open() {
_isOpen = true;
isOpened();
}
/*
function close () {
_isOpen = false
isClosed()
_isOpen = false
isClosed()
}
*/
// ---------------------------------------------------------------------------
objectName: '__internalWindow'
property bool showAsTool : false
property bool showAsTool: false
// Don't use Popup for flags : it could lead to error in geometry. On Mac, Using Tool ensure to have the Window on Top and fullscreen independant
// flags: Qt.WindowDoesNotAcceptFocus | Qt.BypassWindowManagerHint | (showAsTool?Qt.Tool:Qt.WindowStaysOnTopHint) | Qt.Window | Qt.FramelessWindowHint;
flags: Qt.SplashScreen | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint // | Qt.WindowStaysOnTopHint
flags: Qt.SplashScreen | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint // | Qt.WindowStaysOnTopHint
opacity: 1.0
height: _content[0] != null ? _content[0].height : 0
width: _content[0] != null ? _content[0].width : 0
visible:true
visible: true
Item {
id: content
anchors.fill:parent
anchors.fill: parent
focus: false
property var $parent: mainItem
}
// ---------------------------------------------------------------------------
/*
states: State {
name: 'opening'
when: _isOpen
// ---------------------------------------------------------------------------
/*
states: State {
name: 'opening'
when: _isOpen
PropertyChanges {
opacity: 1.0
target: window
}
}
PropertyChanges {
opacity: 1.0
target: window
}
}
transitions: [
Transition {
from: ''
to: 'opening'
ScriptAction {
script: {
if (wrapper.requestActivate) {
window.requestActivate()
}
}
}
},
Transition {
from: '*'
to: ''
ScriptAction {
script: window.close()
}
}
]
*/
transitions: [
Transition {
from: ''
to: 'opening'
ScriptAction {
script: {
if (wrapper.requestActivate) {
window.requestActivate()
}
}
}
},
Transition {
from: '*'
to: ''
ScriptAction {
script: window.close()
}
}
]
*/
}

View file

@ -7,84 +7,86 @@ import QtQuick.Dialogs
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Dialog {
id: mainItem
property string identity
property string domain
readonly property string password: passwordEdit.text
property var callback// Define cb(var) function
topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20)
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(637)
topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20)
leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(637)
modal: true
closePolicy: Popup.NoAutoClose
onAccepted: {
if( callback) callback.cb(password)
close()
if (callback)
callback.cb(password);
close();
}
onRejected: close()
Component.onDestruction: if(callback) callback.destroy()
Component.onDestruction: if (callback)
callback.destroy()
content: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(20)
id: contentLayout
Text {
Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
font {
pixelSize: Typography.h3.pixelSize
weight: Typography.h3.weight
}
//: "Authentification requise"
text: qsTr("account_settings_dialog_invalid_password_title")
}
spacing: Utils.getSizeWithScreenRatio(20)
Text {
Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
//: La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte.
text: qsTr("account_settings_dialog_invalid_password_message").arg(mainItem.identity)
font.pixelSize: Utils.getSizeWithScreenRatio(16)
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
font {
pixelSize: Typography.h3.pixelSize
weight: Typography.h3.weight
}
//: "Authentification requise"
text: qsTr("account_settings_dialog_invalid_password_title")
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
//: La connexion a échoué pour le compte %1. Vous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte.
text: qsTr("account_settings_dialog_invalid_password_message").arg(mainItem.identity)
font.pixelSize: Utils.getSizeWithScreenRatio(16)
font {
pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight
}
}
FormItemLayout {
id: passwordItem
Layout.fillWidth: true
label: qsTr("password")
enableErrorText: true
mandatory: true
contentItem: TextField {
id: passwordEdit
hidden: true
width: parent.width
isError: passwordItem.errorTextVisible
KeyNavigation.down: cancelButton
}
}
FormItemLayout {
id: passwordItem
Layout.fillWidth: true
label: qsTr("password")
enableErrorText: true
mandatory: true
contentItem: TextField {
id: passwordEdit
hidden: true
width: parent.width
isError: passwordItem.errorTextVisible
KeyNavigation.down: cancelButton
}
}
}
buttons: [
MediumButton {
id: cancelButton
Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: "Annuler
text: qsTr("cancel")
Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: "Annuler
text: qsTr("cancel")
style: ButtonStyle.secondary
onClicked: mainItem.rejected()
KeyNavigation.up: passwordEdit
@ -92,20 +94,20 @@ Dialog {
},
MediumButton {
id: connectButton
Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: Connexion
text: qsTr("assistant_account_login")
Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: Connexion
text: qsTr("assistant_account_login")
style: ButtonStyle.main
KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton
onClicked: {
passwordItem.errorMessage = ""
if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password")
return
passwordItem.errorMessage = "";
if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password");
return;
}
mainItem.accepted()
mainItem.accepted();
}
}
]

Some files were not shown because too many files have changed in this diff Show more