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 id: mainItem
textSize: Typography.b1.pixelSize textSize: Typography.b1.pixelSize
textWeight: Typography.b1.weight textWeight: Typography.b1.weight
leftPadding: Utils.getSizeWithScreenRatio(20) leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20) rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(11) topPadding: Utils.getSizeWithScreenRatio(11)
bottomPadding: Utils.getSizeWithScreenRatio(11) bottomPadding: Utils.getSizeWithScreenRatio(11)
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,41 +2,35 @@ import QtQuick
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button { Button {
id: mainItem id: mainItem
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5) radius: Utils.getSizeWithScreenRatio(5)
shadowEnabled: mainItem.activeFocus || hovered shadowEnabled: mainItem.activeFocus || hovered
style: ButtonStyle.hoveredBackground style: ButtonStyle.hoveredBackground
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: mainItem.radius radius: mainItem.radius
color: mainItem.pressed color: mainItem.pressed ? mainItem.pressedColor : mainItem.hovered || mainItem.hasNavigationFocus ? mainItem.hoveredColor :
? mainItem.pressedColor mainItem.color
: mainItem.hovered || mainItem.hasNavigationFocus border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
? mainItem.hoveredColor border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
: mainItem.color }
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
contentItem: EffectImage { contentItem: EffectImage {
imageSource: mainItem.icon.source imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
? mainItem.pressedImageColor mainItem.contentImageColor
: mainItem.hovered Layout.preferredWidth: mainItem.icon.width
? mainItem.hoveredImageColor Layout.preferredHeight: mainItem.icon.height
: 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.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Button { Button {
id: mainItem id: mainItem
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
textSize: Typography.p1.pixelSize textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight textWeight: Typography.p1.weight
radius: Utils.getSizeWithScreenRatio(5) radius: Utils.getSizeWithScreenRatio(5)
shadowEnabled: mainItem.activeFocus || hovered shadowEnabled: mainItem.activeFocus || hovered
style: ButtonStyle.hoveredBackground style: ButtonStyle.hoveredBackground
property bool inverseLayout: false property bool inverseLayout: false
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
contentItem: RowLayout { contentItem: RowLayout {
spacing: mainItem.spacing spacing: mainItem.spacing
layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft: Qt.LeftToRight layoutDirection: mainItem.inverseLayout ? Qt.RightToLeft : Qt.LeftToRight
EffectImage { EffectImage {
imageSource: mainItem.icon.source imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height imageHeight: mainItem.icon.height
colorizationColor: mainItem.pressed colorizationColor: mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor :
? mainItem.pressedImageColor mainItem.contentImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
Layout.preferredWidth: mainItem.icon.width Layout.preferredWidth: mainItem.icon.width
Layout.preferredHeight: mainItem.icon.height Layout.preferredHeight: mainItem.icon.height
} }
@ -41,18 +38,15 @@ Button {
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: mainItem.text text: mainItem.text
maximumLineCount: 1 maximumLineCount: 1
color: pressed color: pressed ? mainItem.pressedTextColor : mainItem.hovered ? mainItem.hoveredTextColor : mainItem.textColor
? mainItem.pressedTextColor
: mainItem.hovered
? mainItem.hoveredTextColor
: mainItem.textColor
font { font {
pixelSize: mainItem.textSize pixelSize: mainItem.textSize
weight: mainItem.textWeight weight: mainItem.textWeight
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization capitalization: mainItem.capitalization
underline: mainItem.underline 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 { TextMetrics {
@ -67,6 +61,8 @@ Button {
bold: true 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.Effects
import QtQuick.Layouts import QtQuick.Layouts
import Linphone 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {

View file

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

View file

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

View file

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

View file

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

View file

@ -2,11 +2,11 @@ import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import Linphone 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 { ComboBox {
id: mainItem id: mainItem
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner
@ -14,16 +14,16 @@ ComboBox {
property alias entries: mainItem.model property alias entries: mainItem.model
oneLine: true oneLine: true
currentIndex: Utils.findIndex(model, function (entry) { currentIndex: Utils.findIndex(model, function (entry) {
if(propertyOwnerGui) if (propertyOwnerGui)
return Utils.equalObject(entry,propertyOwnerGui.core[propertyName]) return Utils.equalObject(entry, propertyOwnerGui.core[propertyName]);
else else
return Utils.equalObject(entry,propertyOwner[propertyName]) return Utils.equalObject(entry, propertyOwner[propertyName]);
}) })
onCurrentValueChanged: { onCurrentValueChanged: {
if(propertyOwnerGui) { if (propertyOwnerGui) {
binding.when = !Utils.equalObject(currentValue,propertyOwnerGui.core[propertyName]) binding.when = !Utils.equalObject(currentValue, propertyOwnerGui.core[propertyName]);
}else{ } else {
binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName]) binding.when = !Utils.equalObject(currentValue, propertyOwner[propertyName]);
} }
} }
Binding { Binding {

View file

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

View file

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

View file

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

View file

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

@ -18,36 +18,41 @@ Mosaic {
margins: 0 margins: 0
// On grid view, we limit the quality if there are enough participants// The vga mode has been activated from the factory rc // 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() //onParticipantCountChanged: participantCount > ConstantsCpp.maxMosaicParticipants ? SettingsModel.setLimitedMosaicQuality() : SettingsModel.setHighMosaicQuality()
delegateModel: DelegateModel{ delegateModel: DelegateModel {
id: gridModel id: gridModel
property ParticipantDeviceProxy participantDevices : ParticipantDeviceProxy { property ParticipantDeviceProxy participantDevices: ParticipantDeviceProxy {
id: allDevices id: allDevices
qmlName: "G" 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] model: grid.call && grid.call.core.isConference ? participantDevices : [0, 1]
delegate: Item{ delegate: Item {
id: avatarCell 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: { 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) height: grid.cellHeight - Utils.getSizeWithScreenRatio(10)
width: grid.cellWidth - Utils.getSizeWithScreenRatio(10) width: grid.cellWidth - Utils.getSizeWithScreenRatio(10)
Sticker { Sticker {
id: cameraView id: cameraView
previewEnabled: index == 0 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 anchors.fill: parent
qmlName: 'G_'+index qmlName: 'G_' + index
call: grid.call && !grid.call.core.isConference ? grid.call : null call: grid.call && !grid.call.core.isConference ? grid.call : null
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress) property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: (index == 0 && accountObj) ? accountObj.value : null account: (index == 0 && accountObj) ? accountObj.value : null
displayAll: false displayAll: false
displayPresence: false displayPresence: false
participantDevice: avatarCell.currentDevice 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 Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
spacing: Utils.getSizeWithScreenRatio(30) spacing: Utils.getSizeWithScreenRatio(30)
property var callHistoryGui property var callHistoryGui
@ -20,12 +20,9 @@ ColumnLayout {
property bool isConference: conferenceInfo != undefined && conferenceInfo != null property bool isConference: conferenceInfo != undefined && conferenceInfo != null
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || "" property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress) property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value: "" property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""
property string contactName: contact property string contactName: contact ? contact.core.fullName : callHistoryGui ? callHistoryGui.core.displayName :
? contact.core.fullName computedContactName
: 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 // for a specific address and not for the entire contact
@ -34,21 +31,21 @@ ColumnLayout {
property alias buttonContent: rightButton.data property alias buttonContent: rightButton.data
property alias detailContent: detailControl.data property alias detailContent: detailControl.data
signal conferenceChatDisplayRequested() signal conferenceChatDisplayRequested
signal conferenceCallHistoryDisplayRequested() signal conferenceCallHistoryDisplayRequested
ColumnLayout { ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(13) spacing: Utils.getSizeWithScreenRatio(13)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Item { Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: detailAvatar.height Layout.preferredHeight: detailAvatar.height
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Avatar { Avatar {
id: detailAvatar id: detailAvatar
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: Utils.getSizeWithScreenRatio(100) width: Utils.getSizeWithScreenRatio(100)
height: Utils.getSizeWithScreenRatio(100) height: Utils.getSizeWithScreenRatio(100)
contact: mainItem.contact || null contact: mainItem.contact || null
isConference: !!mainItem.conferenceInfo isConference: !!mainItem.conferenceInfo
displayNameVal: mainItem.contactName displayNameVal: mainItem.contactName
@ -58,18 +55,18 @@ ColumnLayout {
id: rightButton id: rightButton
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: detailAvatar.verticalCenter anchors.verticalCenter: detailAvatar.verticalCenter
anchors.rightMargin: Utils.getSizeWithScreenRatio(20) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(30) width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30) height: Utils.getSizeWithScreenRatio(30)
} }
} }
ColumnLayout { ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
ColumnLayout { ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2) spacing: Utils.getSizeWithScreenRatio(2)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Text { Text {
Layout.preferredWidth: implicitWidth Layout.preferredWidth: implicitWidth
@ -79,8 +76,8 @@ ColumnLayout {
text: detailAvatar.displayNameVal text: detailAvatar.displayNameVal
maximumLineCount: 1 maximumLineCount: 1
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
} }
Text { Text {
@ -92,8 +89,8 @@ ColumnLayout {
elide: Text.ElideMiddle elide: Text.ElideMiddle
maximumLineCount: 1 maximumLineCount: 1
font { font {
pixelSize: Utils.getSizeWithScreenRatio(12) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
@ -105,8 +102,8 @@ ColumnLayout {
text: contact ? contact.core.presenceStatus : "" text: contact ? contact.core.presenceStatus : ""
color: contact ? contact.core.presenceColor : 'transparent' color: contact ? contact.core.presenceColor : 'transparent'
font { font {
pixelSize: Utils.getSizeWithScreenRatio(12) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
@ -119,9 +116,9 @@ ColumnLayout {
style: ButtonStyle.grey style: ButtonStyle.grey
onClicked: { onClicked: {
if (mainItem.conferenceInfo) { if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo) callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow) UtilsCpp.smartShowWindow(callsWindow);
} }
} }
} }
@ -129,96 +126,103 @@ ColumnLayout {
id: confWithChatLayout id: confWithChatLayout
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature && mainItem.chatGui !== null visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature && mainItem.chatGui !== null
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72) spacing: Utils.getSizeWithScreenRatio(72)
// Layout.fillWidth: true // Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height Layout.preferredHeight: childrenRect.height
LabelButton { LabelButton {
visible: !SettingsCpp.disableChatFeature visible: !SettingsCpp.disableChatFeature
width: Utils.getSizeWithScreenRatio(56) width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoconference button.icon.source: AppIcons.videoconference
//: "Join" //: "Join"
label: qsTr("meeting_info_join_title") label: qsTr("meeting_info_join_title")
button.onClicked: if (mainItem.conferenceInfo) { button.onClicked: if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference(mainItem.conferenceInfo) callsWindow.setupConference(mainItem.conferenceInfo);
UtilsCpp.smartShowWindow(callsWindow) UtilsCpp.smartShowWindow(callsWindow);
} }
} }
LabelButton { LabelButton {
visible: !SettingsCpp.disableChatFeature visible: !SettingsCpp.disableChatFeature
button.checkable: true button.checkable: true
width: Utils.getSizeWithScreenRatio(56) width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked label: button.checked ?
//: "Call history" //: "Call history"
? qsTr("contact_call_history_action") qsTr("contact_call_history_action") :
//: "Conversation" //: "Conversation"
: qsTr("contact_conversation_action") qsTr("contact_conversation_action")
button.onCheckedChanged: { button.onCheckedChanged: {
if (button.checked) mainItem.conferenceChatDisplayRequested() if (button.checked)
else mainItem.conferenceCallHistoryDisplayRequested() mainItem.conferenceChatDisplayRequested();
else
mainItem.conferenceCallHistoryDisplayRequested();
} }
} }
} }
RowLayout { RowLayout {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72) spacing: Utils.getSizeWithScreenRatio(72)
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height Layout.preferredHeight: childrenRect.height
visible: !mainItem.isConference visible: !mainItem.isConference
LabelButton { LabelButton {
width: Utils.getSizeWithScreenRatio(56) width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.phone button.icon.source: AppIcons.phone
//: "Appel" //: "Appel"
label: qsTr("contact_call_action") label: qsTr("contact_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem) if (mainItem.specificAddress === "")
else UtilsCpp.createCall(mainItem.specificAddress) mainWindow.startCallWithContact(mainItem.contact, false, mainItem);
else
UtilsCpp.createCall(mainItem.specificAddress);
} }
} }
LabelButton { LabelButton {
visible: !SettingsCpp.disableChatFeature visible: !SettingsCpp.disableChatFeature
width: Utils.getSizeWithScreenRatio(56) width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.chatTeardropText button.icon.source: AppIcons.chatTeardropText
//: "Message" //: "Message"
label: qsTr("contact_message_action") label: qsTr("contact_message_action")
button.onClicked: { button.onClicked: {
console.debug("[CallHistoryLayout.qml] Open conversation") console.debug("[CallHistoryLayout.qml] Open conversation");
if (mainItem.specificAddress === "") { if (mainItem.specificAddress === "") {
mainWindow.sendMessageToContact(mainItem.contact) mainWindow.sendMessageToContact(mainItem.contact);
} } else {
else { console.log("specific address", mainItem.specificAddress);
console.log("specific address", mainItem.specificAddress) mainWindow.displayChatPage(mainItem.specificAddress);
mainWindow.displayChatPage(mainItem.specificAddress)
} }
} }
} }
LabelButton { LabelButton {
visible: SettingsCpp.videoEnabled visible: SettingsCpp.videoEnabled
width: Utils.getSizeWithScreenRatio(56) width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24) button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24) button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoCamera button.icon.source: AppIcons.videoCamera
//: "Appel Video" //: "Appel Video"
label: qsTr("contact_video_call_action") label: qsTr("contact_video_call_action")
button.onClicked: { button.onClicked: {
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem) if (mainItem.specificAddress === "")
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true}) mainWindow.startCallWithContact(mainItem.contact, true, mainItem);
} else
} UtilsCpp.createCall(mainItem.specificAddress, {
'localVideoEnabled': true
});
}
}
} }
ColumnLayout { ColumnLayout {
id: detailControl id: detailControl
@ -226,6 +230,6 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter 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 CallGui call
property ConferenceGui conference: call && call.core.conference property ConferenceGui conference: call && call.core.conference
property bool callTerminatedByUser: false 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 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 conferenceLayout: call ? call.core.conferenceVideoLayout : LinphoneEnums.ConferenceLayout.ActiveSpeaker
property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1 property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
property int lastConfLayoutBeforeSharing: -1 property int lastConfLayoutBeforeSharing: -1
property string localAddress: call property string localAddress: call ? call.conference ? call.conference.core.me.core.sipAddress :
? call.conference call.core.localAddress : ""
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
onParticipantDeviceCountChanged: { onParticipantDeviceCountChanged: {
setConferenceLayout() setConferenceLayout();
} }
Component.onCompleted: setConferenceLayout() Component.onCompleted: setConferenceLayout()
onConferenceLayoutChanged: { onConferenceLayoutChanged: {
console.log("CallLayout change : " +conferenceLayout) console.log("CallLayout change : " + conferenceLayout);
setConferenceLayout() setConferenceLayout();
} }
Connections { Connections {
target: mainItem.conference? mainItem.conference.core : null target: mainItem.conference ? mainItem.conference.core : null
function onIsScreenSharingEnabledChanged() { function onIsScreenSharingEnabledChanged() {
setConferenceLayout() setConferenceLayout();
} }
function onIsLocalScreenSharingChanged() { function onIsLocalScreenSharingChanged() {
if (mainItem.conference.core.isLocalScreenSharing) { if (mainItem.conference.core.isLocalScreenSharing) {
mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout mainItem.lastConfLayoutBeforeSharing = mainItem.conferenceLayout;
} }
setConferenceLayout() setConferenceLayout();
} }
} }
function 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 stop sharing screen, reset conference layout to the previous one
if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !== -1) { if (mainItem.conference && !mainItem.conference.core.isLocalScreenSharing && mainItem.lastConfLayoutBeforeSharing !==
mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing -1) {
mainItem.lastConfLayoutBeforeSharing = -1 mainItem.conferenceLayout = mainItem.lastConfLayoutBeforeSharing;
mainItem.lastConfLayoutBeforeSharing = -1;
} }
callLayout.sourceComponent = conference callLayout.sourceComponent = conference ? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout
? conference.core.isScreenSharingEnabled || (mainItem.conferenceLayout == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1) == LinphoneEnums.ConferenceLayout.ActiveSpeaker && participantDeviceCount > 1)
? activeSpeakerComponent ? activeSpeakerComponent : participantDeviceCount <= 1 ? waitingForOthersComponent : gridComponent :
: participantDeviceCount <= 1 activeSpeakerComponent;
? waitingForOthersComponent
: gridComponent
: activeSpeakerComponent
} }
Text { Text {
id: callTerminatedText id: callTerminatedText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(25) anchors.topMargin: Utils.getSizeWithScreenRatio(25)
z: 1 z: 1
visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error || mainItem.callState === LinphoneEnums.CallState.Released visible: mainItem.callState === LinphoneEnums.CallState.End || mainItem.callState === LinphoneEnums.CallState.Error
text: mainItem.conference || mainItem.callState === LinphoneEnums.CallState.Released
//: "Vous avez quitté la conférence" text: mainItem.conference ?
? qsTr("meeting_event_conference_destroyed") //: "Vous avez quitté la conférence"
: mainItem.callTerminatedByUser qsTr("meeting_event_conference_destroyed") : mainItem.callTerminatedByUser ?
//: "Vous avez terminé l'appel" //: "Vous avez terminé l'appel"
? qsTr("call_ended_by_user") qsTr("call_ended_by_user") : mainItem.callStarted ?
: mainItem.callStarted //: "Votre correspondant a terminé l'appel"
//: "Votre correspondant a terminé l'appel" qsTr("call_ended_by_remote") : call && call.core.lastErrorMessage || ""
? qsTr("call_ended_by_remote")
: call && call.core.lastErrorMessage || ""
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
pixelSize: Utils.getSizeWithScreenRatio(22) pixelSize: Utils.getSizeWithScreenRatio(22)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
Loader{ Loader {
id: callLayout id: callLayout
anchors.fill: parent anchors.fill: parent
sourceComponent: mainItem.participantDeviceCount === 0 sourceComponent: mainItem.participantDeviceCount === 0 ? waitingForOthersComponent : activeSpeakerComponent
? waitingForOthersComponent
: activeSpeakerComponent
} }
Sticker { Sticker {
id: preview id: preview
qmlName: 'P' qmlName: 'P'
previewEnabled: true previewEnabled: true
visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent === waitingForOthersComponent) visible: (callLayout.sourceComponent === activeSpeakerComponent || callLayout.sourceComponent
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress === waitingForOthersComponent) && mainItem.callState !== LinphoneEnums.CallState.OutgoingProgress
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState !== LinphoneEnums.CallState.OutgoingRinging && mainItem.callState
&& mainItem.callState !== LinphoneEnums.CallState.OutgoingInit !== LinphoneEnums.CallState.OutgoingInit && !mainItem.conference?.core.isScreenSharingEnabled
&& !mainItem.conference?.core.isScreenSharingEnabled && mainItem.participantDeviceCount <= 2
&& mainItem.participantDeviceCount <= 2 height: Utils.getSizeWithScreenRatio(180)
height: Utils.getSizeWithScreenRatio(180) width: Utils.getSizeWithScreenRatio(300)
width: Utils.getSizeWithScreenRatio(300)
anchors.right: mainItem.right anchors.right: mainItem.right
anchors.bottom: mainItem.bottom anchors.bottom: mainItem.bottom
anchors.rightMargin: Utils.getSizeWithScreenRatio(20) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(10) anchors.bottomMargin: Utils.getSizeWithScreenRatio(10)
onVideoEnabledChanged: console.log("Preview : " +videoEnabled + " / " +visible +" / " +mainItem.call) onVideoEnabledChanged: console.log("Preview : " + videoEnabled + " / " + visible + " / " + mainItem.call)
property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress) property var accountObj: UtilsCpp.findLocalAccountByAddress(mainItem.localAddress)
account: accountObj && accountObj.value || null account: accountObj && accountObj.value || null
call: mainItem.call call: mainItem.call
displayAll: false displayAll: false
displayPresence: false displayPresence: false
@ -124,21 +115,21 @@ Item {
id: previewMouseArea id: previewMouseArea
anchors.fill: parent anchors.fill: parent
movableArea: mainItem movableArea: mainItem
margin: Utils.getSizeWithScreenRatio(10) margin: Utils.getSizeWithScreenRatio(10)
function resetPosition(){ function resetPosition() {
preview.anchors.right = mainItem.right preview.anchors.right = mainItem.right;
preview.anchors.bottom = mainItem.bottom preview.anchors.bottom = mainItem.bottom;
preview.anchors.rightMargin = previewMouseArea.margin preview.anchors.rightMargin = previewMouseArea.margin;
preview.anchors.bottomMargin = previewMouseArea.margin preview.anchors.bottomMargin = previewMouseArea.margin;
}
onVisibleChanged: if(!visible){
resetPosition()
} }
onVisibleChanged: if (!visible) {
resetPosition();
}
drag.target: preview drag.target: preview
onDraggingChanged: if(dragging) { onDraggingChanged: if (dragging) {
preview.anchors.right = undefined preview.anchors.right = undefined;
preview.anchors.bottom = undefined preview.anchors.bottom = undefined;
} }
onRequestResetPosition: resetPosition() onRequestResetPosition: resetPosition()
} }
} }
@ -147,22 +138,22 @@ Item {
id: waitingForOthersComponent id: waitingForOthersComponent
Rectangle { Rectangle {
color: DefaultStyle.grey_600 color: DefaultStyle.grey_600
radius: Utils.getSizeWithScreenRatio(15) radius: Utils.getSizeWithScreenRatio(15)
ColumnLayout { ColumnLayout {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Utils.getSizeWithScreenRatio(22) spacing: Utils.getSizeWithScreenRatio(22)
width: waitText.implicitWidth width: waitText.implicitWidth
Text { Text {
id: waitText id: waitText
//: "En attente d'autres participants" //: "En attente d'autres participants"
text: qsTr("conference_call_empty") text: qsTr("conference_call_empty")
Layout.preferredHeight: Utils.getSizeWithScreenRatio(67) Layout.preferredHeight: Utils.getSizeWithScreenRatio(67)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
font { font {
pixelSize: Utils.getSizeWithScreenRatio(30) pixelSize: Utils.getSizeWithScreenRatio(30)
weight: Utils.getSizeWithScreenRatio(300) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
Item { Item {
@ -172,16 +163,16 @@ Item {
borderColor: DefaultStyle.main2_400 borderColor: DefaultStyle.main2_400
icon.source: AppIcons.shareNetwork icon.source: AppIcons.shareNetwork
contentImageColor: DefaultStyle.main2_400 contentImageColor: DefaultStyle.main2_400
//: "Partager le lien" //: "Partager le lien"
text: qsTr("conference_share_link_title") text: qsTr("conference_share_link_title")
anchors.centerIn: parent anchors.centerIn: parent
textColor: DefaultStyle.main2_400 textColor: DefaultStyle.main2_400
onClicked: { onClicked: {
if (mainItem.conference) { if (mainItem.conference) {
UtilsCpp.copyToClipboard(mainItem.conference.core.uri) UtilsCpp.copyToClipboard(mainItem.conference.core.uri);
showInformationPopup(qsTr("copied"), showInformationPopup(qsTr("copied"),
//: Le lien de la réunion a été copié dans le presse-papier //: Le lien de la réunion a été copié dans le presse-papier
qsTr("information_popup_meeting_address_copied_to_clipboard"), true) qsTr("information_popup_meeting_address_copied_to_clipboard"), true);
} }
} }
} }
@ -190,19 +181,18 @@ Item {
} }
} }
Component{ Component {
id: activeSpeakerComponent id: activeSpeakerComponent
ActiveSpeakerLayout{ ActiveSpeakerLayout {
id: activeSpeaker id: activeSpeaker
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
call: mainItem.call call: mainItem.call
} }
} }
Component{ Component {
id: gridComponent id: gridComponent
CallGridLayout{ CallGridLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
call: mainItem.call call: mainItem.call

View file

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

View file

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

View file

@ -19,7 +19,6 @@ GridLayout {
property real maxWidth: Utils.getSizeWithScreenRatio(3 * 105) property real maxWidth: Utils.getSizeWithScreenRatio(3 * 105)
columns: optimalColumns columns: optimalColumns
property int optimalColumns: { property int optimalColumns: {
let maxCols = Math.floor(maxWidth / itemWidth); let maxCols = Math.floor(maxWidth / itemWidth);
let bestCols = 1; let bestCols = 1;
@ -30,10 +29,7 @@ GridLayout {
let rows = Math.ceil(itemCount / cols); let rows = Math.ceil(itemCount / cols);
let emptySlots = cols * rows - itemCount; let emptySlots = cols * rows - itemCount;
if ( if (rows < minRows || (rows === minRows && emptySlots < minEmptySlots)) {
rows < minRows ||
(rows === minRows && emptySlots < minEmptySlots)
) {
bestCols = cols; bestCols = cols;
minRows = rows; minRows = rows;
minEmptySlots = emptySlots; minEmptySlots = emptySlots;

View file

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

View file

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

View file

@ -6,120 +6,127 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp 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 { FocusScope {
id: mainItem id: mainItem
property color searchBarColor: DefaultStyle.grey_100 property color searchBarColor: DefaultStyle.grey_100
property color searchBarBorderColor: "transparent" property color searchBarBorderColor: "transparent"
property alias searchBar: searchBar property alias searchBar: searchBar
property string startGroupButtonText property string startGroupButtonText
property bool startGroupButtonVisible: true property bool startGroupButtonVisible: true
property NumericPadPopup numPadPopup property NumericPadPopup numPadPopup
signal groupCreationRequested() signal groupCreationRequested
signal contactClicked(FriendGui contact) signal contactClicked(FriendGui contact)
clip: true clip: true
property alias topContent: topLayout.data property alias topContent: topLayout.data
property bool topLayoutVisible: topLayout.children.length > 0 property bool topLayoutVisible: topLayout.children.length > 0
property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39) property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39)
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: Utils.getSizeWithScreenRatio(22) spacing: Utils.getSizeWithScreenRatio(22)
ColumnLayout { ColumnLayout {
id: topLayout id: topLayout
visible: mainItem.topLayoutVisible visible: mainItem.topLayoutVisible
spacing: Utils.getSizeWithScreenRatio(18) spacing: Utils.getSizeWithScreenRatio(18)
} }
ColumnLayout { ColumnLayout {
onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close() onVisibleChanged: if (!visible && mainItem.numPadPopup)
spacing: Utils.getSizeWithScreenRatio(38) mainItem.numPadPopup.close()
SearchBar { spacing: Utils.getSizeWithScreenRatio(38)
id: searchBar SearchBar {
Layout.alignment: Qt.AlignTop id: searchBar
Layout.fillWidth: true Layout.alignment: Qt.AlignTop
Layout.rightMargin: mainItem.searchBarRightMaring Layout.fillWidth: true
focus: true Layout.rightMargin: mainItem.searchBarRightMaring
color: mainItem.searchBarColor focus: true
borderColor: mainItem.searchBarBorderColor color: mainItem.searchBarColor
//: "Rechercher un contact" borderColor: mainItem.searchBarBorderColor
placeholderText: qsTr("search_bar_look_for_contact_text") //: "Rechercher un contact"
numericPadPopup: mainItem.numPadPopup placeholderText: qsTr("search_bar_look_for_contact_text")
KeyNavigation.down: groupCreationButton numericPadPopup: mainItem.numPadPopup
} KeyNavigation.down: groupCreationButton
ColumnLayout { }
id: content ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(32) id: content
Button { spacing: Utils.getSizeWithScreenRatio(32)
id: groupCreationButton Button {
visible: mainItem.startGroupButtonVisible id: groupCreationButton
Layout.preferredWidth: Utils.getSizeWithScreenRatio(320) visible: mainItem.startGroupButtonVisible
Layout.preferredHeight: Utils.getSizeWithScreenRatio(44) Layout.preferredWidth: Utils.getSizeWithScreenRatio(320)
padding: 0 Layout.preferredHeight: Utils.getSizeWithScreenRatio(44)
KeyNavigation.up: searchBar padding: 0
KeyNavigation.down: contactList KeyNavigation.up: searchBar
onClicked: mainItem.groupCreationRequested() KeyNavigation.down: contactList
background: Rectangle { onClicked: mainItem.groupCreationRequested()
anchors.fill: parent background: Rectangle {
radius: height / 2 anchors.fill: parent
gradient: Gradient { radius: height / 2
orientation: Gradient.Horizontal gradient: Gradient {
GradientStop { position: 0.0; color: DefaultStyle.main2_100} orientation: Gradient.Horizontal
GradientStop { position: 1.0; color: DefaultStyle.grey_0} GradientStop {
} position: 0.0
// Black border for keyboard navigation color: DefaultStyle.main2_100
border.color: DefaultStyle.main2_900 }
border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0 GradientStop {
} position: 1.0
Accessible.name: mainItem.startGroupButtonText color: DefaultStyle.grey_0
contentItem: RowLayout { }
spacing: Utils.getSizeWithScreenRatio(16) }
anchors.verticalCenter: parent.verticalCenter // Black border for keyboard navigation
Rectangle { border.color: DefaultStyle.main2_900
width: Utils.getSizeWithScreenRatio(44) border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
height: width }
radius: width / 2 Accessible.name: mainItem.startGroupButtonText
color: DefaultStyle.main1_500_main contentItem: RowLayout {
EffectImage { spacing: Utils.getSizeWithScreenRatio(16)
imageSource: AppIcons.usersThreeFilled anchors.verticalCenter: parent.verticalCenter
anchors.centerIn: parent Rectangle {
width: Utils.getSizeWithScreenRatio(24) width: Utils.getSizeWithScreenRatio(44)
height: width height: width
fillMode: Image.PreserveAspectFit radius: width / 2
colorizationColor: DefaultStyle.grey_0 color: DefaultStyle.main1_500_main
} EffectImage {
} imageSource: AppIcons.usersThreeFilled
Text { anchors.centerIn: parent
text: mainItem.startGroupButtonText width: Utils.getSizeWithScreenRatio(24)
color: DefaultStyle.grey_1000 height: width
font { fillMode: Image.PreserveAspectFit
pixelSize: Typography.h4.pixelSize colorizationColor: DefaultStyle.grey_0
weight: Typography.h4.weight }
} }
} Text {
Item { text: mainItem.startGroupButtonText
Layout.fillWidth: true color: DefaultStyle.grey_1000
} font {
EffectImage { pixelSize: Typography.h4.pixelSize
imageSource: AppIcons.rightArrow weight: Typography.h4.weight
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) }
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) }
colorizationColor: DefaultStyle.main2_500_main Item {
} Layout.fillWidth: true
} }
} EffectImage {
AllContactListView{ imageSource: AppIcons.rightArrow
id: contactList Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.fillWidth: true Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.fillHeight: true colorizationColor: DefaultStyle.main2_500_main
showContactMenu: false }
searchBarText: searchBar.text }
onContactSelected: (contact) => { }
mainItem.contactClicked(contact) 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 Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
spacing: Utils.getSizeWithScreenRatio(15) spacing: Utils.getSizeWithScreenRatio(15)
property string label property string label
property var icon property var icon
property alias content: contentControl.contentItem property alias content: contentControl.contentItem
signal titleIconClicked signal titleIconClicked
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Text { Text {
text: mainItem.label text: mainItem.label
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
} }
} }
RoundButton { RoundButton {
visible: mainItem.icon != undefined visible: mainItem.icon != undefined
icon.source: mainItem.icon icon.source: mainItem.icon
style: ButtonStyle.noBackgroundOrange style: ButtonStyle.noBackgroundOrange
onClicked: mainItem.titleIconClicked() onClicked: mainItem.titleIconClicked()
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
RoundButton { RoundButton {
id: expandButton id: expandButton
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
checkable: true checkable: true
checked: true checked: true
icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow
KeyNavigation.down: contentControl KeyNavigation.down: contentControl
} }
} }
RoundedPane { RoundedPane {
id: contentControl id: contentControl
visible: expandButton.checked visible: expandButton.checked
Layout.fillWidth: true Layout.fillWidth: true
leftPadding: Utils.getSizeWithScreenRatio(20) leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20) rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(17) topPadding: Utils.getSizeWithScreenRatio(17)
bottomPadding: 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/Style/buttonStyle.js" as ButtonStyle
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{ FocusScope {
id: mainItem id: mainItem
property alias contentItem: contentItem.data property alias contentItem: contentItem.data
property string label: "" property string label: ""
@ -21,33 +21,32 @@ FocusScope{
implicitHeight: layout.implicitHeight implicitHeight: layout.implicitHeight
function clearErrorText() { function clearErrorText() {
errorText.clear() errorText.clear();
} }
onErrorMessageChanged: if (errorMessage.length > 0) { onErrorMessageChanged: if (errorMessage.length > 0) {
var item = mainItem var item = mainItem;
do { do {
var parentItem = item.parent var parentItem = item.parent;
if (parentItem.contentItem) { if (parentItem.contentItem) {
var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y) var itemPosInParent = mainItem.mapToItem(parentItem.contentItem, mainItem.x, mainItem.y);
if (parentItem.contentY > itemPosInParent.y) { if (parentItem.contentY > itemPosInParent.y) {
parentItem.contentY = itemPosInParent.y; parentItem.contentY = itemPosInParent.y;
} } else if (parentItem.contentY + parentItem.height < itemPosInParent.y + mainItem.height) {
else if (parentItem.contentY+parentItem.height < itemPosInParent.y+mainItem.height) { parentItem.contentY = itemPosInParent.y + mainItem.height - height;
parentItem.contentY = itemPosInParent.y + mainItem.height - height; }
} }
} item = parentItem;
item = parentItem } while (item.parent != undefined && parentItem.contentItem === undefined)
} while(item.parent != undefined && parentItem.contentItem === undefined) }
}
ColumnLayout { ColumnLayout {
id: layout id: layout
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
Text { Text {
visible: label.length > 0 visible: label.length > 0
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -63,7 +62,9 @@ FocusScope{
weight: Typography.p2.weight weight: Typography.p2.weight
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
PopupButton { PopupButton {
visible: mainItem.tooltip !== "" visible: mainItem.tooltip !== ""
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
@ -78,8 +79,8 @@ FocusScope{
Text { Text {
visible: mainItem.labelIndication !== undefined visible: mainItem.labelIndication !== undefined
font.pixelSize: Utils.getSizeWithScreenRatio(12) font.pixelSize: Utils.getSizeWithScreenRatio(12)
font.weight: Utils.getSizeWithScreenRatio(300) font.weight: Utils.getSizeWithScreenRatio(300)
text: mainItem.labelIndication text: mainItem.labelIndication
} }
} }
@ -99,6 +100,5 @@ FocusScope{
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
} }
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,12 +5,12 @@ import QtQuick.Effects
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import CustomControls 1.0 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 { Control.TabBar {
id: mainItem id: mainItem
//spacing: Utils.getSizeWithScreenRatio(32) //spacing: Utils.getSizeWithScreenRatio(32)
topPadding: Utils.getSizeWithScreenRatio(36) topPadding: Utils.getSizeWithScreenRatio(36)
property var model property var model
readonly property alias cornerRadius: bottomLeftCorner.radius readonly property alias cornerRadius: bottomLeftCorner.radius
@ -19,49 +19,51 @@ Control.TabBar {
property int visibleCount: 0 property int visibleCount: 0
signal enterPressed() signal enterPressed
signal spacePressed() signal spacePressed
// Call it after model is ready. If done before, Repeater will not be updated // Call it after model is ready. If done before, Repeater will not be updated
function initButtons(){ function initButtons() {
actionsRepeater.model = mainItem.model actionsRepeater.model = mainItem.model;
} }
function updateVisibleCount() { function updateVisibleCount() {
mainItem.visibleCount = 0 mainItem.visibleCount = 0;
contentChildren.forEach(child => { contentChildren.forEach(child => {
if (child.visible) mainItem.visibleCount = mainItem.visibleCount + 1 if (child.visible)
}) mainItem.visibleCount = mainItem.visibleCount + 1;
});
} }
onDefaultAccountChanged: { onDefaultAccountChanged: {
if (defaultAccount) defaultAccount.core?.lRefreshNotifications() if (defaultAccount)
defaultAccount.core?.lRefreshNotifications();
} }
Connections { Connections {
target: SettingsCpp target: SettingsCpp
function onDisableMeetingsFeatureChanged() { function onDisableMeetingsFeatureChanged() {
initButtons() initButtons();
} }
function onDisableChatFeatureChanged() { function onDisableChatFeatureChanged() {
initButtons() initButtons();
} }
} }
contentItem: ListView { contentItem: ListView {
model: mainItem.contentModel model: mainItem.contentModel
currentIndex: mainItem.currentIndex currentIndex: mainItem.currentIndex
spacing: mainItem.spacing spacing: mainItem.spacing
orientation: ListView.Vertical orientation: ListView.Vertical
// boundsBehavior: Flickable.StopAtBounds // boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded flickableDirection: Flickable.AutoFlickIfNeeded
// snapMode: ListView.SnapToItem // snapMode: ListView.SnapToItem
// highlightMoveDuration: 0 // highlightMoveDuration: 0
// highlightRangeMode: ListView.ApplyRange // highlightRangeMode: ListView.ApplyRange
// preferredHighlightBegin: 40 // preferredHighlightBegin: 40
// preferredHighlightEnd: width - 40 // preferredHighlightEnd: width - 40
} }
background: Item { background: Item {
id: background id: background
@ -70,30 +72,30 @@ Control.TabBar {
id: bottomLeftCorner id: bottomLeftCorner
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
radius: Utils.getSizeWithScreenRatio(25) radius: Utils.getSizeWithScreenRatio(25)
} }
Rectangle { Rectangle {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
width: parent.width/2 width: parent.width / 2
height: parent.height/2 height: parent.height / 2
} }
Rectangle { Rectangle {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
y: parent.y + parent.height/2 y: parent.y + parent.height / 2
width: parent.width width: parent.width
height: parent.height/2 height: parent.height / 2
} }
} }
Repeater { Repeater {
id: actionsRepeater id: actionsRepeater
Control.TabButton { Control.TabButton {
id: tabButton id: tabButton
width: mainItem.width width: mainItem.width
bottomInset: Utils.getSizeWithScreenRatio(32) bottomInset: Utils.getSizeWithScreenRatio(32)
topInset: Utils.getSizeWithScreenRatio(32) topInset: Utils.getSizeWithScreenRatio(32)
hoverEnabled: true hoverEnabled: true
visible: modelData?.visible != undefined ? modelData.visible : true visible: modelData?.visible != undefined ? modelData.visible : true
onVisibleChanged: mainItem.updateVisibleCount() onVisibleChanged: mainItem.updateVisibleCount()
@ -102,15 +104,10 @@ Control.TabBar {
focusPolicy: Qt.StrongFocus focusPolicy: Qt.StrongFocus
activeFocusOnTab: true activeFocusOnTab: true
UnreadNotification { UnreadNotification {
unread: !defaultAccount unread: !defaultAccount ? -1 : index === 0 ? defaultAccount.core?.unreadCallNotifications || -1 : index === 2
? -1 ? defaultAccount.core?.unreadMessageNotifications || -1 : 0
: index === 0
? defaultAccount.core?.unreadCallNotifications || -1
: index === 2
? defaultAccount.core?.unreadMessageNotifications || -1
: 0
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(15) anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
anchors.top: parent.top anchors.top: parent.top
} }
MouseArea { MouseArea {
@ -118,7 +115,7 @@ Control.TabBar {
cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
background: Rectangle{ background: Rectangle {
// Black border for keyboard navigation // Black border for keyboard navigation
visible: tabButton.keyboardFocus visible: tabButton.keyboardFocus
color: "transparent" color: "transparent"
@ -130,7 +127,8 @@ Control.TabBar {
contentItem: ColumnLayout { contentItem: ColumnLayout {
EffectImage { EffectImage {
id: buttonIcon 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 imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon
Layout.preferredWidth: buttonSize Layout.preferredWidth: buttonSize
Layout.preferredHeight: buttonSize Layout.preferredHeight: buttonSize
@ -138,18 +136,16 @@ Control.TabBar {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0 colorizationColor: DefaultStyle.grey_0
useColor: !modelData.colored useColor: !modelData.colored
onStatusChanged: if (status === Image.Ready && !buttonText.visible) buttonText.visible = true onStatusChanged: if (status === Image.Ready && !buttonText.visible)
buttonText.visible = true
} }
Text { Text {
id: buttonText id: buttonText
text: modelData.label text: modelData.label
visible: false visible: false
font { font {
weight: mainItem.currentIndex === index weight: mainItem.currentIndex === index ? Utils.getSizeWithScreenRatio(800) : tabButton.hovered
? Utils.getSizeWithScreenRatio(800) ? Utils.getSizeWithScreenRatio(600) : Utils.getSizeWithScreenRatio(400)
: tabButton.hovered
? Utils.getSizeWithScreenRatio(600)
: Utils.getSizeWithScreenRatio(400)
pixelSize: Utils.getSizeWithScreenRatio(11) pixelSize: Utils.getSizeWithScreenRatio(11)
} }
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
@ -166,29 +162,29 @@ Control.TabBar {
text: modelData.label text: modelData.label
font: buttonText.font font: buttonText.font
Component.onCompleted: { Component.onCompleted: {
font.weight = Utils.getSizeWithScreenRatio(800) font.weight = Utils.getSizeWithScreenRatio(800);
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize) mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize);
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.enterPressed() mainItem.enterPressed();
} else if(event.key === Qt.Key_Space){ } else if (event.key === Qt.Key_Space) {
mainItem.spacePressed() mainItem.spacePressed();
} else if(event.key === Qt.Key_Down){ } else if (event.key === Qt.Key_Down) {
event.accepted = true; event.accepted = true;
if(TabBar.index >= mainItem.visibleCount - 1) if (TabBar.index >= mainItem.visibleCount - 1)
return; return;
tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason) tabButton.nextItemInFocusChain(true).forceActiveFocus(Qt.TabFocusReason);
} else if(event.key === Qt.Key_Up){ } else if (event.key === Qt.Key_Up) {
event.accepted = true; event.accepted = true;
if(TabBar.index <= 0) if (TabBar.index <= 0)
return; return;
tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason) tabButton.nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason);
} }
} }
onClicked: { 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
id: mainItem id: mainItem
clip: true clip: true
keyNavigationEnabled: false // We will reimplement the keyNavigation keyNavigationEnabled: false // We will reimplement the keyNavigation
activeFocusOnTab: true activeFocusOnTab: true
property SearchBar searchBar property SearchBar searchBar
property bool loading: false property bool loading: false
property string searchText: searchBar?.text property string searchText: searchBar?.text
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
property bool lastFocusByNavigationKeyboard: false // Workaround to get the correct focusReason property bool lastFocusByNavigationKeyboard: false // Workaround to get the correct focusReason
signal resultsReceived signal resultsReceived
onResultsReceived: { onResultsReceived: {
loading = false loading = false;
} }
model: CallHistoryProxy { model: CallHistoryProxy {
id: callHistoryProxy id: callHistoryProxy
onListAboutToBeReset: loading = true onListAboutToBeReset: loading = true
filterText: mainItem.searchText filterText: mainItem.searchText
onFilterTextChanged: maxDisplayItems = initialDisplayItems onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(56))) initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(56)))
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onModelAboutToBeReset: loading = true onModelAboutToBeReset: loading = true
onModelReset: { onModelReset: {
mainItem.resultsReceived() mainItem.resultsReceived();
} }
} }
flickDeceleration: 10000 flickDeceleration: 10000
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) { if (event.key == Qt.Key_Escape) {
console.log("Back") console.log("Back");
searchBar.forceActiveFocus(Qt.BacktabFocusReason) searchBar.forceActiveFocus(Qt.BacktabFocusReason);
event.accepted = true 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 // 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 (event.key === Qt.Key_Up) {
if(currentIndex === 0){ if (currentIndex === 0) {
searchBar.forceActiveFocus(Qt.BacktabFocusReason) searchBar.forceActiveFocus(Qt.BacktabFocusReason);
lastFocusByNavigationKeyboard = false lastFocusByNavigationKeyboard = false;
}else{ } else {
decrementCurrentIndex() decrementCurrentIndex();
currentItem.forceActiveFocus(Qt.BacktabFocusReason) // The focusReason is created by QT later, need to create a workaround currentItem.forceActiveFocus(
lastFocusByNavigationKeyboard = true Qt.BacktabFocusReason); // The focusReason is created by QT later, need to create a workaround
} lastFocusByNavigationKeyboard = true;
event.accepted = true }
} event.accepted = true;
else if(event.key === Qt.Key_Down){ } else if (event.key === Qt.Key_Down) {
incrementCurrentIndex() incrementCurrentIndex();
currentItem.forceActiveFocus(Qt.TabFocusReason) // The focusReason is created by QT later, need to create a workaround currentItem.forceActiveFocus(
lastFocusByNavigationKeyboard = true Qt.TabFocusReason); // The focusReason is created by QT later, need to create a workaround
event.accepted = true lastFocusByNavigationKeyboard = true;
} event.accepted = true;
} }
}
Component.onCompleted: cacheBuffer = Math.max(mainItem.height,0) //contentHeight>0 ? contentHeight : 0// cache all items Component.onCompleted: cacheBuffer = Math.max(mainItem.height,
// remove binding loop 0) //contentHeight>0 ? contentHeight : 0// cache all items
// onContentHeightChanged: Qt.callLater(function () { // remove binding loop
// if (mainItem) // onContentHeightChanged: Qt.callLater(function () {
// mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0 // if (mainItem)
// }) // mainItem.cacheBuffer = Math?.max(contentHeight, 0) || 0
// })
onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0) currentIndex = 0 onActiveFocusChanged: if (activeFocus && currentIndex < 0 && count > 0)
onCountChanged: { currentIndex = 0
if (currentIndex < 0 && count > 0) { onCountChanged: {
mainItem.currentIndex = 0 // Select first item after loading model if (currentIndex < 0 && count > 0) {
} mainItem.currentIndex = 0; // Select first item after loading model
if (atYBeginning) }
positionViewAtBeginning() // Stay at beginning if (atYBeginning)
} positionViewAtBeginning(); // Stay at beginning
Connections { }
target: deleteHistoryPopup Connections {
function onAccepted() { target: deleteHistoryPopup
mainItem.model.removeAllEntries() function onAccepted() {
} mainItem.model.removeAllEntries();
} }
}
onAtYEndChanged: { onAtYEndChanged: {
if (atYEnd && count > 0) { if (atYEnd && count > 0) {
callHistoryProxy.displayMore() callHistoryProxy.displayMore();
} }
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
function moveToCurrentItem() { function moveToCurrentItem() {
if (mainItem.currentIndex >= 0) if (mainItem.currentIndex >= 0)
Utils.updatePosition(mainItem, mainItem) Utils.updatePosition(mainItem, mainItem);
} }
onCurrentItemChanged: { onCurrentItemChanged: {
moveToCurrentItem() moveToCurrentItem();
} }
// Update position only if we are moving to current item and its position is changing. // Update position only if we are moving to current item and its position is changing.
property var _currentItemY: currentItem?.y property var _currentItemY: currentItem?.y
on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) { on_CurrentItemYChanged: if (_currentItemY && moveAnimation.running) {
moveToCurrentItem() moveToCurrentItem();
} }
Behavior on contentY { Behavior on contentY {
NumberAnimation { NumberAnimation {
id: moveAnimation id: moveAnimation
duration: 500 duration: 500
easing.type: Easing.OutExpo easing.type: Easing.OutExpo
alwaysRunToEnd: true alwaysRunToEnd: true
} }
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
BusyIndicator { BusyIndicator {
anchors.horizontalCenter: mainItem.horizontalCenter anchors.horizontalCenter: mainItem.horizontalCenter
visible: mainItem.loading visible: mainItem.loading
height: visible ? mainItem.busyIndicatorSize : 0 height: visible ? mainItem.busyIndicatorSize : 0
width: mainItem.busyIndicatorSize width: mainItem.busyIndicatorSize
indicatorHeight: mainItem.busyIndicatorSize indicatorHeight: mainItem.busyIndicatorSize
indicatorWidth: mainItem.busyIndicatorSize indicatorWidth: mainItem.busyIndicatorSize
indicatorColor: DefaultStyle.main1_500_main indicatorColor: DefaultStyle.main1_500_main
} }
// Qt bug: sometimes, containsMouse may not be send and update on each MouseArea. // 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. // So we need to use this variable to switch off all hovered items.
property int lastMouseContainsIndex: -1 property int lastMouseContainsIndex: -1
delegate: FocusScope { delegate: FocusScope {
width: mainItem.width width: mainItem.width
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
Accessible.role: Accessible.ListItem Accessible.role: Accessible.ListItem
RowLayout { RowLayout {
z: 1 z: 1
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Utils.getSizeWithScreenRatio(10) anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Avatar { Avatar {
id: historyAvatar id: historyAvatar
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress)
contact: contactObj?.value || null contact: contactObj?.value || null
displayNameVal: modelData.core.displayName displayNameVal: modelData.core.displayName
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
width: Utils.getSizeWithScreenRatio(45) width: Utils.getSizeWithScreenRatio(45)
height: Utils.getSizeWithScreenRatio(45) height: Utils.getSizeWithScreenRatio(45)
isConference: modelData.core.isConference isConference: modelData.core.isConference
shadowEnabled: false shadowEnabled: false
asynchronous: false asynchronous: false
} }
ColumnLayout { ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
maximumLineCount: 1 maximumLineCount: 1
text: modelData.core.displayName text: modelData.core.displayName
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
} }
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(6) spacing: Utils.getSizeWithScreenRatio(6)
EffectImage { EffectImage {
id: statusIcon id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted
=== LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow :
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
|| 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
colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
=== LinphoneEnums.CallStatus.Declined === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main :
=== LinphoneEnums.CallStatus.DeclinedElsewhere modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
|| modelData.core.status Layout.preferredWidth: Utils.getSizeWithScreenRatio(12)
=== LinphoneEnums.CallStatus.Aborted Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
|| modelData.core.status transform: Rotation {
=== LinphoneEnums.CallStatus.EarlyAborted angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined
|| modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status
Layout.preferredWidth: Utils.getSizeWithScreenRatio(12) === LinphoneEnums.CallStatus.Aborted || modelData.core.status
Layout.preferredHeight: Utils.getSizeWithScreenRatio(12) === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
transform: Rotation { origin {
angle: modelData.core.isOutgoing x: statusIcon.width / 2
&& (modelData.core.status === LinphoneEnums.CallStatus.Declined y: statusIcon.height / 2
|| modelData.core.status }
=== LinphoneEnums.CallStatus.DeclinedElsewhere }
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted }
|| modelData.core.status Text {
=== LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 // text: modelData.core.date
origin { text: UtilsCpp.formatDate(modelData.core.date)
x: statusIcon.width / 2 font {
y: statusIcon.height / 2 pixelSize: Utils.getSizeWithScreenRatio(12)
} weight: Utils.getSizeWithScreenRatio(300)
} }
} }
Text { }
// text: modelData.core.date }
text: UtilsCpp.formatDate(modelData.core.date) BigButton {
font { id: callButton
pixelSize: Utils.getSizeWithScreenRatio(12) visible: !modelData.core.isConference || !SettingsCpp.disableMeetingsFeature
weight: Utils.getSizeWithScreenRatio(300) style: ButtonStyle.noBackground
} icon.source: AppIcons.phone
} focus: false
} activeFocusOnTab: false
} asynchronous: false
BigButton {
id: callButton
visible: !modelData.core.isConference || !SettingsCpp.disableMeetingsFeature
style: ButtonStyle.noBackground
icon.source: AppIcons.phone
focus: false
activeFocusOnTab: false
asynchronous: false
//: Call %1 //: Call %1
Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal) Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal)
onClicked: { onClicked: {
if (modelData.core.isConference) { if (modelData.core.isConference) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow() var callsWindow = UtilsCpp.getOrCreateCallsWindow();
callsWindow.setupConference( callsWindow.setupConference(modelData.core.conferenceInfo);
modelData.core.conferenceInfo) UtilsCpp.smartShowWindow(callsWindow);
UtilsCpp.smartShowWindow(callsWindow) } else {
} else { UtilsCpp.createCall(modelData.core.remoteAddress);
UtilsCpp.createCall(modelData.core.remoteAddress) }
} }
} Keys.onPressed: event => {
Keys.onPressed: event => { if (event.key === Qt.Key_Left) {
if (event.key === Qt.Key_Left){ backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason);
backgroundMouseArea.forceActiveFocus(Qt.BacktabFocusReason) lastFocusByNavigationKeyboard = true;
lastFocusByNavigationKeyboard = true; }
} }
} onActiveFocusChanged: {
onActiveFocusChanged: { if (!activeFocus) {
if (!activeFocus) { console.log("Unfocus button");
console.log("Unfocus button"); callButton.focus = false; // Make sure to be unfocusable (could be when called by forceActiveFocus)
callButton.focus = false // Make sure to be unfocusable (could be when called by forceActiveFocus) backgroundMouseArea.focus = true;
backgroundMouseArea.focus = true }
} }
} }
} }
} MouseArea {
MouseArea { id: backgroundMouseArea
id: backgroundMouseArea hoverEnabled: true
hoverEnabled: true anchors.fill: parent
anchors.fill: parent focus: true
focus: true property bool keyboardFocus: FocusHelper.keyboardFocus || activeFocus && lastFocusByNavigationKeyboard
property bool keyboardFocus: FocusHelper.keyboardFocus || activeFocus && lastFocusByNavigationKeyboard
//: %1 - %2 - %3 - right arrow for call-back button //: %1 - %2 - %3 - right arrow for call-back button
Accessible.name: qsTr("call_history_entry_accessible_name").arg( Accessible.name: qsTr("call_history_entry_accessible_name").arg(
//: "Appel manqué" //: "Appel manqué"
modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") modelData.core.status === LinphoneEnums.CallStatus.Missed ? qsTr("notification_missed_call_title") :
//: "Appel sortant" //: "Appel sortant"
: modelData.core.isOutgoing ? qsTr("call_outgoing") modelData.core.isOutgoing ? qsTr("call_outgoing") :
//: "Appel entrant" //: "Appel entrant"
: qsTr("call_audio_incoming") qsTr("call_audio_incoming")).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(
).arg(historyAvatar.displayNameVal).arg(UtilsCpp.formatDate(modelData.core.date)) modelData.core.date))
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) if (containsMouse)
mainItem.lastMouseContainsIndex = index mainItem.lastMouseContainsIndex = index;
else if (mainItem.lastMouseContainsIndex == index) else if (mainItem.lastMouseContainsIndex == index)
mainItem.lastMouseContainsIndex = -1 mainItem.lastMouseContainsIndex = -1;
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
opacity: 0.7 opacity: 0.7
radius: Utils.getSizeWithScreenRatio(8) radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex color: mainItem.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
=== index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
border.color: backgroundMouseArea.keyboardFocus ? DefaultStyle.main2_900 : "transparent" border.color: backgroundMouseArea.keyboardFocus ? DefaultStyle.main2_900 : "transparent"
border.width: backgroundMouseArea.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0 border.width: backgroundMouseArea.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
visible: mainItem.lastMouseContainsIndex === index visible: mainItem.lastMouseContainsIndex === index || mainItem.currentIndex === index
|| mainItem.currentIndex === index }
} onPressed: {
onPressed: { mainItem.currentIndex = model.index;
mainItem.currentIndex = model.index mainItem.forceActiveFocus();
mainItem.forceActiveFocus() mainItem.lastFocusByNavigationKeyboard = false;
mainItem.lastFocusByNavigationKeyboard = false }
} Keys.onPressed: event => {
Keys.onPressed: event => { if (event.key === Qt.Key_Right) {
if(event.key === Qt.Key_Right){ callButton.forceActiveFocus(Qt.TabFocusReason);
callButton.forceActiveFocus(Qt.TabFocusReason) }
} }
} }
} }
}
} }

View file

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

View file

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

View file

@ -4,11 +4,10 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp 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 // 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 // The FileView file does not allow that as it is a Loader and the image
@ -23,7 +22,7 @@ AnimatedImage {
mipmap: false//SettingsModel.mipmapEnabled mipmap: false//SettingsModel.mipmapEnabled
autoTransform: true autoTransform: true
fillMode: Image.PreserveAspectFit 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.width: implicitWidth
// sourceSize.height: implicitHeight // sourceSize.height: implicitHeight
states: State { states: State {
@ -38,19 +37,21 @@ AnimatedImage {
// Changing cursor in MouseArea seems not to work with the Loader // Changing cursor in MouseArea seems not to work with the Loader
// Use override cursor for this case // Use override cursor for this case
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
mainItem.state = containsMouse ? 'hovered' : '' else
} UtilsCpp.restoreGlobalCursor();
onPressed: (mouse) => { mainItem.state = containsMouse ? 'hovered' : '';
mouse.accepted = true
// if(SettingsModel.isVfsEncrypted){
// window.attachVirtualWindow(Utils.buildCommonDialogUri('FileViewDialog'), {
// contentGui: mainItem.contentGui,
// }, function (status) {
// })
// }else
mainItem.contentGui.core.lOpenFile()
} }
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,72 +13,73 @@ Item {
// used for creating a voice recording message // used for creating a voice recording message
property var chatMessageObj property var chatMessageObj
property ChatMessageGui chatMessage: chatMessageObj && chatMessageObj.value || null 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() onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop()
property bool recording: false property bool recording: false
property RecorderGui recorderGui: recorderLoader.item || null property RecorderGui recorderGui: recorderLoader.item || null
signal voiceRecordingMessageCreationRequested(RecorderGui recorderGui) signal voiceRecordingMessageCreationRequested(RecorderGui recorderGui)
signal stopRecording() signal stopRecording
signal endOfFileReached() signal endOfFileReached
// auto play if follows a voice recording // auto play if follows a voice recording
function requestPlaying() { function requestPlaying() {
if(soudPlayerLoader.item) { if (soudPlayerLoader.item) {
soudPlayerLoader.item.play(true) soudPlayerLoader.item.play(true);
} }
} }
function createVoiceMessageInChat(chat) { function createVoiceMessageInChat(chat) {
if (recorderLoader.item) { if (recorderLoader.item) {
mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat) mainItem.chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderLoader.item, chat);
} else { } else {
//: Error //: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: Failed to create voice message : error in recorder //: Failed to create voice message : error in recorder
qsTr("information_popup_voice_message_error_message"), false) qsTr("information_popup_voice_message_error_message"), false);
} }
} }
Loader { Loader {
id: soudPlayerLoader id: soudPlayerLoader
property int duration: mainItem.chatMessageContentGui property int duration: mainItem.chatMessageContentGui ? mainItem.chatMessageContentGui.core.fileDuration : item
? mainItem.chatMessageContentGui.core.fileDuration ? item.core.duration : 0
: item
? item.core.duration
: 0
property int position: item?.core.position || 0 property int position: item?.core.position || 0
active: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.isVoiceRecording active: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.isVoiceRecording
sourceComponent: SoundPlayerGui { sourceComponent: SoundPlayerGui {
id: soundPlayerGui id: soundPlayerGui
source: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.filePath source: mainItem.chatMessageContentGui && mainItem.chatMessageContentGui.core.filePath
function play(restartIfPlaying){ function play(restartIfPlaying) {
if(mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)){// Pause the play if (mainItem.isPlaying && (restartIfPlaying === undefined || !restartIfPlaying)) {
soundPlayerGui.core.lPause() // Pause the play
} else if (restartIfPlaying) { //Play from scratch soundPlayerGui.core.lPause();
soundPlayerGui.core.lRestart() } else if (restartIfPlaying) {
} else {// Play the audio //Play from scratch
soundPlayerGui.core.lPlay() soundPlayerGui.core.lRestart();
} else {
// Play the audio
soundPlayerGui.core.lPlay();
} }
} }
onStopped: { onStopped: {
mediaProgressBar.value = 101 mediaProgressBar.value = 101;
} }
onPositionChanged: { onPositionChanged: {
mediaProgressBar.progressPosition = soudPlayerLoader.position mediaProgressBar.progressPosition = soudPlayerLoader.position;
mediaProgressBar.value = 100 * ( mediaProgressBar.progressPosition / soudPlayerLoader.duration) mediaProgressBar.value = 100 * (mediaProgressBar.progressPosition / soudPlayerLoader.duration);
} }
onSourceChanged: if (source != "") { onSourceChanged: if (source != "") {
core.lOpen() // Open the file and allow seeking core.lOpen(); // Open the file and allow seeking
mediaProgressBar.value = 0 mediaProgressBar.value = 0;
mediaProgressBar.refresh() mediaProgressBar.refresh();
} }
onErrorChanged: (error) => { onErrorChanged: error => {
//: Error //: Error
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), error, false);
} }
onEofReached: { onEofReached: {
mainItem.endOfFileReached() mainItem.endOfFileReached();
} }
} }
} }
@ -93,57 +94,55 @@ Item {
Connections { Connections {
target: mainItem target: mainItem
function onStopRecording() { function onStopRecording() {
recorderLoader.item.core.lStop() recorderLoader.item.core.lStop();
} }
} }
sourceComponent: RecorderGui { sourceComponent: RecorderGui {
id: recorderGui id: recorderGui
onReady: core.lStart() onReady: core.lStart()
onStateChanged: (state) => { onStateChanged: state => {
if (state === LinphoneEnums.RecorderState.Running) mediaProgressBar.start() if (state === LinphoneEnums.RecorderState.Running)
if (state === LinphoneEnums.RecorderState.Closed) { mediaProgressBar.start();
mediaProgressBar.stop() if (state === LinphoneEnums.RecorderState.Closed) {
mainItem.voiceRecordingMessageCreationRequested(recorderGui) mediaProgressBar.stop();
} mainItem.voiceRecordingMessageCreationRequested(recorderGui);
} }
}
} }
} }
MediaProgressBar{ MediaProgressBar {
id: mediaProgressBar id: mediaProgressBar
anchors.fill: parent anchors.fill: parent
progressDuration: soudPlayerLoader.active progressDuration: soudPlayerLoader.active ? soudPlayerLoader.duration : recorderLoader ? recorderLoader.duration :
? soudPlayerLoader.duration chatMessageContentGui.core.fileDuration
: recorderLoader
? recorderLoader.duration
: chatMessageContentGui.core.fileDuration
progressPosition: 0 progressPosition: 0
value: 0 value: 0
recording: recorderLoader.state === LinphoneEnums.RecorderState.Running recording: recorderLoader.state === LinphoneEnums.RecorderState.Running
function refresh(){ function refresh() {
if(soudPlayerLoader.item){ if (soudPlayerLoader.item) {
soudPlayerLoader.item.core.lRefreshPosition() soudPlayerLoader.item.core.lRefreshPosition();
} else if (recorderLoader.item) { } else if (recorderLoader.item) {
recorderLoader.item.core.lRefresh() recorderLoader.item.core.lRefresh();
} }
} }
onEndReached:{ onEndReached: {
if(soudPlayerLoader.item) if (soudPlayerLoader.item)
soudPlayerLoader.item.core.lStop() soudPlayerLoader.item.core.lStop();
} }
onPlayStopButtonToggled: { onPlayStopButtonToggled: {
if(soudPlayerLoader.item) { if (soudPlayerLoader.item) {
soudPlayerLoader.item.play() soudPlayerLoader.item.play();
} else if (recorderLoader.item) { } else if (recorderLoader.item) {
recorderLoader.item.core.lStop() recorderLoader.item.core.lStop();
} }
} }
onRefreshPositionRequested: refresh() onRefreshPositionRequested: refresh()
onSeekRequested: (ms) => { onSeekRequested: ms => {
if(soudPlayerLoader.active) { if (soudPlayerLoader.active) {
soudPlayerLoader.item.core.lSeek(ms) soudPlayerLoader.item.core.lSeek(ms);
} }
} }
} }
} }

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -5,418 +5,415 @@ import QtQuick.Controls.Basic as Control
import Qt.labs.qmlmodels import Qt.labs.qmlmodels
import Linphone import Linphone
import UtilsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
id: mainItem id: mainItem
spacing: Utils.getSizeWithScreenRatio(4) spacing: Utils.getSizeWithScreenRatio(4)
property ChatGui chat property ChatGui chat
property color backgroundColor property color backgroundColor
property bool lastItemVisible: false property bool lastItemVisible: false
property int lastIndexFoundWithFilter: -1 property int lastIndexFoundWithFilter: -1
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property bool loading: false property bool loading: false
property bool isEncrypted: chat && chat.core.isEncrypted property bool isEncrypted: chat && chat.core.isEncrypted
property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== "" && AppCpp.currentAccount.core.conferenceFactoryAddress !== "" property bool showEncryptedInfo: AppCpp.currentAccount !== null && AppCpp.currentAccount.core.limeServerUrl !== ""
highlightFollowsCurrentItem: true && AppCpp.currentAccount.core.conferenceFactoryAddress !== ""
highlightFollowsCurrentItem: true
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop
signal showReactionsForMessageRequested(ChatMessageGui chatMessage) signal showReactionsForMessageRequested(ChatMessageGui chatMessage)
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage) signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
signal replyToMessageRequested(ChatMessageGui chatMessage) signal replyToMessageRequested(ChatMessageGui chatMessage)
signal forwardMessageRequested(ChatMessageGui chatMessage) signal forwardMessageRequested(ChatMessageGui chatMessage)
signal editMessageRequested(ChatMessageGui chatMessage) signal editMessageRequested(ChatMessageGui chatMessage)
signal requestHighlight(int indexToHighlight) signal requestHighlight(int indexToHighlight)
signal requestAutoPlayVoiceRecording(int indexToPlay) signal requestAutoPlayVoiceRecording(int indexToPlay)
signal searchMessageByIdRequested(string id) signal searchMessageByIdRequested(string id)
currentIndex: -1 currentIndex: -1
property string filterText property string filterText
onFilterTextChanged: { onFilterTextChanged: {
lastIndexFoundWithFilter = -1 lastIndexFoundWithFilter = -1;
if (filterText === "") return if (filterText === "")
eventLogProxy.filterText = filterText return;
var indexVisible = indexAt(contentX, contentY) eventLogProxy.filterText = filterText;
eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true) var indexVisible = indexAt(contentX, contentY);
} eventLogProxy.findIndexCorrespondingToFilter(indexVisible, true, true);
signal findIndexWithFilter(bool forward) }
property bool searchForward: true signal findIndexWithFilter(bool forward)
onFindIndexWithFilter: (forward) => { property bool searchForward: true
searchForward = forward onFindIndexWithFilter: forward => {
eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false) searchForward = forward;
} eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false);
onSearchMessageByIdRequested: (id) => { }
eventLogProxy.findChatMessageById(id) onSearchMessageByIdRequested: id => {
} eventLogProxy.findChatMessageById(id);
}
Button { Button {
visible: !mainItem.lastItemVisible visible: !mainItem.lastItemVisible
icon.source: AppIcons.downArrow icon.source: AppIcons.downArrow
leftPadding: Utils.getSizeWithScreenRatio(20) leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20) rightPadding: Utils.getSizeWithScreenRatio(20)
topPadding: Utils.getSizeWithScreenRatio(20) topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20) bottomPadding: Utils.getSizeWithScreenRatio(20)
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
style: ButtonStyle.main style: ButtonStyle.main
anchors.right: parent.right anchors.right: parent.right
anchors.bottomMargin: Utils.getSizeWithScreenRatio(18) anchors.bottomMargin: Utils.getSizeWithScreenRatio(18)
anchors.rightMargin: Utils.getSizeWithScreenRatio(18) anchors.rightMargin: Utils.getSizeWithScreenRatio(18)
onClicked: { onClicked: {
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex();
mainItem.positionViewAtIndex(index, ListView.Contain) mainItem.positionViewAtIndex(index, ListView.Contain);
eventLogProxy.markIndexAsRead(index) eventLogProxy.markIndexAsRead(index);
} }
UnreadNotification { UnreadNotification {
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.topMargin: Utils.getSizeWithScreenRatio(-5) anchors.topMargin: Utils.getSizeWithScreenRatio(-5)
anchors.rightMargin: Utils.getSizeWithScreenRatio(-5) anchors.rightMargin: Utils.getSizeWithScreenRatio(-5)
unread: mainItem.chat?.core.unreadMessagesCount || 0 unread: mainItem.chat?.core.unreadMessagesCount || 0
} }
} }
onAtYBeginningChanged: if (atYBeginning && count !== 0) { onAtYBeginningChanged: if (atYBeginning && count !== 0) {
eventLogProxy.displayMore() eventLogProxy.displayMore();
} }
onAtYEndChanged: if (atYEnd && chat && count !== 0) { onAtYEndChanged: if (atYEnd && chat && count !== 0) {
chat.core.lMarkAsRead() chat.core.lMarkAsRead();
} }
model: EventLogProxy { model: EventLogProxy {
id: eventLogProxy id: eventLogProxy
chatGui: mainItem.chat chatGui: mainItem.chat
filterText: mainItem.filterText filterText: mainItem.filterText
initialDisplayItems: 20 initialDisplayItems: 20
displayItemsStep: 20 displayItemsStep: 20
onModelAboutToBeReset: { onModelAboutToBeReset: {
loading = true loading = true;
} }
onModelReset: loading = false onModelReset: loading = false
onModelUpdated: { onModelUpdated: {
loading = false loading = false;
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex();
var itemToSelect = mainItem.itemAtIndex(index) var itemToSelect = mainItem.itemAtIndex(index);
mainItem.positionViewAtIndex(index, ListView.Beginning) mainItem.positionViewAtIndex(index, ListView.Beginning);
var lastMessage = itemAtIndex(0) var lastMessage = itemAtIndex(0);
mainItem.lastItemVisible = lastMessage.isFullyVisible mainItem.lastItemVisible = lastMessage.isFullyVisible;
eventLogProxy.markIndexAsRead(index) eventLogProxy.markIndexAsRead(index);
} }
onEventInsertedByUser: (index) => { onEventInsertedByUser: index => {
mainItem.positionViewAtIndex(index, ListView.Beginning) mainItem.positionViewAtIndex(index, ListView.Beginning);
} }
onIndexWithFilterFound: (index) => { onIndexWithFilterFound: index => {
if (index !== -1) { if (index !== -1) {
currentIndex = index currentIndex = index;
mainItem.positionViewAtIndex(index, ListView.Center) mainItem.positionViewAtIndex(index, ListView.Center);
mainItem.requestHighlight(index) mainItem.requestHighlight(index);
mainItem.lastIndexFoundWithFilter = index mainItem.lastIndexFoundWithFilter = index;
} else { } else {
if (mainItem.lastIndexFoundWithFilter !== index) { if (mainItem.lastIndexFoundWithFilter !== index) {
//: Find message //: Find message
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), mainItem.searchForward ?
mainItem.searchForward //: Last result reached
//: Last result reached qsTr("info_popup_last_result_message") :
? qsTr("info_popup_last_result_message") //: First result reached
//: First result reached qsTr("info_popup_first_result_message"), false);
: qsTr("info_popup_first_result_message"), false) mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center);
mainItem.positionViewAtIndex(mainItem.lastIndexFoundWithFilter, ListView.Center) mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter);
mainItem.requestHighlight(mainItem.lastIndexFoundWithFilter) } else {
} //: Find message
else { UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"),
//: Find message //: No result found
UtilsCpp.showInformationPopup(qsTr("popup_info_find_message_title"), qsTr("info_popup_no_result_message"), false);
//: No result found }
qsTr("info_popup_no_result_message"), false) }
} }
} onFoundMessagById: index => {
} if (index !== -1) {
onFoundMessagById: (index) => { currentIndex = index;
if (index !== -1) { mainItem.positionViewAtIndex(index, ListView.Center);
currentIndex = index mainItem.requestHighlight(index);
mainItem.positionViewAtIndex(index, ListView.Center) }
mainItem.requestHighlight(index) }
} }
}
}
footer: Item { footer: Item {
visible: mainItem.chat && !mainItem.loading visible: mainItem.chat && !mainItem.loading
height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(30) height: visible ? (headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin) : Utils.getSizeWithScreenRatio(
width: headerMessage.width 30)
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)
}
}
}
BusyIndicator { width: headerMessage.width
anchors.horizontalCenter: mainItem.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: mainItem.verticalCenter Control.Control {
visible: mainItem.loading id: headerMessage
height: visible ? mainItem.busyIndicatorSize : 0 visible: mainItem.showEncryptedInfo
width: mainItem.busyIndicatorSize property int topMargin: Utils.getSizeWithScreenRatio(mainItem.contentHeight > mainItem.height ? 30 : 50)
indicatorHeight: mainItem.busyIndicatorSize property int bottomMargin: Utils.getSizeWithScreenRatio(30)
indicatorWidth: mainItem.busyIndicatorSize anchors.topMargin: topMargin
indicatorColor: DefaultStyle.main1_500_main anchors.bottomMargin: bottomMargin
} anchors.top: parent.top
padding: Utils.getSizeWithScreenRatio(10)
background: Rectangle {
Dialog { color: "transparent"
id: messageDeletionDialog border.color: DefaultStyle.main2_200
width: Utils.getSizeWithScreenRatio(637) border.width: Utils.getSizeWithScreenRatio(2)
//: "Supprimer le message ?" radius: Utils.getSizeWithScreenRatio(10)
title: qsTr("conversation_dialog_delete_chat_message_title") }
property var chatMessage contentItem: RowLayout {
buttons: RowLayout { EffectImage {
id: buttonsLayout Layout.preferredWidth: Utils.getSizeWithScreenRatio(23)
Layout.alignment: Qt.AlignBottom | Qt.AlignRight Layout.preferredHeight: Utils.getSizeWithScreenRatio(23)
spacing: Utils.getSizeWithScreenRatio(20) imageSource: mainItem.isEncrypted ? AppIcons.lockSimple : AppIcons.lockSimpleOpen
MediumButton { colorizationColor: mainItem.isEncrypted ? DefaultStyle.info_500_main : DefaultStyle.warning_700
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 { ColumnLayout {
id: secondButtonId spacing: Utils.getSizeWithScreenRatio(2)
text: qsTr("conversation_dialog_delete_for_everyone_label") Text {
style: ButtonStyle.main text: mainItem.isEncrypted ?
onClicked: { //: End to end encrypted chat
messageDeletionDialog.chatMessage.core.lRetract() qsTr("chat_message_list_encrypted_header_title") :
messageDeletionDialog.close() //: 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 Text {
KeyNavigation.right: thirdButtonId text: mainItem.isEncrypted ?
} //: Messages in this conversation are e2e encrypted. \n Only your correspondent can decrypt them.
MediumButton { qsTr("chat_message_list_encrypted_header_message") :
id: thirdButtonId //: Messages are not end to end encrypted, \n may sure you don't share any sensitive information !
text: qsTr("dialog_cancel") qsTr("chat_message_list_not_encrypted_header_message")
style: ButtonStyle.secondary Layout.fillWidth: true
onClicked: { color: DefaultStyle.grey_400
messageDeletionDialog.close() font {
pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight
}
} }
KeyNavigation.left: secondButtonId
KeyNavigation.right: firstButtonId
} }
} }
} }
}
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)
}
}
}
delegate: DelegateChooser { BusyIndicator {
role: "eventType" anchors.horizontalCenter: mainItem.horizontalCenter
DelegateChoice { anchors.verticalCenter: mainItem.verticalCenter
roleValue: "chatMessage" visible: mainItem.loading
delegate: ChatMessage { height: visible ? mainItem.busyIndicatorSize : 0
id: chatMessageDelegate width: mainItem.busyIndicatorSize
visible: !mainItem.loading indicatorHeight: mainItem.busyIndicatorSize
property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY) indicatorWidth: mainItem.busyIndicatorSize
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) indicatorColor: DefaultStyle.main1_500_main
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
onMessageDeletionRequested: { Dialog {
if (chatMessage.core.isOutgoing && chatMessage.core.isRetractable && !chatMessage.core.isRetracted) { id: messageDeletionDialog
messageDeletionDialog.chatMessage = chatMessage width: Utils.getSizeWithScreenRatio(637)
messageDeletionDialog.open() //: "Supprimer le message ?"
} else { title: qsTr("conversation_dialog_delete_chat_message_title")
chatMessage.core.lDelete() 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) Component.onCompleted: {
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage) if (index === 0) {
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage) mainItem.lastItemVisible = isFullyVisible;
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage) }
onSearchMessageByIdRequested: (id) => mainItem.searchMessageByIdRequested(id) }
onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage) chat: mainItem.chat
onEndOfVoiceRecordingReached: { searchedTextPart: mainItem.filterText
if (nextChatMessage && nextChatMessage.core.isVoiceRecording) mainItem.requestAutoPlayVoiceRecording(index - 1) maxWidth: Math.round(mainItem.width * (3 / 4))
} width: mainItem.width
Connections { property var previousIndex: index - 1
target: mainItem property ChatMessageGui nextChatMessage: index <= 0 ? null : eventLogProxy.getEventAtIndex(index - 1)
function onRequestHighlight(indexToHighlight) { ? eventLogProxy.getEventAtIndex(index - 1).core.chatMessageGui : null
if (indexToHighlight === index) { property var previousFromAddress: eventLogProxy.getEventAtIndex(index + 1)?.core.chatMessage?.fromAddress
requestHighlight() backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100
} isFirstMessage: !previousFromAddress || previousFromAddress !== chatMessage.core.fromAddress
} anchors.right: !isRemoteMessage && parent ? parent.right : undefined
function onRequestAutoPlayVoiceRecording(indexToPlay) {
if (indexToPlay === index) { onMessageDeletionRequested: {
chatMessageDelegate.requestAutoPlayVoiceRecording() 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 { Connections {
target: chatMessage.core target: chatMessage.core
onIsRetractedChanged: { onIsRetractedChanged: {
if (chatMessage.core.isRetracted && chatMessage.core.isOutgoing) { if (chatMessage.core.isRetracted && chatMessage.core.isOutgoing) {
UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"), UtilsCpp.showInformationPopup(qsTr("info_toast_deleted_title"),
//: The message has been deleted //: The message has been deleted
qsTr("info_toast_deleted_message"), true) 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 { DelegateChoice {
roleValue: "ephemeralEvent" roleValue: "event"
delegate: Item { delegate: Item {
id: ephemeralEventDelegate id: eventDelegate
visible: !mainItem.loading visible: !mainItem.loading
property int yoff: Math.round(ephemeralEventDelegate.y - mainItem.contentY) property int yoff: Math.round(eventDelegate.y - mainItem.contentY)
property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
onIsFullyVisibleChanged: { onIsFullyVisibleChanged: {
if (index === 0) { if (index === 0) {
mainItem.lastItemVisible = isFullyVisible mainItem.lastItemVisible = isFullyVisible;
} }
} }
property bool showTopMargin: !header.visible && index == 0 property bool showTopMargin: !header.visible && index == 0
width: mainItem.width width: mainItem.width
//height: Utils.getSizeWithScreenRatio(40) height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + eventItem.implicitHeight
height: (showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0) + ephemeralEventItem.height Event {
EphemeralEvent { id: eventItem
id: ephemeralEventItem anchors.top: parent.top
anchors.top: parent.top anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0
anchors.topMargin: showTopMargin ? Utils.getSizeWithScreenRatio(30) : 0 width: parent.width
eventLogGui: modelData 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,21 +5,22 @@ import Linphone
import UtilsCpp import UtilsCpp
// TODO : into Loader // TODO : into Loader
// ============================================================================= // =============================================================================
TextEdit { TextEdit {
id: mainItem id: mainItem
property ChatMessageContentGui contentGui property ChatMessageContentGui contentGui
property ChatGui chatGui: null property ChatGui chatGui: null
property string lastTextSelected : '' property string lastTextSelected: ''
property string searchedTextPart property string searchedTextPart
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
// force restoring cursor in case we click on a mention, otherwise // force restoring cursor in case we click on a mention, otherwise
// the cursor stays IBeam // the cursor stays IBeam
onVisibleChanged: if (!visible) UtilsCpp.restoreGlobalCursor() onVisibleChanged: if (!visible)
UtilsCpp.restoreGlobalCursor()
font { 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 weight: Typography.p1.weight
} }
// property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth // property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth
@ -31,58 +32,62 @@ TextEdit {
text: contentGui.core.richFormatText text: contentGui.core.richFormatText
onSearchedTextPartChanged: { onSearchedTextPartChanged: {
contentGui.core.setSearchedTextPart(searchedTextPart) contentGui.core.setSearchedTextPart(searchedTextPart);
} }
textFormat: Text.RichText // To supports links and imgs. textFormat: Text.RichText // To supports links and imgs.
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
onLinkActivated: (link) => { onLinkActivated: link => {
if (link.startsWith('sip')) if (link.startsWith('sip'))
UtilsCpp.createCall(link) UtilsCpp.createCall(link);
else if (link.startsWith('mention:')) { else if (link.startsWith('mention:')) {
var mentionAddress = link.substring(8) // remove "mention:" var mentionAddress = link.substring(8); // remove "mention:"
UtilsCpp.openContactAtAddress(mentionAddress); UtilsCpp.openContactAtAddress(mentionAddress);
} } else
else Qt.openUrlExternally(link);
Qt.openUrlExternally(link) }
} onSelectedTextChanged: {
onSelectedTextChanged:{ if (selectedText != '')
if(selectedText != '') lastTextSelected = selectedText lastTextSelected = selectedText;
} }
onLinkHovered: { onLinkHovered: {
if (hoveredLink !== "") UtilsCpp.setGlobalCursor(Qt.PointingHandCursor) if (hoveredLink !== "")
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.PointingHandCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
onActiveFocusChanged: { onActiveFocusChanged: {
if(activeFocus) { if (activeFocus) {
lastTextSelected = '' lastTextSelected = '';
} } else
else mouseArea.keepLastSelection = false mouseArea.keepLastSelection = false;
// deselect() // deselect()
} }
MouseArea { MouseArea {
id: mouseArea id: mouseArea
property bool keepLastSelection: false property bool keepLastSelection: false
property int lastStartSelection:0 property int lastStartSelection: 0
property int lastEndSelection:0 property int lastEndSelection: 0
anchors.fill: parent anchors.fill: parent
propagateComposedEvents: true propagateComposedEvents: true
hoverEnabled: true hoverEnabled: true
scrollGestureEnabled: false scrollGestureEnabled: false
onContainsMouseChanged: { onContainsMouseChanged: {
if (containsMouse) UtilsCpp.setGlobalCursor(Qt.IBeamCursor) if (containsMouse)
else UtilsCpp.restoreGlobalCursor() UtilsCpp.setGlobalCursor(Qt.IBeamCursor);
else
UtilsCpp.restoreGlobalCursor();
} }
cursorShape: mainItem.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor cursorShape: mainItem.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onPressed: (mouse) => { onPressed: mouse => {
// if(!keepLastSelection) { // if(!keepLastSelection) {
// lastStartSelection = parent.selectionStart // lastStartSelection = parent.selectionStart
// lastEndSelection = parent.selectionEnd // lastEndSelection = parent.selectionEnd
// } // }
keepLastSelection = true keepLastSelection = true;
mouse.accepted = false mouse.accepted = false;
} }
} }
} }

View file

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

View file

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

View file

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

View file

@ -9,412 +9,398 @@ 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
Flickable { Flickable {
id: mainItem id: mainItem
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick
property bool showInitials: true // Display Initials of Display name. property bool showInitials: true // Display Initials of Display name.
property bool showActions: false // Display actions layout (call buttons) property bool showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts. property bool showContactMenu: true // Display the dot menu for contacts.
property bool showFavorites: true // Display the favorites in the header property bool showFavorites: true // Display the favorites in the header
property bool hideSuggestions: false // Hide not stored contacts (not suggestions) 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 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 string highlightText: searchText // Bold characters in Display name.
property var sourceFlags: LinphoneEnums.MagicSearchSource.All 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 selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected. property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts property list<string> selectedContacts
// List of default address on selected contacts. // List of default address on selected contacts.
//property FriendGui selectedContact//: model.getAt(currentIndex) || null //property FriendGui selectedContact//: model.getAt(currentIndex) || null
property FriendGui highlightedContact property FriendGui highlightedContact
property bool searchOnEmpty: true property bool searchOnEmpty: true
property bool loading: false property bool loading: false
property bool pauseSearch: false // true = don't search on text change property bool pauseSearch: false // true = don't search on text change
// Model properties // Model properties
// set searchBarText without specifying a model to bold // set searchBarText without specifying a model to bold
// matching names // matching names
property string searchBarText property string searchBarText
property string searchText property string searchText
// Binding is done on searchBarTextChanged // Binding is done on searchBarTextChanged
property ConferenceInfoGui confInfoGui property ConferenceInfoGui confInfoGui
property bool haveFavorites: false property bool haveFavorites: false
property bool haveContacts: count > 0 property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18) property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39) property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property int count: contactsList.count + suggestionsList.count + favoritesList.count property int count: contactsList.count + suggestionsList.count + favoritesList.count
contentHeight: contentsLayout.height contentHeight: contentsLayout.height
rightMargin: itemsRightMargin rightMargin: itemsRightMargin
signal contactStarredChanged signal contactStarredChanged
signal contactDeletionRequested(FriendGui contact) signal contactDeletionRequested(FriendGui contact)
signal contactAddedToSelection(string address) signal contactAddedToSelection(string address)
signal contactRemovedFromSelection(string address) signal contactRemovedFromSelection(string address)
signal contactSelected(FriendGui contact) signal contactSelected(FriendGui contact)
function selectContact(address) { function selectContact(address) {
var index = contactsProxy.loadUntil(address) // Be sure to have this address in proxy if it exists var index = contactsProxy.loadUntil(address); // Be sure to have this address in proxy if it exists
if (index != -1) { if (index != -1) {
contactsList.selectIndex(index) contactsList.selectIndex(index);
} }
return index return index;
} }
function addContactToSelection(address) { function addContactToSelection(address) {
if (multiSelectionEnabled) { if (multiSelectionEnabled) {
var indexInSelection = selectedContacts.indexOf(address) var indexInSelection = selectedContacts.indexOf(address);
if (indexInSelection == -1) { if (indexInSelection == -1) {
selectedContacts.push(address) selectedContacts.push(address);
contactAddedToSelection(address) contactAddedToSelection(address);
} }
} }
} }
function removeContactFromSelection(indexInSelection) { function removeContactFromSelection(indexInSelection) {
var addressToRemove = selectedContacts[indexInSelection] var addressToRemove = selectedContacts[indexInSelection];
if (indexInSelection != -1) { if (indexInSelection != -1) {
selectedContacts.splice(indexInSelection, 1) selectedContacts.splice(indexInSelection, 1);
contactRemovedFromSelection(addressToRemove) contactRemovedFromSelection(addressToRemove);
} }
} }
function removeSelectedContactByAddress(address) { function removeSelectedContactByAddress(address) {
var index = selectedContacts.indexOf(address) var index = selectedContacts.indexOf(address);
if (index != -1) { if (index != -1) {
selectedContacts.splice(index, 1) selectedContacts.splice(index, 1);
contactRemovedFromSelection(address) contactRemovedFromSelection(address);
} }
} }
function haveAddress(address) { function haveAddress(address) {
var index = magicSearchProxy.findFriendIndexByAddress(address) var index = magicSearchProxy.findFriendIndexByAddress(address);
return index != -1 return index != -1;
} }
function getFirstContact() { function getFirstContact() {
if (mainItem.showFavorites) { if (mainItem.showFavorites) {
var firstContact = favoritesList.itemAtIndex(0) var firstContact = favoritesList.itemAtIndex(0);
if (firstContact !== null) return firstContact if (firstContact !== null)
} return firstContact;
var firstContact = contactsList.itemAtIndex(0) }
if (firstContact !== null) return firstContact var firstContact = contactsList.itemAtIndex(0);
if (!mainItem.hideSuggestions) { if (firstContact !== null)
var firstContact = suggestionsList.itemAtIndex(0) return firstContact;
if (firstContact !== null) return firstContact if (!mainItem.hideSuggestions) {
} var firstContact = suggestionsList.itemAtIndex(0);
return null if (firstContact !== null)
} return firstContact;
}
return null;
}
function resetSelections() { function resetSelections() {
mainItem.highlightedContact = null mainItem.highlightedContact = null;
favoritesList.currentIndex = -1 favoritesList.currentIndex = -1;
contactsList.currentIndex = -1 contactsList.currentIndex = -1;
suggestionsList.currentIndex = -1 suggestionsList.currentIndex = -1;
} }
function findNextList(item, count, direction) { function findNextList(item, count, direction) {
if (count == 3) if (count == 3)
return null return null;
var nextItem var nextItem;
switch (item) { switch (item) {
case suggestionsList: case suggestionsList:
nextItem = (direction > 0 ? favoritesList : contactsList) nextItem = (direction > 0 ? favoritesList : contactsList);
break break;
case contactsList: case contactsList:
nextItem = (direction > 0 ? suggestionsList : favoritesList) nextItem = (direction > 0 ? suggestionsList : favoritesList);
break break;
case favoritesList: case favoritesList:
nextItem = (direction > 0 ? contactsList : suggestionsList) nextItem = (direction > 0 ? contactsList : suggestionsList);
break break;
default: default:
return null return null;
} }
if (nextItem.model.count > 0) if (nextItem.model.count > 0)
return nextItem return nextItem;
else else
return findNextList(nextItem, count + 1, direction) return findNextList(nextItem, count + 1, direction);
} }
function updatePosition(list) { function updatePosition(list) {
Utils.updatePosition(mainItem, list) Utils.updatePosition(mainItem, list);
} }
onHighlightedContactChanged: { onHighlightedContactChanged: {
favoritesList.highlightedContact = highlightedContact favoritesList.highlightedContact = highlightedContact;
contactsList.highlightedContact = highlightedContact contactsList.highlightedContact = highlightedContact;
suggestionsList.highlightedContact = highlightedContact suggestionsList.highlightedContact = highlightedContact;
} }
onSearchBarTextChanged: { onSearchBarTextChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) { if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText searchText = searchBarText.length === 0 ? "*" : searchBarText;
} }
} }
onPauseSearchChanged: { onPauseSearchChanged: {
if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) { if (!pauseSearch && (mainItem.searchOnEmpty || searchBarText != '')) {
searchText = searchBarText.length === 0 ? "*" : searchBarText searchText = searchBarText.length === 0 ? "*" : searchBarText;
} }
} }
onSearchTextChanged: { onSearchTextChanged: {
loading = true loading = true;
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (!event.accepted) { if (!event.accepted) {
if (event.key == Qt.Key_Up if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
|| event.key == Qt.Key_Down) { var newItem;
var newItem var direction = (event.key == Qt.Key_Up ? -1 : 1);
var direction = (event.key == Qt.Key_Up ? -1 : 1) if (suggestionsList.activeFocus)
if (suggestionsList.activeFocus) newItem = findNextList(suggestionsList, 0, direction);
newItem = findNextList(suggestionsList, 0, else if (contactsList.activeFocus)
direction) newItem = findNextList(contactsList, 0, direction);
else if (contactsList.activeFocus) else if (favoritesList.activeFocus)
newItem = findNextList(contactsList, 0, newItem = findNextList(favoritesList, 0, direction);
direction) else
else if (favoritesList.activeFocus) newItem = findNextList(suggestionsList, 0, direction);
newItem = findNextList(favoritesList, 0, if (newItem) {
direction) newItem.selectIndex(direction > 0 ? -1 : newItem.model.count - 1, direction > 0 ? Qt.BacktabFocusReason :
else Qt.TabFocusReason);
newItem = findNextList(suggestionsList, 0, event.accepted = true;
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));
} }
Component.onCompleted: { }
if (confInfoGui) { }
for (var i = 0; i < confInfoGui.core.participants.length; ++i) {
selectedContacts.push(
confInfoGui.core.getParticipantAddressAt(i))
}
}
}
Connections { Connections {
target: SettingsCpp target: SettingsCpp
onLdapConfigChanged: { onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts) if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
} }
property MagicSearchProxy mainModel: MagicSearchProxy { property MagicSearchProxy mainModel: MagicSearchProxy {
id: magicSearchProxy id: magicSearchProxy
searchText: mainItem.searchText searchText: mainItem.searchText
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
sourceFlags: mainItem.sourceFlags sourceFlags: mainItem.sourceFlags
onModelReset: { onModelReset: {
mainItem.resetSelections() mainItem.resetSelections();
} }
onResultsProcessed: { onResultsProcessed: {
mainItem.loading = false mainItem.loading = false;
mainItem.contentY = 0 mainItem.contentY = 0;
} }
onInitialized: { onInitialized: {
if (mainItem.searchOnEmpty || searchText != '') { if (mainItem.searchOnEmpty || searchText != '') {
mainItem.loading = true mainItem.loading = true;
forceUpdate() forceUpdate();
} }
} }
} }
onAtYEndChanged: if (atYEnd) { onAtYEndChanged: if (atYEnd) {
if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites) if (favoritesProxy.haveMore && favoritesList.expanded && mainItem.showFavorites)
favoritesProxy.displayMore() favoritesProxy.displayMore();
else if (contactsProxy.haveMore && contactsList.expanded) { else if (contactsProxy.haveMore && contactsList.expanded) {
contactsProxy.displayMore() contactsProxy.displayMore();
} } else
else suggestionsProxy.displayMore();
suggestionsProxy.displayMore() }
} Behavior on contentY {
Behavior on contentY { NumberAnimation {
NumberAnimation { duration: 500
duration: 500 easing.type: Easing.OutExpo
easing.type: Easing.OutExpo }
} }
}
Control.ScrollBar.vertical: ScrollBar { Control.ScrollBar.vertical: ScrollBar {
id: scrollbar id: scrollbar
z: 1 z: 1
topPadding: Utils.getSizeWithScreenRatio(24) // Avoid to be on top of collapse button topPadding: Utils.getSizeWithScreenRatio(24) // Avoid to be on top of collapse button
active: true active: true
interactive: true interactive: true
visible: mainItem.contentHeight > mainItem.height visible: mainItem.contentHeight > mainItem.height
policy: Control.ScrollBar.AsNeeded policy: Control.ScrollBar.AsNeeded
} }
ColumnLayout { ColumnLayout {
id: contentsLayout id: contentsLayout
width: mainItem.width width: mainItem.width
spacing: 0 spacing: 0
BusyIndicator { BusyIndicator {
id: busyIndicator id: busyIndicator
visible: mainItem.loading visible: mainItem.loading
width: mainItem.busyIndicatorSize width: mainItem.busyIndicatorSize
height: mainItem.busyIndicatorSize height: mainItem.busyIndicatorSize
Layout.preferredWidth: mainItem.busyIndicatorSize Layout.preferredWidth: mainItem.busyIndicatorSize
Layout.preferredHeight: mainItem.busyIndicatorSize Layout.preferredHeight: mainItem.busyIndicatorSize
Layout.alignment: Qt.AlignCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignCenter | Qt.AlignVCenter
} }
ContactListView { ContactListView {
id: favoritesList id: favoritesList
visible: contentHeight > 0 visible: contentHeight > 0
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: implicitHeight Layout.preferredHeight: implicitHeight
sectionsWeight: mainItem.sectionsWeight sectionsWeight: mainItem.sectionsWeight
sectionsPixelSize: mainItem.sectionsPixelSize sectionsPixelSize: mainItem.sectionsPixelSize
interactive: false interactive: false
highlightText: mainItem.highlightText highlightText: mainItem.highlightText
showActions: mainItem.showActions showActions: mainItem.showActions
showInitials: mainItem.showInitials showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu showContactMenu: mainItem.showContactMenu
showDefaultAddress: false showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
//: "Favoris" //: "Favoris"
title: qsTr("car_favorites_contacts_title") title: qsTr("car_favorites_contacts_title")
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(favoritesList) onUpdatePosition: mainItem.updatePosition(favoritesList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact) }
} onAddContactToSelection: address => {
onAddContactToSelection: address => { mainItem.addContactToSelection(address);
mainItem.addContactToSelection(address) }
} onRemoveContactFromSelection: index => {
onRemoveContactFromSelection: index => { mainItem.removeContactFromSelection(index);
mainItem.removeContactFromSelection( }
index)
}
property MagicSearchProxy proxy: MagicSearchProxy { property MagicSearchProxy proxy: MagicSearchProxy {
id: favoritesProxy id: favoritesProxy
parentProxy: mainItem.mainModel parentProxy: mainItem.mainModel
showMe: mainItem.showMe showMe: mainItem.showMe
filterType: MagicSearchProxy.FilteringTypes.Favorites filterType: MagicSearchProxy.FilteringTypes.Favorites
} }
model: mainItem.showFavorites model: mainItem.showFavorites && (mainItem.searchBarText == '' || mainItem.searchBarText == '*') ? proxy : []
&& (mainItem.searchBarText == '' }
|| mainItem.searchBarText == '*') ? proxy : []
}
ContactListView { ContactListView {
id: contactsList id: contactsList
visible: contentHeight > 0 visible: contentHeight > 0
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: implicitHeight Layout.preferredHeight: implicitHeight
Layout.topMargin: favoritesList.height > 0 ? Utils.getSizeWithScreenRatio(4) : 0 Layout.topMargin: favoritesList.height > 0 ? Utils.getSizeWithScreenRatio(4) : 0
interactive: false interactive: false
highlightText: mainItem.highlightText highlightText: mainItem.highlightText
showActions: mainItem.showActions showActions: mainItem.showActions
showInitials: mainItem.showInitials showInitials: mainItem.showInitials
showContactMenu: mainItem.showContactMenu showContactMenu: mainItem.showContactMenu
showDefaultAddress: false showDefaultAddress: false
selectionEnabled: mainItem.selectionEnabled selectionEnabled: mainItem.selectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
//: 'Contacts' //: 'Contacts'
title: qsTr("generic_address_picker_contacts_list_title") title: qsTr("generic_address_picker_contacts_list_title")
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(contactsList) onUpdatePosition: mainItem.updatePosition(contactsList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact) }
} onAddContactToSelection: address => {
onAddContactToSelection: address => { mainItem.addContactToSelection(address);
mainItem.addContactToSelection(address) }
} onRemoveContactFromSelection: index => {
onRemoveContactFromSelection: index => { mainItem.removeContactFromSelection(index);
mainItem.removeContactFromSelection( }
index)
}
model: MagicSearchProxy { model: MagicSearchProxy {
id: contactsProxy id: contactsProxy
parentProxy: mainItem.mainModel parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != ''
| (mainItem.searchText != '*' || SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap
&& mainItem.searchText != '' | MagicSearchProxy.FilteringTypes.CardDAV : 0)
|| SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap | MagicSearchProxy.FilteringTypes.CardDAV : 0) initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63)))
initialDisplayItems: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63))) displayItemsStep: 3 * initialDisplayItems / 2
displayItemsStep: 3 * initialDisplayItems / 2 onLocalFriendCreated: index => {
onLocalFriendCreated: (index) => { contactsList.selectIndex(index);
contactsList.selectIndex(index) }
} }
} }
} ContactListView {
ContactListView { id: suggestionsList
id: suggestionsList visible: contentHeight > 0
visible: contentHeight > 0 Layout.fillWidth: true
Layout.fillWidth: true Layout.preferredHeight: implicitHeight
Layout.preferredHeight: implicitHeight Layout.topMargin: (contactsList.height + favoritesList.height) > 0 ? Utils.getSizeWithScreenRatio(4) : 0
Layout.topMargin: (contactsList.height + favoritesList.height) > 0 ? Utils.getSizeWithScreenRatio(4) : 0 interactive: false
interactive: false showInitials: false
showInitials: false highlightText: mainItem.highlightText
highlightText: mainItem.highlightText showActions: mainItem.showActions
showActions: mainItem.showActions showContactMenu: mainItem.showContactMenu
showContactMenu: mainItem.showContactMenu showDefaultAddress: true
showDefaultAddress: true showDisplayName: false
showDisplayName: false selectionEnabled: mainItem.selectionEnabled
selectionEnabled: mainItem.selectionEnabled multiSelectionEnabled: mainItem.multiSelectionEnabled
multiSelectionEnabled: mainItem.multiSelectionEnabled selectedContacts: mainItem.selectedContacts
selectedContacts: mainItem.selectedContacts //: "Suggestions"
//: "Suggestions" title: qsTr("generic_address_picker_suggestions_list_title")
title: qsTr("generic_address_picker_suggestions_list_title") itemsRightMargin: mainItem.itemsRightMargin
itemsRightMargin: mainItem.itemsRightMargin
onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact onHighlightedContactChanged: mainItem.highlightedContact = highlightedContact
onContactSelected: contactGui => { onContactSelected: contactGui => {
mainItem.contactSelected(contactGui) mainItem.contactSelected(contactGui);
} }
onUpdatePosition: mainItem.updatePosition(suggestionsList) onUpdatePosition: mainItem.updatePosition(suggestionsList)
onContactDeletionRequested: contact => { onContactDeletionRequested: contact => {
mainItem.contactDeletionRequested( mainItem.contactDeletionRequested(contact);
contact) }
} onAddContactToSelection: address => {
onAddContactToSelection: address => { mainItem.addContactToSelection(address);
mainItem.addContactToSelection(address) }
} onRemoveContactFromSelection: index => {
onRemoveContactFromSelection: index => { mainItem.removeContactFromSelection(index);
mainItem.removeContactFromSelection( }
index) model: MagicSearchProxy {
} id: suggestionsProxy
model: MagicSearchProxy { parentProxy: mainItem.mainModel
id: suggestionsProxy filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other
parentProxy: mainItem.mainModel initialDisplayItems: contactsProxy.haveMore && contactsList.expanded ? 0 : Math.max(20, Math.round(2
filterType: mainItem.hideSuggestions ? MagicSearchProxy.FilteringTypes.None : MagicSearchProxy.FilteringTypes.Other * mainItem.height / Utils.getSizeWithScreenRatio(63)))
initialDisplayItems: contactsProxy.haveMore && contactsList.expanded onInitialDisplayItemsChanged: maxDisplayItems = initialDisplayItems
? 0 displayItemsStep: 3 * initialDisplayItems / 2
: Math.max(20, Math.round(2 * mainItem.height / Utils.getSizeWithScreenRatio(63))) onModelReset: maxDisplayItems = initialDisplayItems
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 // Fill contact, account or call
// Initials will be displayed if there isn't any avatar. // Initials will be displayed if there isn't any avatar.
// TODO : get FriendGui from Call. // TODO : get FriendGui from Call.
Loader{ Loader {
id: mainItem id: mainItem
property AccountGui account: null property AccountGui account: null
property FriendGui contact: null property FriendGui contact: null
property CallGui call: null property CallGui call: null
property bool isConference: false property bool isConference: false
property bool shadowEnabled: true property bool shadowEnabled: true
property var _address: account property var _address: account ? account.core?.identityAddress || "" : call ? call.core.remoteAddress : contact
? account.core?.identityAddress || "" ? contact.core.defaultAddress : ''
: call
? call.core.remoteAddress
: contact
? contact.core.defaultAddress
: ''
readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address readonly property var address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(_address) : _address
property var displayNameObj: UtilsCpp.getDisplayName(_address) property var displayNameObj: UtilsCpp.getDisplayName(_address)
property var displayNameVal: account && account.core.displayName property var displayNameVal: account && account.core.displayName ? account.core.displayName : contact && contact.core.fullName
? account.core.displayName ? contact.core.fullName : displayNameObj ? displayNameObj.value : ""
: contact && contact.core.fullName property bool haveAvatar: account ? account.core.pictureUri : contact ? contact.core.pictureUri :
? contact.core.fullName computedAvatarUri.length != 0
: displayNameObj
? displayNameObj.value
: ""
property bool haveAvatar: account
? account.core.pictureUri
: contact
? contact.core.pictureUri
: computedAvatarUri.length != 0
property var avatarObj: UtilsCpp.findAvatarByAddress(_address) property var avatarObj: UtilsCpp.findAvatarByAddress(_address)
property string computedAvatarUri: avatarObj ? avatarObj.value : '' property string computedAvatarUri: avatarObj ? avatarObj.value : ''
@ -51,17 +38,15 @@ Loader{
// override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified // override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address) property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp ? call.core.tokenVerified :
? call.core.tokenVerified contact ? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount
: contact === contact.core.devices.length : false
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
: false
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
property bool displayPresence: true property bool displayPresence: true
asynchronous: true asynchronous: true
sourceComponent: Component{ sourceComponent: Component {
Item { Item {
anchors.fill: parent anchors.fill: parent
@ -81,10 +66,11 @@ Loader{
initialItem: mainItem.haveAvatar ? avatar : initials initialItem: mainItem.haveAvatar ? avatar : initials
anchors.fill: parent anchors.fill: parent
Connections{ Connections {
target: mainItem target: mainItem
onHaveAvatarChanged: { onHaveAvatarChanged: {
stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate)} stackView.replace(mainItem.haveAvatar ? avatar : initials, StackView.Immediate);
}
} }
Rectangle { Rectangle {
@ -94,7 +80,7 @@ Loader{
z: 1 z: 1
color: "transparent" color: "transparent"
border { border {
width: Utils.getSizeWithScreenRatio(2) width: Utils.getSizeWithScreenRatio(2)
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500_main color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500_main
} }
EffectImage { EffectImage {
@ -104,28 +90,22 @@ Loader{
height: width height: width
imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted imageSource: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
} }
Image { Image {
visible: mainItem.displayPresence visible: mainItem.displayPresence
width: stackView.width/4.5 width: stackView.width / 4.5
height: width height: width
sourceSize.width: width sourceSize.width: width
sourceSize.height: width sourceSize.height: width
smooth: false smooth: false
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: stackView.width / 15 anchors.rightMargin: stackView.width / 15
z: 1 z: 1
source: account source: account ? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok ? account.core?.registrationIcon :
? (account.core?.registrationState !== LinphoneEnums.RegistrationState.Ok account.core?.presenceIcon) : (contact ? contact.core?.presenceIcon : "")
? account.core?.registrationIcon
: account.core?.presenceIcon)
: (contact
? contact.core?.presenceIcon
: "")
RotationAnimator on rotation { RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise direction: RotationAnimator.Clockwise
@ -135,10 +115,9 @@ Loader{
duration: 10000 duration: 10000
} }
} }
} }
Component{ Component {
id: initials id: initials
Item { Item {
id: avatarItem id: avatarItem
@ -146,7 +125,8 @@ Loader{
width: height width: height
Rectangle { Rectangle {
id: initialItem 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 radius: width / 2
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
height: stackView.height height: stackView.height
@ -167,7 +147,7 @@ Loader{
EffectImage { EffectImage {
id: initialImg id: initialImg
visible: initialItem.initials === "" || initialItem.initials[0] === "+" visible: initialItem.initials === "" || initialItem.initials[0] === "+"
width: stackView.width/2 width: stackView.width / 2
height: width height: width
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile imageSource: mainItem.isConference ? AppIcons.videoconference : AppIcons.profile
@ -188,7 +168,7 @@ Loader{
} }
} }
} }
Component{ Component {
id: avatar id: avatar
Item { Item {
id: avatarItem id: avatarItem
@ -204,11 +184,8 @@ Loader{
sourceSize.height: avatarItem.height sourceSize.height: avatarItem.height
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
anchors.centerIn: parent anchors.centerIn: parent
source: mainItem.account source: mainItem.account ? mainItem.account.core.pictureUri : mainItem.contact ? mainItem.contact.core.pictureUri :
? mainItem.account.core.pictureUri computedAvatarUri
: mainItem.contact
? mainItem.contact.core.pictureUri
: computedAvatarUri
mipmap: true mipmap: true
layer.enabled: true layer.enabled: true
} }

View file

@ -4,28 +4,27 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import CustomControls 1.0 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 import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.Control{ Control.Control {
id: mainItem id: mainItem
activeFocusOnTab: true activeFocusOnTab: true
padding: Utils.getSizeWithScreenRatio(10) padding: Utils.getSizeWithScreenRatio(10)
property AccountGui account property AccountGui account
leftPadding: Utils.getSizeWithScreenRatio(8) leftPadding: Utils.getSizeWithScreenRatio(8)
rightPadding: Utils.getSizeWithScreenRatio(8) rightPadding: Utils.getSizeWithScreenRatio(8)
property var style property var style
property bool isSelected property bool isSelected
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties // 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 hoveredBackgroundColor: style?.color?.hovered ?? defaultBackgroundColor
readonly property color selectedBackgroundColor: style?.color?.selected ?? defaultBackgroundColor readonly property color selectedBackgroundColor: style?.color?.selected ?? defaultBackgroundColor
readonly property color focusedBackgroundColor: style?.color?.keybaordFocused ?? defaultBackgroundColor readonly property color focusedBackgroundColor: style?.color?.keybaordFocused ?? defaultBackgroundColor
@ -37,42 +36,45 @@ Control.Control{
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
signal avatarClicked() signal avatarClicked
signal backgroundClicked() signal backgroundClicked
signal edit() signal edit
background: Rectangle { background: Rectangle {
radius: Utils.getSizeWithScreenRatio(10) radius: Utils.getSizeWithScreenRatio(10)
color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor : mainItem.defaultBackgroundColor color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor :
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected ? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor 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 border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
MouseArea{ MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
onClicked: mainItem.backgroundClicked() onClicked: mainItem.backgroundClicked()
} }
} }
contentItem: RowLayout{ contentItem: RowLayout {
spacing: 0 spacing: 0
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Button { Button {
id: avatarButton id: avatarButton
onClicked: mainItem.avatarClicked() onClicked: mainItem.avatarClicked()
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
color: "transparent" color: "transparent"
contentItem: Item{ contentItem: Item {
anchors.fill: parent anchors.fill: parent
width: avatarButton.width width: avatarButton.width
height: avatarButton.height height: avatarButton.height
Avatar{ Avatar {
id: avatar id: avatar
height: avatarButton.height height: avatarButton.height
width: avatarButton.width width: avatarButton.width
account: mainItem.account account: mainItem.account
} }
Rectangle{ Rectangle {
// Black border for keyboard navigation // Black border for keyboard navigation
visible: avatarButton.keyboardFocus visible: avatarButton.keyboardFocus
width: avatarButton.width width: avatarButton.width
@ -85,10 +87,10 @@ Control.Control{
} }
} }
Item { Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(200) Layout.preferredWidth: Utils.getSizeWithScreenRatio(200)
Layout.fillHeight: true Layout.fillHeight: true
Layout.rightMargin: Utils.getSizeWithScreenRatio(10) Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
ContactDescription{ ContactDescription {
id: description id: description
anchors.fill: parent anchors.fill: parent
account: mainItem.account account: mainItem.account
@ -97,10 +99,10 @@ Control.Control{
} }
Item { Item {
Layout.minimumWidth: Utils.getSizeWithScreenRatio(86) Layout.minimumWidth: Utils.getSizeWithScreenRatio(86)
Layout.maximumWidth: Utils.getSizeWithScreenRatio(150) Layout.maximumWidth: Utils.getSizeWithScreenRatio(150)
width: contactStatusPopup.width width: contactStatusPopup.width
height: contactStatusPopup.height height: contactStatusPopup.height
ContactStatusPopup{ ContactStatusPopup {
id: contactStatusPopup id: contactStatusPopup
visible: mainItem.account.core.publishEnabled visible: mainItem.account.core.publishEnabled
} }
@ -111,32 +113,32 @@ Control.Control{
onClicked: mainItem.account.core.lSetRegisterEnabled(true) onClicked: mainItem.account.core.lSetRegisterEnabled(true)
} }
} }
Item{ Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(26) Layout.preferredWidth: Utils.getSizeWithScreenRatio(26)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26) Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin: Utils.getSizeWithScreenRatio(40) Layout.leftMargin: Utils.getSizeWithScreenRatio(40)
visible: mainItem.account.core.unreadNotifications > 0 visible: mainItem.account.core.unreadNotifications > 0
Rectangle{ Rectangle {
id: unreadNotifications id: unreadNotifications
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: Utils.getSizeWithScreenRatio(26) width: Utils.getSizeWithScreenRatio(26)
height: Utils.getSizeWithScreenRatio(26) height: Utils.getSizeWithScreenRatio(26)
radius: width/2 radius: width / 2
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
border.color: DefaultStyle.grey_0 border.color: DefaultStyle.grey_0
border.width: Utils.getSizeWithScreenRatio(2) border.width: Utils.getSizeWithScreenRatio(2)
Text{ Text {
id: unreadCount id: unreadCount
anchors.fill: parent anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2) anchors.margins: Utils.getSizeWithScreenRatio(2)
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
minimumPixelSize: 5 minimumPixelSize: 5
fontSizeMode: Text.Fit fontSizeMode: Text.Fit
font.pixelSize: Utils.getSizeWithScreenRatio(11) font.pixelSize: Utils.getSizeWithScreenRatio(11)
font.weight: Utils.getSizeWithScreenRatio(700) font.weight: Utils.getSizeWithScreenRatio(700)
text: mainItem.account.core.unreadNotifications >= 100 ? '99+' : mainItem.account.core.unreadNotifications text: mainItem.account.core.unreadNotifications >= 100 ? '99+' : mainItem.account.core.unreadNotifications
} }
} }
@ -149,38 +151,40 @@ Control.Control{
} }
} }
Voicemail { Voicemail {
Layout.leftMargin: Utils.getSizeWithScreenRatio(18) Layout.leftMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Utils.getSizeWithScreenRatio(20) Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(26) Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
scaleFactor: 0.7 scaleFactor: 0.7
showMwi: mainItem.account.core.showMwi showMwi: mainItem.account.core.showMwi
visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi
voicemailCount: mainItem.account.core.voicemailCount voicemailCount: mainItem.account.core.voicemailCount
onClicked: { onClicked: {
if (mainItem.account.core.voicemailAddress.length > 0) if (mainItem.account.core.voicemailAddress.length > 0)
UtilsCpp.createCall(mainItem.account.core.voicemailAddress) UtilsCpp.createCall(mainItem.account.core.voicemailAddress);
else else
//: Erreur //: Erreur
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: L'URI de messagerie vocale n'est pas définie. //: L'URI de messagerie vocale n'est pas définie.
qsTr("information_popup_voicemail_address_undefined_message"), false) qsTr("information_popup_voicemail_address_undefined_message"), false);
} }
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
Button { Button {
id: manageAccount id: manageAccount
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.manageProfile icon.source: AppIcons.manageProfile
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
visible: !SettingsCpp.hideAccountSettings visible: !SettingsCpp.hideAccountSettings
//: Account settings of %1 //: Account settings of %1
Accessible.name: qsTr("account_settings_name_accessible_name") Accessible.name: qsTr("account_settings_name_accessible_name")
onClicked: { 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope { FocusScope {
id: mainItem id: mainItem
implicitHeight: visible ? Utils.getSizeWithScreenRatio(56) : 0 implicitHeight: visible ? Utils.getSizeWithScreenRatio(56) : 0
property var searchResultItem property var searchResultItem
property bool showInitials: true // Display Initials of Display name. property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below 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 showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts. property bool showContactMenu: true // Display the dot menu for contacts.
property string highlightText property string highlightText
property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText, searchResultItem.core.defaultAddress) property string addressFromFilter: UtilsCpp.getAddressToDisplay(searchResultItem.core.addresses, highlightText,
searchResultItem.core.defaultAddress)
// Bold characters in Display name. // Bold characters in Display name.
property bool displayNameCapitalization: true // Capitalize display name. property bool displayNameCapitalization: true // Capitalize display name.
property bool selectionEnabled: true // Contact can be selected property bool selectionEnabled: true // Contact can be selected
property bool multiSelectionEnabled: false //Multiple items can be selected. property bool multiSelectionEnabled: false //Multiple items can be selected.
property list<string> selectedContacts property list<string> selectedContacts
// List of default address on selected contacts. // List of default address on selected contacts.
property bool isSelected: false // selected in list => currentIndex == index property bool isSelected: false // selected in list => currentIndex == index
property bool isLastHovered: false property bool isLastHovered: false
property var previousInitial property var previousInitial
// Use directly previous initial // Use directly previous initial
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39) property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property var displayName: searchResultItem? searchResultItem.core.fullName : "" property var displayName: searchResultItem ? searchResultItem.core.fullName : ""
property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) : '' property var initial: displayName.length > 0 ? UtilsCpp.getInitials(displayName, 1).toLocaleLowerCase(AppCpp.localeAsString) :
''
signal clicked(var mouse) signal clicked(var mouse)
signal contactDeletionRequested(FriendGui contact) signal contactDeletionRequested(FriendGui contact)
signal containsMouseChanged(bool containsMouse) signal containsMouseChanged(bool containsMouse)
Accessible.name: displayName Accessible.name: displayName
MouseArea { MouseArea {
Text { id: contactArea
id: initialText Text {
anchors.left: parent.left id: initialText
visible: mainItem.showInitials anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter visible: mainItem.showInitials
anchors.rightMargin: Utils.getSizeWithScreenRatio(15) anchors.verticalCenter: parent.verticalCenter
verticalAlignment: Text.AlignVCenter anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
width: Utils.getSizeWithScreenRatio(20) verticalAlignment: Text.AlignVCenter
opacity: previousInitial != mainItem.initial ? 1 : 0 width: Utils.getSizeWithScreenRatio(20)
text: mainItem.initial opacity: previousInitial != mainItem.initial ? 1 : 0
textFormat: Text.RichText text: mainItem.initial
color: DefaultStyle.main2_400 textFormat: Text.RichText
font { color: DefaultStyle.main2_400
pixelSize: Utils.getSizeWithScreenRatio(20) font {
weight: Utils.getSizeWithScreenRatio(500) pixelSize: Utils.getSizeWithScreenRatio(20)
capitalization: Font.AllUppercase weight: Utils.getSizeWithScreenRatio(500)
} capitalization: Font.AllUppercase
} }
RowLayout { }
id: contactDelegate RowLayout {
anchors.left: initialText.visible ? initialText.right : parent.left id: contactDelegate
anchors.right: parent.right anchors.left: initialText.visible ? initialText.right : parent.left
anchors.rightMargin: mainItem.itemsRightMargin anchors.right: parent.right
anchors.top: parent.top anchors.rightMargin: mainItem.itemsRightMargin
anchors.bottom: parent.bottom anchors.top: parent.top
spacing: Utils.getSizeWithScreenRatio(16) anchors.bottom: parent.bottom
z: contactArea.z + 1 spacing: Utils.getSizeWithScreenRatio(16)
Avatar { z: contactArea.z + 1
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Avatar {
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.leftMargin: Utils.getSizeWithScreenRatio(5) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
contact: searchResultItem Layout.leftMargin: Utils.getSizeWithScreenRatio(5)
shadowEnabled: false contact: searchResultItem
} shadowEnabled: false
ColumnLayout { }
spacing: 0 ColumnLayout {
Text { spacing: 0
id: displayNameText Text {
visible: mainItem.showDisplayName id: displayNameText
Layout.fillWidth: true visible: mainItem.showDisplayName
Layout.preferredHeight: visible ? implicitHeight: 0 Layout.fillWidth: true
text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)), Layout.preferredHeight: visible ? implicitHeight : 0
mainItem.highlightText) text: UtilsCpp.boldTextPart(UtilsCpp.encodeEmojiToQmlRichFormat((mainItem.displayName)), mainItem.highlightText)
textFormat: Text.RichText textFormat: Text.RichText
font { font {
pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize pixelSize: mainItem.showDefaultAddress ? Typography.h4.pixelSize : Typography.p1.pixelSize
capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
weight: mainItem.showDefaultAddress ? Typography.h4.weight : Typography.p1.weight weight: mainItem.showDefaultAddress ? Typography.h4.weight : Typography.p1.weight
} }
maximumLineCount: 1 maximumLineCount: 1
} }
Text { Text {
Layout.topMargin: Utils.getSizeWithScreenRatio(2) Layout.topMargin: Utils.getSizeWithScreenRatio(2)
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: visible ? implicitHeight: 0 Layout.preferredHeight: visible ? implicitHeight : 0
visible: mainItem.showDefaultAddress visible: mainItem.showDefaultAddress
property string address: SettingsCpp.hideSipAddresses property string address: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(mainItem.addressFromFilter) :
? UtilsCpp.getUsername(mainItem.addressFromFilter) mainItem.addressFromFilter
: mainItem.addressFromFilter text: UtilsCpp.boldTextPart(address, mainItem.highlightText)
text: UtilsCpp.boldTextPart(address, mainItem.highlightText) textFormat: Text.AutoText
textFormat: Text.AutoText maximumLineCount: 1
maximumLineCount: 1 elide: Text.ElideRight
elide: Text.ElideRight font {
font { weight: Utils.getSizeWithScreenRatio(300)
weight: Utils.getSizeWithScreenRatio(300) pixelSize: Utils.getSizeWithScreenRatio(12)
pixelSize: Utils.getSizeWithScreenRatio(12) }
} }
} }
} Item {
Item { Layout.fillWidth: true
Layout.fillWidth: true }
} RowLayout {
RowLayout { id: actionsRow
id: actionsRow z: contactArea.z + 1
z: contactArea.z + 1 visible: mainItem.showActions || actionButtons.visible || mainItem.showContactMenu || mainItem.multiSelectionEnabled
visible: mainItem.showActions || actionButtons.visible || mainItem.showContactMenu || mainItem.multiSelectionEnabled spacing: visible ? Utils.getSizeWithScreenRatio(16) : 0
spacing: visible ? Utils.getSizeWithScreenRatio(16) : 0 enabled: visible
enabled: visible Layout.rightMargin: Utils.getSizeWithScreenRatio(5)
Layout.rightMargin: Utils.getSizeWithScreenRatio(5) EffectImage {
EffectImage { id: isSelectedCheck
id: isSelectedCheck visible: mainItem.multiSelectionEnabled && (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1)
visible: mainItem.multiSelectionEnabled Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
&& (mainItem.selectedContacts.indexOf(mainItem.addressFromFilter) != -1) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(24) imageSource: AppIcons.check
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24) colorizationColor: DefaultStyle.main1_500_main
imageSource: AppIcons.check }
colorizationColor: DefaultStyle.main1_500_main RowLayout {
} id: actionButtons
RowLayout { visible: mainItem.showActions
id: actionButtons spacing: visible ? Utils.getSizeWithScreenRatio(10) : 0
visible: mainItem.showActions IconButton {
spacing: visible ? Utils.getSizeWithScreenRatio(10) : 0 id: callButton
IconButton { Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
id: callButton Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) icon.width: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) icon.height: Utils.getSizeWithScreenRatio(24)
icon.width: Utils.getSizeWithScreenRatio(24) icon.source: AppIcons.phone
icon.height: Utils.getSizeWithScreenRatio(24) focus: visible
icon.source: AppIcons.phone radius: Utils.getSizeWithScreenRatio(40)
focus: visible style: ButtonStyle.grey
radius: Utils.getSizeWithScreenRatio(40) onClicked: UtilsCpp.createCall(mainItem.addressFromFilter)
style: ButtonStyle.grey KeyNavigation.left: chatButton
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter) KeyNavigation.right: videoCallButton
KeyNavigation.left: chatButton //: "Call %1"
KeyNavigation.right: videoCallButton Accessible.name: qsTr("call_with_contact_name_accessible_button").arg(mainItem.displayName)
//: "Call %1" keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
Accessible.name: qsTr("call_with_contact_name_accessible_button").arg(mainItem.displayName) }
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus IconButton {
} id: videoCallButton
IconButton { visible: SettingsCpp.videoEnabled
id: videoCallButton Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
visible: SettingsCpp.videoEnabled Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) icon.width: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) icon.height: Utils.getSizeWithScreenRatio(24)
icon.width: Utils.getSizeWithScreenRatio(24) icon.source: AppIcons.videoCamera
icon.height: Utils.getSizeWithScreenRatio(24) focus: visible && !callButton.visible
icon.source: AppIcons.videoCamera radius: Utils.getSizeWithScreenRatio(40)
focus: visible && !callButton.visible style: ButtonStyle.grey
radius: Utils.getSizeWithScreenRatio(40) onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {
style: ButtonStyle.grey "localVideoEnabled": true
onClicked: UtilsCpp.createCall(mainItem.addressFromFilter, {"localVideoEnabled": true}) })
KeyNavigation.left: callButton KeyNavigation.left: callButton
KeyNavigation.right: chatButton KeyNavigation.right: chatButton
//: "Video call %1" //: "Video call %1"
Accessible.name: qsTr("video_call_with_contact_name_accessible_button").arg(mainItem.displayName) Accessible.name: qsTr("video_call_with_contact_name_accessible_button").arg(mainItem.displayName)
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
} }
IconButton { IconButton {
id: chatButton id: chatButton
visible: actionButtons.visible visible: actionButtons.visible && !SettingsCpp.disableChatFeature
&& !SettingsCpp.disableChatFeature Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) icon.width: Utils.getSizeWithScreenRatio(24)
icon.width: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.source: AppIcons.chatTeardropText
icon.source: AppIcons.chatTeardropText focus: visible && !callButton.visible && !videoCallButton.visible
focus: visible && !callButton.visible radius: Utils.getSizeWithScreenRatio(40)
&& !videoCallButton.visible style: ButtonStyle.grey
radius: Utils.getSizeWithScreenRatio(40) KeyNavigation.left: videoCallButton
style: ButtonStyle.grey KeyNavigation.right: callButton
KeyNavigation.left: videoCallButton onClicked: {
KeyNavigation.right: callButton console.debug("[ContactListItem.qml] Open conversation");
onClicked: { mainWindow.displayChatPage(mainItem.addressFromFilter);
console.debug("[ContactListItem.qml] Open conversation") }
mainWindow.displayChatPage(mainItem.addressFromFilter) //: "Message %1"
} Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName)
//: "Message %1" keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
Accessible.name: qsTr("message_with_contact_name_accessible_button").arg(mainItem.displayName) }
keyboardFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus }
} PopupButton {
} id: friendPopup
PopupButton { z: contactArea.z + 1
id: friendPopup popup.x: 0
z: contactArea.z + 1 popup.padding: Utils.getSizeWithScreenRatio(10)
popup.x: 0 visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered
popup.padding: Utils.getSizeWithScreenRatio(10) || popup.opened)
visible: mainItem.showContactMenu && (contactArea.containsMouse || mainItem.isLastHovered || hovered || popup.opened) enabled: visible
enabled: visible
popup.contentItem: ColumnLayout { popup.contentItem: ColumnLayout {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
visible: searchResultItem && searchResultItem.core.isStored visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
&& !searchResultItem.core.readOnly //: "Enlever des favoris"
//: "Enlever des favoris" text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") :
text: searchResultItem.core.starred ? qsTr("contact_details_remove_from_favourites") //: "Ajouter aux favoris"
//: "Ajouter aux favoris" qsTr("contact_details_add_to_favourites")
: qsTr("contact_details_add_to_favourites") icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart spacing: Utils.getSizeWithScreenRatio(10)
spacing: Utils.getSizeWithScreenRatio(10) textColor: DefaultStyle.main2_500_main
textColor: DefaultStyle.main2_500_main hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700
hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700 contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600 onClicked: {
onClicked: { searchResultItem.core.lSetStarred(!searchResultItem.core.starred);
searchResultItem.core.lSetStarred( friendPopup.close();
!searchResultItem.core.starred) }
friendPopup.close() style: ButtonStyle.noBackground
} }
style: ButtonStyle.noBackground IconLabelButton {
} text: qsTr("Partager")
IconLabelButton { Layout.fillWidth: true
text: qsTr("Partager") icon.source: AppIcons.shareNetwork
Layout.fillWidth: true spacing: Utils.getSizeWithScreenRatio(10)
icon.source: AppIcons.shareNetwork textColor: DefaultStyle.main2_500_main
spacing: Utils.getSizeWithScreenRatio(10) onClicked: {
textColor: DefaultStyle.main2_500_main var vcard = searchResultItem.core.getVCard();
onClicked: { var username = searchResultItem.core.givenName + searchResultItem.core.familyName;
var vcard = searchResultItem.core.getVCard() var filepath = UtilsCpp.createVCardFile(username, vcard);
var username = searchResultItem.core.givenName if (filepath == "")
+ searchResultItem.core.familyName UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
var filepath = UtilsCpp.createVCardFile( //: La création du fichier vcard a échoué
username, vcard) qsTr("information_popup_vcard_creation_error"), false);
if (filepath == "") else
UtilsCpp.showInformationPopup( //: VCard créée
qsTr("information_popup_error_title"), mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"),
//: La création du fichier vcard a échoué //: "VCard du contact enregistrée dans %1"
qsTr("information_popup_vcard_creation_error"), qsTr("information_popup_vcard_creation_success").arg(filepath));
false) //: Partage de contact
else UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"), vcard, filepath);
//: VCard créée }
mainWindow.showInformationPopup(qsTr("information_popup_vcard_creation_title"), style: ButtonStyle.noBackground
//: "VCard du contact enregistrée dans %1" }
qsTr("information_popup_vcard_creation_success").arg(filepath)) IconLabelButton {
//: Partage de contact //: "Supprimer"
UtilsCpp.shareByEmail(qsTr("contact_sharing_email_title"),vcard, filepath) text: qsTr("contact_details_delete")
} icon.source: AppIcons.trashCan
style: ButtonStyle.noBackground spacing: Utils.getSizeWithScreenRatio(10)
} visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly
IconLabelButton { Layout.fillWidth: true
//: "Supprimer" onClicked: {
text: qsTr("contact_details_delete") mainItem.contactDeletionRequested(searchResultItem);
icon.source: AppIcons.trashCan friendPopup.close();
spacing: Utils.getSizeWithScreenRatio(10) }
visible: searchResultItem && searchResultItem.core.isStored && !searchResultItem.core.readOnly style: ButtonStyle.noBackgroundRed
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: {
id: contactArea mainItem.containsMouseChanged(containsMouse);
enabled: mainItem.selectionEnabled }
anchors.fill: parent Rectangle {
//height: mainItem.height anchors.fill: contactArea
hoverEnabled: true radius: Utils.getSizeWithScreenRatio(8)
acceptedButtons: Qt.AllButtons opacity: 0.7
focus: !actionButtons.visible color: mainItem.isSelected ? DefaultStyle.main2_200 : DefaultStyle.main2_100
onContainsMouseChanged: { visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered
mainItem.containsMouseChanged(containsMouse) }
} Keys.onPressed: event => {
Rectangle { if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
anchors.fill: contactArea contactArea.clicked(undefined);
radius: Utils.getSizeWithScreenRatio(8) event.accepted = true;
opacity: 0.7 }
color: mainItem.isSelected ? DefaultStyle.main2_200 : DefaultStyle.main2_100 }
visible: mainItem.isLastHovered || mainItem.isSelected || friendPopup.hovered onClicked: mouse => {
} forceActiveFocus();
Keys.onPressed: event => { if (mouse && mouse.button == Qt.RightButton && mainItem.showContactMenu) {
if (event.key == Qt.Key_Space if (friendPopup)
|| event.key == Qt.Key_Enter friendPopup.open();
|| event.key == Qt.Key_Return) { } else {
contactArea.clicked(undefined) mainItem.clicked(mouse);
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 UtilsCpp 1.0
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import SettingsCpp 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 import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ListView { ListView {
id: mainItem id: mainItem
@ -15,7 +15,7 @@ ListView {
property string title property string title
property bool showInitials: true // Display Initials of Display name. property bool showInitials: true // Display Initials of Display name.
property bool showDefaultAddress: true // Display address below 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 showActions: false // Display actions layout (call buttons)
property bool showContactMenu: true // Display the dot menu for contacts. property bool showContactMenu: true // Display the dot menu for contacts.
property bool showFavorites: true // Display the favorites in the header property bool showFavorites: true // Display the favorites in the header
@ -38,27 +38,28 @@ ListView {
property bool haveFavorites: false property bool haveFavorites: false
property bool haveContacts: count > 0 property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Utils.getSizeWithScreenRatio(18) property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real itemsRightMargin: Utils.getSizeWithScreenRatio(39) property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property bool expanded: true property bool expanded: true
property real headerHeight: headerItem?.height property real headerHeight: headerItem?.height
signal contactDeletionRequested(FriendGui contact) signal contactDeletionRequested(FriendGui contact)
signal contactSelected(FriendGui contact) // Click/Space/Enter signal contactSelected(FriendGui contact) // Click/Space/Enter
signal addContactToSelection(var address) signal addContactToSelection(var address)
signal removeContactFromSelection(var indexInSelection) signal removeContactFromSelection(var indexInSelection)
signal updatePosition() signal updatePosition
clip: true clip: true
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
cacheBuffer: 400 cacheBuffer: 400
implicitHeight: contentHeight 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() onYChanged: updatePosition()
@ -68,49 +69,52 @@ ListView {
property bool _moveToIndex: false property bool _moveToIndex: false
function selectIndex(index, focusReason = Qt.OtherFocusReason){ function selectIndex(index, focusReason = Qt.OtherFocusReason) {
if(mainItem.expanded && index >= 0){ if (mainItem.expanded && index >= 0) {
mainItem.currentIndex = index mainItem.currentIndex = index;
var item = itemAtIndex(mainItem.currentIndex) var item = itemAtIndex(mainItem.currentIndex);
if(item){// Item is ready and available if (item) {
mainItem.highlightedContact = item.searchResultItem // Item is ready and available
item.forceActiveFocus(focusReason) mainItem.highlightedContact = item.searchResultItem;
updatePosition() item.forceActiveFocus(focusReason);
_moveToIndex = false updatePosition();
}else{// Move on the next items load. _moveToIndex = false;
} else {
// Move on the next items load.
// If visible, try to wait loading // If visible, try to wait loading
_moveToIndex = visible _moveToIndex = visible;
} }
}else{ } else {
mainItem.currentIndex = -1 mainItem.currentIndex = -1;
mainItem.highlightedContact = null mainItem.highlightedContact = null;
if(headerItem) { if (headerItem) {
headerItem.forceActiveFocus(focusReason) headerItem.forceActiveFocus(focusReason);
} }
_moveToIndex = false _moveToIndex = false;
} }
} }
onContactSelected: updatePosition() onContactSelected: updatePosition()
onExpandedChanged: if(!expanded) updatePosition() onExpandedChanged: if (!expanded)
updatePosition()
keyNavigationEnabled: false keyNavigationEnabled: false
Keys.onPressed: (event)=> { Keys.onPressed: event => {
if(event.key == Qt.Key_Up || event.key == Qt.Key_Down){ if (event.key == Qt.Key_Up || event.key == Qt.Key_Down) {
if(event.key == Qt.Key_Up && !headerItem.activeFocus) { if (event.key == Qt.Key_Up && !headerItem.activeFocus) {
if(currentIndex >= 0 ) { if (currentIndex >= 0) {
selectIndex(mainItem.currentIndex-1, Qt.BacktabFocusReason) selectIndex(mainItem.currentIndex - 1, Qt.BacktabFocusReason);
event.accepted = true; event.accepted = true;
} }
}else if(event.key == Qt.Key_Down && mainItem.expanded){ } else if (event.key == Qt.Key_Down && mainItem.expanded) {
if(currentIndex < model.count - 1) { if (currentIndex < model.count - 1) {
selectIndex(mainItem.currentIndex+1, Qt.TabFocusReason) selectIndex(mainItem.currentIndex + 1, Qt.TabFocusReason);
event.accepted = true; event.accepted = true;
} }
} }
} }
} }
Component.onCompleted: { Component.onCompleted: {
if (confInfoGui) { 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)); selectedContacts.push(confInfoGui.core.getParticipantAddressAt(i));
} }
} }
@ -120,29 +124,30 @@ ListView {
target: SettingsCpp target: SettingsCpp
function onLdapConfigChanged() { function onLdapConfigChanged() {
if (SettingsCpp.syncLdapContacts) if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
function onCardDAVAddressBookSynchronized() { function onCardDAVAddressBookSynchronized() {
console.log("card dav synchro update") console.log("card dav synchro update");
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate();
} }
} }
// Workaround: itemAtIndex and count are decorellated and are not enough to know when the ListView has load all its children. // 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. // So when itemAtIndex is not available, start this timer along count changed signal.
Timer{ Timer {
id: delaySelection id: delaySelection
interval: 100 interval: 100
running: _moveToIndex running: _moveToIndex
onTriggered: { onTriggered: {
_moveToIndex = false _moveToIndex = false;
if(count > mainItem.currentIndex) selectIndex(mainItem.currentIndex) if (count > mainItem.currentIndex)
else{ selectIndex(mainItem.currentIndex);
_moveToIndex = true else {
_moveToIndex = true;
} }
} }
} }
header: FocusScope{ header: FocusScope {
id: headerItem id: headerItem
width: mainItem.width width: mainItem.width
height: headerContents.implicitHeight height: headerContents.implicitHeight
@ -151,10 +156,11 @@ ListView {
id: headerContents id: headerContents
width: parent.width width: parent.width
spacing: 0 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.fillWidth: true
Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0 Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0
Layout.bottomMargin: Utils.getSizeWithScreenRatio(4) Layout.bottomMargin: Utils.getSizeWithScreenRatio(4)
RowLayout { RowLayout {
id: headerTitleLayout id: headerTitleLayout
anchors.fill: parent anchors.fill: parent
@ -175,28 +181,28 @@ ListView {
id: headerExpandButton id: headerExpandButton
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: mainItem.expanded ? AppIcons.upArrow : AppIcons.downArrow icon.source: mainItem.expanded ? AppIcons.upArrow : AppIcons.downArrow
Layout.rightMargin: mainItem.itemsRightMargin Layout.rightMargin: mainItem.itemsRightMargin
focus: true focus: true
onClicked: mainItem.expanded = !mainItem.expanded onClicked: mainItem.expanded = !mainItem.expanded
Rectangle { Rectangle {
anchors.fill: headerExpandButton anchors.fill: headerExpandButton
radius: headerExpandButton.width/2 radius: headerExpandButton.width / 2
visible: headerExpandButton.activeFocus visible: headerExpandButton.activeFocus
opacity: 0.5 opacity: 0.5
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
} }
Accessible.name: (mainItem.expanded ? Accessible.name: (mainItem.expanded ?
//: Shrink %1 //: Shrink %1
qsTr("shrink_accessible_name") : qsTr("shrink_accessible_name") :
//: Expand %1 //: Expand %1
qsTr("expand_accessible_name")).arg(mainItem.title) qsTr("expand_accessible_name")).arg(mainItem.title)
} }
} }
} }
} }
} }
delegate: ContactListItem{ delegate: ContactListItem {
id: contactItem id: contactItem
width: mainItem.width width: mainItem.width
focus: true focus: true
@ -215,35 +221,35 @@ ListView {
selectedContacts: mainItem.selectedContacts selectedContacts: mainItem.selectedContacts
isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core isSelected: mainItem.highlightedContact && mainItem.highlightedContact.core == searchResultItem.core
isLastHovered: mainItem.lastMouseContainsIndex == index isLastHovered: mainItem.lastMouseContainsIndex == index
previousInitial: mainItem.itemAtIndex(index-1)?.initial previousInitial: mainItem.itemAtIndex(index - 1)?.initial
itemsRightMargin: mainItem.itemsRightMargin itemsRightMargin: mainItem.itemsRightMargin
onIsSelectedChanged: if(isSelected) mainItem.currentIndex = index onIsSelectedChanged: if (isSelected)
onContactDeletionRequested: (contact) => mainItem.contactDeletionRequested(contact) mainItem.currentIndex = index
onContactDeletionRequested: contact => mainItem.contactDeletionRequested(contact)
onClicked: (mouse) => { onClicked: mouse => {
if (mouse && mouse.button == Qt.RightButton) { if (mouse && mouse.button == Qt.RightButton) {
friendPopup.open() friendPopup.open();
} else { } else {
forceActiveFocus() forceActiveFocus();
mainItem.highlightedContact = contactItem.searchResultItem mainItem.highlightedContact = contactItem.searchResultItem;
if (mainItem.multiSelectionEnabled) { if (mainItem.multiSelectionEnabled) {
var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress) var indexInSelection = mainItem.selectedContacts.indexOf(searchResultItem.core.defaultAddress);
if (indexInSelection == -1) { if (indexInSelection == -1) {
mainItem.addContactToSelection(searchResultItem.core.defaultAddress) mainItem.addContactToSelection(searchResultItem.core.defaultAddress);
} } else {
else { mainItem.removeContactFromSelection(indexInSelection);
mainItem.removeContactFromSelection(indexInSelection) }
} }
} mainItem.contactSelected(searchResultItem);
mainItem.contactSelected(searchResultItem) }
} }
} onContainsMouseChanged: containsMouse => {
onContainsMouseChanged: (containsMouse) => { if (containsMouse)
if(containsMouse) mainItem.lastMouseContainsIndex = index;
mainItem.lastMouseContainsIndex = index else if (mainItem.lastMouseContainsIndex == index)
else if( mainItem.lastMouseContainsIndex == index) mainItem.lastMouseContainsIndex = -1;
mainItem.lastMouseContainsIndex = -1 }
}
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,5 +6,5 @@ Flickable {
contentWidth: contentItem.childrenRect.width contentWidth: contentItem.childrenRect.width
contentHeight: contentItem.childrenRect.height contentHeight: contentItem.childrenRect.height
clip: true 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 { Item {
id: mainItem id: mainItem
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property alias borderGradient: border.gradient property alias borderGradient: border.gradient
property alias gradient: fill.gradient property alias gradient: fill.gradient
property alias color: fill.color property alias color: fill.color
property real radius property real radius
Rectangle { Rectangle {
id: border id: border
radius: mainItem.radius radius: mainItem.radius
anchors.fill: parent anchors.fill: parent
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.grey_0 } GradientStop {
GradientStop { position: 1.0; color: DefaultStyle.grey_100 } position: 0.0
color: DefaultStyle.grey_0
}
GradientStop {
position: 1.0
color: DefaultStyle.grey_100
}
} }
Rectangle { Rectangle {
id: fill id: fill
anchors.fill: parent anchors.fill: parent
anchors.margins: mainItem.borderWidth anchors.margins: mainItem.borderWidth
radius: mainItem.radius radius: mainItem.radius
} }
} }
} }

View file

@ -2,10 +2,10 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
import Linphone 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{ Rectangle {
height: 1 height: 1
Layout.fillWidth: true Layout.fillWidth: true
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -4,15 +4,15 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView { ListView {
id: mainItem id: mainItem
visible: contentHeight > 0 visible: contentHeight > 0
clip: true clip: true
rightMargin: Utils.getSizeWithScreenRatio(5) rightMargin: Utils.getSizeWithScreenRatio(5)
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
property string searchBarText property string searchBarText
@ -26,7 +26,7 @@ ListView {
property ConferenceInfoGui confInfoGui property ConferenceInfoGui confInfoGui
signal addParticipantRequested() signal addParticipantRequested
Control.ScrollBar.vertical: ScrollBar { Control.ScrollBar.vertical: ScrollBar {
id: scrollbar id: scrollbar
@ -44,37 +44,40 @@ ListView {
} }
delegate: Item { delegate: Item {
height: Utils.getSizeWithScreenRatio(56) height: Utils.getSizeWithScreenRatio(56)
width: mainItem.width width: mainItem.width
RowLayout { RowLayout {
id: participantDelegate id: participantDelegate
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: (scrollbar.width + Utils.getSizeWithScreenRatio(5)) anchors.rightMargin: (scrollbar.width + Utils.getSizeWithScreenRatio(5))
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
z: 1 z: 1
Avatar { Avatar {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(45) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
_address: modelData.core.sipAddress _address: modelData.core.sipAddress
secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
shadowEnabled: false shadowEnabled: false
} }
Text { Text {
text: modelData.core.displayName text: modelData.core.displayName
font.pixelSize: Utils.getSizeWithScreenRatio(14) font.pixelSize: Utils.getSizeWithScreenRatio(14)
font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
maximumLineCount: 1 maximumLineCount: 1
Layout.fillWidth: true Layout.fillWidth: true
} }
Item{Layout.fillWidth: true} Item {
Layout.fillWidth: true
}
RowLayout { RowLayout {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
property bool isMe: modelData.core.isMe property bool isMe: modelData.core.isMe
onIsMeChanged: if (isMe) mainItem.me = modelData onIsMeChanged: if (isMe)
spacing: Utils.getSizeWithScreenRatio(26) mainItem.me = modelData
spacing: Utils.getSizeWithScreenRatio(26)
RowLayout { RowLayout {
spacing: Utils.getSizeWithScreenRatio(10) spacing: Utils.getSizeWithScreenRatio(10)
Text { Text {
visible: mainItem.isMeAdmin || modelData.core.isAdmin visible: mainItem.isMeAdmin || modelData.core.isAdmin
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
@ -88,20 +91,21 @@ ListView {
} }
Switch { Switch {
opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0 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) //TODO : Utilser checked et onToggled (pas compris)
onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1) onToggled: participantModel.setParticipantAdminStatus(modelData.core, position === 1)
} }
} }
SmallButton { SmallButton {
opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0 opacity: mainItem.isMeAdmin && !modelData.core.isMe ? 1 : 0
Layout.preferredWidth: Utils.getSizeWithScreenRatio(20) Layout.preferredWidth: Utils.getSizeWithScreenRatio(20)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(20) Layout.preferredHeight: Utils.getSizeWithScreenRatio(20)
color: DefaultStyle.main2_100 color: DefaultStyle.main2_100
leftPadding: Utils.getSizeWithScreenRatio(3) leftPadding: Utils.getSizeWithScreenRatio(3)
rightPadding: Utils.getSizeWithScreenRatio(3) rightPadding: Utils.getSizeWithScreenRatio(3)
topPadding: Utils.getSizeWithScreenRatio(3) topPadding: Utils.getSizeWithScreenRatio(3)
bottomPadding: Utils.getSizeWithScreenRatio(3) bottomPadding: Utils.getSizeWithScreenRatio(3)
style: ButtonStyle.hoveredBackground style: ButtonStyle.hoveredBackground
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
onClicked: participantModel.removeParticipant(modelData.core) 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 { Control.ProgressBar {
id: mainItem id: mainItem
padding: Utils.getSizeWithScreenRatio(3) padding: Utils.getSizeWithScreenRatio(3)
property color backgroundColor: DefaultStyle.main2_100 property color backgroundColor: DefaultStyle.main2_100
property color innerColor: DefaultStyle.info_500_main property color innerColor: DefaultStyle.info_500_main
property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0 property color innerTextColor: centeredText ? DefaultStyle.info_500_main : DefaultStyle.grey_0
property bool innerTextVisible: true property bool innerTextVisible: true
property string innerText: Number.parseFloat(value*100).toFixed(0) + "%" property string innerText: Number.parseFloat(value * 100).toFixed(0) + "%"
property real barWidth: mainItem.visualPosition * mainItem.width property real barWidth: mainItem.visualPosition * mainItem.width
property bool centeredText: textSize.width >= barWidth property bool centeredText: textSize.width >= barWidth
TextMetrics{ TextMetrics {
id: textSize id: textSize
text: mainItem.innerText text: mainItem.innerText
font { font {
pixelSize: Utils.getSizeWithScreenRatio(10) pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700) weight: Utils.getSizeWithScreenRatio(700)
bold: true bold: true
} }
} }
background: Rectangle { background: Rectangle {
color: mainItem.backgroundColor color: mainItem.backgroundColor
radius: Utils.getSizeWithScreenRatio(50) radius: Utils.getSizeWithScreenRatio(50)
anchors.fill: mainItem anchors.fill: mainItem
width: mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height
@ -38,7 +38,7 @@ Control.ProgressBar {
Rectangle { Rectangle {
id: bar id: bar
color: mainItem.innerColor color: mainItem.innerColor
radius: Utils.getSizeWithScreenRatio(50) radius: Utils.getSizeWithScreenRatio(50)
width: mainItem.barWidth width: mainItem.barWidth
height: parent.height height: parent.height
} }
@ -52,9 +52,9 @@ Control.ProgressBar {
color: mainItem.innerTextColor color: mainItem.innerTextColor
maximumLineCount: 1 maximumLineCount: 1
font { font {
pixelSize: Utils.getSizeWithScreenRatio(10) pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Utils.getSizeWithScreenRatio(700) weight: Utils.getSizeWithScreenRatio(700)
} }
} }
} }
} }

View file

@ -4,7 +4,7 @@ import QtQuick.Shapes
import Linphone 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
ProgressBar{ ProgressBar {
id: mainItem id: mainItem
property string text: value + '%' property string text: value + '%'
implicitHeight: 35 implicitHeight: 35
@ -12,19 +12,20 @@ ProgressBar{
to: 100 to: 100
value: 0 value: 0
background: Item {} background: Item {}
Timer{ Timer {
id: animationTest id: animationTest
repeat: true repeat: true
onTriggered: value = (value + 1) % to onTriggered: value = (value + 1) % to
interval: 5 interval: 5
} }
contentItem: Item{ contentItem: Item {
Shape { Shape {
id: shape id: shape
anchors.fill: parent anchors.fill: parent
anchors.margins: Utils.getSizeWithScreenRatio(2) 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.enabled: true
layer.samples: 8 layer.samples: 8
@ -61,11 +62,11 @@ ProgressBar{
centerX: Math.round(shape.width / 2) centerX: Math.round(shape.width / 2)
centerY: Math.round(shape.height / 2) centerY: Math.round(shape.height / 2)
startAngle: -90 // top start startAngle: -90 // top start
sweepAngle: (360/ mainItem.to * mainItem.value) sweepAngle: (360 / mainItem.to * mainItem.value)
} }
} }
} }
Text{ Text {
anchors.centerIn: parent anchors.centerIn: parent
text: mainItem.text text: mainItem.text
color: DefaultStyle.main1_500_main 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 { Control.Control {
id: mainItem id: mainItem
// width: Utils.getSizeWithScreenRatio(360) // width: Utils.getSizeWithScreenRatio(360)
property color backgroundColor: DefaultStyle.grey_0 property color backgroundColor: DefaultStyle.grey_0
padding: Utils.getSizeWithScreenRatio(10) padding: Utils.getSizeWithScreenRatio(10)
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(15) radius: Utils.getSizeWithScreenRatio(15)
color: mainItem.backgroundColor color: mainItem.backgroundColor
} }
} }

View file

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

View file

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

View file

@ -9,27 +9,28 @@ Text {
color: DefaultStyle.danger_500_main color: DefaultStyle.danger_500_main
property bool isVisible: text.length > 0 property bool isVisible: text.length > 0
function clear() { function clear() {
autoHideErrorMessage.stop() autoHideErrorMessage.stop();
text = "" text = "";
} }
function setText(text) { function setText(text) {
if (text.length === 0) { if (text.length === 0) {
clear() clear();
} else { } else {
mainItem.text = text mainItem.text = text;
} }
} }
font { font {
pixelSize: Typography.b3.pixelSize pixelSize: Typography.b3.pixelSize
weight: Typography.b3.weight weight: Typography.b3.weight
} }
Timer { Timer {
id: autoHideErrorMessage id: autoHideErrorMessage
interval: 5000 interval: 5000
onTriggered: { 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 width: txtMeter.advanceWidth
property alias tooltip: tooltip property alias tooltip: tooltip
property alias mouseArea: mouseArea property alias mouseArea: mouseArea
Quick.MouseArea { Quick.MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
@ -23,8 +23,8 @@ Quick.Text {
} }
font { font {
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(10) pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Typography.p1.weight weight: Typography.p1.weight
} }
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
textFormat: Text.PlainText textFormat: Text.PlainText

View file

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

View file

@ -13,11 +13,11 @@ FocusScope {
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
anchors.topMargin: Utils.getSizeWithScreenRatio(16) anchors.topMargin: Utils.getSizeWithScreenRatio(16)
anchors.bottomMargin: Utils.getSizeWithScreenRatio(16) anchors.bottomMargin: Utils.getSizeWithScreenRatio(16)
anchors.leftMargin: Utils.getSizeWithScreenRatio(17) anchors.leftMargin: Utils.getSizeWithScreenRatio(17)
anchors.rightMargin: Utils.getSizeWithScreenRatio(17) anchors.rightMargin: Utils.getSizeWithScreenRatio(17)
spacing: Utils.getSizeWithScreenRatio(12) spacing: Utils.getSizeWithScreenRatio(12)
RoundedPane { RoundedPane {
Layout.fillWidth: true Layout.fillWidth: true
@ -25,32 +25,40 @@ FocusScope {
spacing: 0 spacing: 0
Repeater { Repeater {
model: [ model: [
{text: qsTr("conference_layout_grid"), imgUrl: AppIcons.layout}, {
{text: qsTr("conference_layout_active_speaker"), imgUrl: AppIcons.pip}, text: qsTr("conference_layout_grid"),
{text: qsTr("conference_layout_audio_only"), imgUrl: AppIcons.waveform} imgUrl: AppIcons.layout
},
{
text: qsTr("conference_layout_active_speaker"),
imgUrl: AppIcons.pip
},
{
text: qsTr("conference_layout_audio_only"),
imgUrl: AppIcons.waveform
}
] ]
RadioButton { RadioButton {
id: radiobutton id: radiobutton
enabled: mainItem.call && !mainItem.call.core.paused enabled: mainItem.call && !mainItem.call.core.paused
checkOnClick: false checkOnClick: false
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
indicatorSize: Utils.getSizeWithScreenRatio(20) indicatorSize: Utils.getSizeWithScreenRatio(20)
leftPadding: indicator.width + spacing leftPadding: indicator.width + spacing
spacing: Utils.getSizeWithScreenRatio(8) 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. checkable:
checked: index == 0 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.
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid checked: index == 0 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.Grid : index == 1
: index == 1 ? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker : mainItem.conferenceLayout
? mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.ActiveSpeaker === LinphoneEnums.ConferenceLayout.AudioOnly
: mainItem.conferenceLayout === LinphoneEnums.ConferenceLayout.AudioOnly
onClicked: mainItem.changeLayoutRequested(index) onClicked: mainItem.changeLayoutRequested(index)
contentItem: RowLayout { contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
EffectImage { EffectImage {
id: radioButtonImg id: radioButtonImg
Layout.preferredWidth: Utils.getSizeWithScreenRatio(32) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(32) Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
imageSource: modelData.imgUrl imageSource: modelData.imgUrl
colorizationColor: DefaultStyle.main2_500_main colorizationColor: DefaultStyle.main2_500_main
} }
@ -58,7 +66,7 @@ FocusScope {
text: modelData.text text: modelData.text
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pixelSize: Utils.getSizeWithScreenRatio(14) font.pixelSize: Utils.getSizeWithScreenRatio(14)
Layout.fillWidth: true 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 QtQuick.Controls.Basic as Control
import Linphone import Linphone
import ConstantsCpp 1.0 import ConstantsCpp 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 import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
spacing: Utils.getSizeWithScreenRatio(8) spacing: Utils.getSizeWithScreenRatio(8)
FormItemLayout { FormItemLayout {
id: username id: username
Layout.preferredWidth: Utils.getSizeWithScreenRatio(346) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
//: Nom d'utilisateur : username //: Nom d'utilisateur : username
label: qsTr("username") label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: usernameEdit id: usernameEdit
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: username.errorTextVisible || (errorText.isVisible && text.length > 0) isError: username.errorTextVisible || (errorText.isVisible && text.length > 0)
onAccepted: passwordEdit.forceActiveFocus() onAccepted: passwordEdit.forceActiveFocus()
//: "%1 mandatory" //: "%1 mandatory"
@ -31,15 +31,15 @@ ColumnLayout {
Layout.preferredHeight: password.implicitHeight Layout.preferredHeight: password.implicitHeight
FormItemLayout { FormItemLayout {
id: password id: password
width: Utils.getSizeWithScreenRatio(346) width: Utils.getSizeWithScreenRatio(346)
//: Mot de passe //: Mot de passe
label: qsTr("password") label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: passwordEdit id: passwordEdit
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: password.errorTextVisible || (errorText.isVisible && text.length > 0) isError: password.errorTextVisible || (errorText.isVisible && text.length > 0)
hidden: true hidden: true
onAccepted: connectionButton.trigger() onAccepted: connectionButton.trigger()
@ -52,17 +52,16 @@ ColumnLayout {
target: LoginPageCpp target: LoginPageCpp
function onErrorMessageChanged() { function onErrorMessageChanged() {
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0) if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
errorText.setText(LoginPageCpp.errorMessage) errorText.setText(LoginPageCpp.errorMessage);
} }
} }
} }
} }
} }
RowLayout { RowLayout {
Layout.topMargin: Utils.getSizeWithScreenRatio(7) Layout.topMargin: Utils.getSizeWithScreenRatio(7)
spacing: Utils.getSizeWithScreenRatio(29) spacing: Utils.getSizeWithScreenRatio(29)
BigButton { BigButton {
id: connectionButton id: connectionButton
style: ButtonStyle.main style: ButtonStyle.main
@ -71,13 +70,13 @@ ColumnLayout {
id: connectionButtonContent id: connectionButtonContent
currentIndex: 0 currentIndex: 0
Text { Text {
//: "Connexion" //: "Connexion"
text: qsTr("assistant_account_login") text: qsTr("assistant_account_login")
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font { font {
pixelSize: Typography.b1.pixelSize pixelSize: Typography.b1.pixelSize
weight: Typography.b1.weight weight: Typography.b1.weight
} }
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
} }
@ -92,34 +91,34 @@ ColumnLayout {
target: LoginPageCpp target: LoginPageCpp
function onRegistrationStateChanged() { function onRegistrationStateChanged() {
if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) { if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) {
connectionButton.enabled = true connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0 connectionButtonContent.currentIndex = 0;
} }
} }
function onErrorMessageChanged() { function onErrorMessageChanged() {
connectionButton.enabled = true connectionButton.enabled = true;
connectionButtonContent.currentIndex = 0 connectionButtonContent.currentIndex = 0;
} }
} }
} }
function trigger() { function trigger() {
username.errorMessage = "" username.errorMessage = "";
password.errorMessage = "" password.errorMessage = "";
errorText.text = "" errorText.text = "";
if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) { if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0) {
if (usernameEdit.text.length == 0) if (usernameEdit.text.length == 0)
//: "Veuillez saisir un nom d'utilisateur" //: "Veuillez saisir un nom d'utilisateur"
username.errorMessage = qsTr("assistant_account_login_missing_username") username.errorMessage = qsTr("assistant_account_login_missing_username");
if (passwordEdit.text.length == 0) if (passwordEdit.text.length == 0)
//: "Veuillez saisir un mot de passe" //: "Veuillez saisir un mot de passe"
password.errorMessage = qsTr("assistant_account_login_missing_password") password.errorMessage = qsTr("assistant_account_login_missing_password");
return return;
} }
LoginPageCpp.login(usernameEdit.text, passwordEdit.text) LoginPageCpp.login(usernameEdit.text, passwordEdit.text);
connectionButton.enabled = false connectionButton.enabled = false;
connectionButtonContent.currentIndex = 1 connectionButtonContent.currentIndex = 1;
} }
onPressed: connectionButton.trigger() onPressed: connectionButton.trigger()
@ -127,11 +126,10 @@ ColumnLayout {
SmallButton { SmallButton {
id: forgottenButton id: forgottenButton
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
//: "Mot de passe oublié ?" //: "Mot de passe oublié ?"
text: qsTr("assistant_forgotten_password") text: qsTr("assistant_forgotten_password")
underline: true underline: true
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl) onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,29 +24,30 @@ FormItemLayout {
property var value: propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName] property var value: propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName]
function value() { 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 validator: textField.validator
property alias customButtonIcon: textField.customButtonIcon property alias customButtonIcon: textField.customButtonIcon
property alias customCallback: textField.customCallback property alias customCallback: textField.customCallback
property alias customButtonAccessibleName: textField.customButtonAccessibleName property alias customButtonAccessibleName: textField.customButtonAccessibleName
property var isValid: function(text) { property var isValid: function (text) {
return true return true;
} }
function empty() { function empty() {
textField.text = "" textField.text = "";
} }
contentItem: TextField { contentItem: TextField {
id: textField id: textField
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder 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 customWidth: mainItem.parent.width
propertyName: mainItem.propertyName propertyName: mainItem.propertyName
propertyOwner: mainItem.propertyOwner propertyOwner: mainItem.propertyOwner
@ -54,18 +55,18 @@ FormItemLayout {
canBeEmpty: mainItem.canBeEmpty canBeEmpty: mainItem.canBeEmpty
isValid: mainItem.isValid isValid: mainItem.isValid
toValidate: mainItem.toValidate toValidate: mainItem.toValidate
onValidationChecked: (isValid) => { onValidationChecked: isValid => {
if (isValid) return if (isValid)
if (!canBeEmpty && empty) { return;
//: "ne peut être vide" if (!canBeEmpty && empty) {
mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty") //: "ne peut être vide"
} else { mainItem.errorMessage = qsTr("textfield_error_message_cannot_be_empty");
//: "Format non reconnu" } else {
mainItem.errorMessage = qsTr("textfield_error_message_unknown_format") //: "Format non reconnu"
} mainItem.errorMessage = qsTr("textfield_error_message_unknown_format");
} }
}
onTextChanged: mainItem.clearErrorText() onTextChanged: mainItem.clearErrorText()
Accessible.name: mainItem.title 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 { Control.TextField {
id: mainItem id: mainItem
property real inputSize: Utils.getSizeWithScreenRatio(100) property real inputSize: Utils.getSizeWithScreenRatio(100)
property bool isError: false property bool isError: false
color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main 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 width: inputSize * 0.9
height: inputSize height: inputSize
@ -21,12 +24,12 @@ Control.TextField {
placeholderTextColor: "transparent" placeholderTextColor: "transparent"
// cursorVisible is overwritten on focus change so useless to hide the cursor // cursorVisible is overwritten on focus change so useless to hide the cursor
cursorDelegate: Item{} cursorDelegate: Item {}
// horizontalAlignment: Control.TextField.AlignHCenter // horizontalAlignment: Control.TextField.AlignHCenter
font.family: DefaultStyle.defaultFont font.family: DefaultStyle.defaultFont
font.pixelSize: inputSize / 2 font.pixelSize: inputSize / 2
font.weight: Utils.getSizeWithScreenRatio(300) font.weight: Utils.getSizeWithScreenRatio(300)
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
@ -34,12 +37,9 @@ Control.TextField {
// height: mainItem.inputSize // height: mainItem.inputSize
Rectangle { Rectangle {
id: background id: background
border.width: Utils.getSizeWithScreenRatio(1) border.width: Utils.getSizeWithScreenRatio(1)
border.color: mainItem.isError border.color: mainItem.isError ? DefaultStyle.danger_500_main : mainItem.activeFocus ? DefaultStyle.main1_500_main :
? DefaultStyle.danger_500_main DefaultStyle.main2_500_main
: mainItem.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.main2_500_main
radius: mainItem.inputSize * 0.15 radius: mainItem.inputSize * 0.15
width: mainItem.inputSize * 0.9 width: mainItem.inputSize * 0.9
height: mainItem.inputSize height: mainItem.inputSize
@ -48,11 +48,11 @@ Control.TextField {
id: indicator id: indicator
visible: mainItem.activeFocus visible: mainItem.activeFocus
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
height : Utils.getSizeWithScreenRatio(1) height: Utils.getSizeWithScreenRatio(1)
width: mainItem.inputSize * 0.67 width: mainItem.inputSize * 0.67
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom 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 QtQuick.Effects
import Linphone import Linphone
import UtilsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
FocusScope { FocusScope {
@ -15,19 +15,21 @@ FocusScope {
property var currentCall property var currentCall
property bool lastRowVisible: true property bool lastRowVisible: true
onButtonPressed: (text) => { onButtonPressed: text => {
if (currentCall) currentCall.core.lSendDtmf(text) if (currentCall)
else UtilsCpp.playDtmf(text) currentCall.core.lSendDtmf(text);
} else
UtilsCpp.playDtmf(text);
}
signal buttonPressed(string text) signal buttonPressed(string text)
signal launchCall() signal launchCall
signal wipe() signal wipe
function keypadKeyPressedAtIndex(index) { function keypadKeyPressedAtIndex(index) {
var button = numPadGrid.getButtonAt(index) var button = numPadGrid.getButtonAt(index);
button.shadowEnabled = true button.shadowEnabled = true;
button.clicked() button.clicked();
removeButtonsShadow.restart() removeButtonsShadow.restart();
} }
Timer { Timer {
@ -36,93 +38,93 @@ FocusScope {
repeat: false repeat: false
onTriggered: { onTriggered: {
for (var i = 0; i < 12; i++) { for (var i = 0; i < 12; i++) {
numPadGrid.getButtonAt(i).shadowEnabled = false numPadGrid.getButtonAt(i).shadowEnabled = false;
} }
} }
} }
function handleKeyPadEvent(event) { function handleKeyPadEvent(event) {
if (event.key === Qt.Key_0) { if (event.key === Qt.Key_0) {
keypadKeyPressedAtIndex(10) keypadKeyPressedAtIndex(10);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_1) { if (event.key === Qt.Key_1) {
keypadKeyPressedAtIndex(0) keypadKeyPressedAtIndex(0);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_2) { if (event.key === Qt.Key_2) {
keypadKeyPressedAtIndex(1) keypadKeyPressedAtIndex(1);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_3) { if (event.key === Qt.Key_3) {
keypadKeyPressedAtIndex(2) keypadKeyPressedAtIndex(2);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_4) { if (event.key === Qt.Key_4) {
keypadKeyPressedAtIndex(3) keypadKeyPressedAtIndex(3);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_5) { if (event.key === Qt.Key_5) {
keypadKeyPressedAtIndex(4) keypadKeyPressedAtIndex(4);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_6) { if (event.key === Qt.Key_6) {
keypadKeyPressedAtIndex(5) keypadKeyPressedAtIndex(5);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_7) { if (event.key === Qt.Key_7) {
keypadKeyPressedAtIndex(6) keypadKeyPressedAtIndex(6);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_8) { if (event.key === Qt.Key_8) {
keypadKeyPressedAtIndex(7) keypadKeyPressedAtIndex(7);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_9) { if (event.key === Qt.Key_9) {
keypadKeyPressedAtIndex(8) keypadKeyPressedAtIndex(8);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Asterisk) { if (event.key === Qt.Key_Asterisk) {
keypadKeyPressedAtIndex(9) keypadKeyPressedAtIndex(9);
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Plus) { if (event.key === Qt.Key_Plus) {
mainItem.buttonPressed("+") mainItem.buttonPressed("+");
event.accepted = true event.accepted = true;
} }
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.launchCall() mainItem.launchCall();
event.accepted = true event.accepted = true;
} }
} }
Keys.onPressed: (event) => { Keys.onPressed: event => {
event.accepted = false event.accepted = false;
if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) { if (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return) {
handleKeyPadEvent(event) handleKeyPadEvent(event);
} }
if (event.key === Qt.Key_Backspace) { if (event.key === Qt.Key_Backspace) {
mainItem.wipe() mainItem.wipe();
event.accepted = true event.accepted = true;
} }
} }
Layout.GridLayout { Layout.GridLayout {
id: numPadGrid id: numPadGrid
columns: 3 columns: 3
columnSpacing: Utils.getSizeWithScreenRatio(40) columnSpacing: Utils.getSizeWithScreenRatio(40)
rowSpacing: Utils.getSizeWithScreenRatio(10) rowSpacing: Utils.getSizeWithScreenRatio(10)
function getButtonAt(index){ function getButtonAt(index) {
index = (index+15) % 15 index = (index + 15) % 15;
if(index >= 0){ if (index >= 0) {
if( index < 9){ if (index < 9) {
return numPadRepeater.itemAt(index) return numPadRepeater.itemAt(index);
}else if( index < 12){ } else if (index < 12) {
return digitRepeater.itemAt(index-9) return digitRepeater.itemAt(index - 9);
}else if (index < 14){ } else if (index < 14) {
return launchCallButton return launchCallButton;
}else if( index < 15){ } else if (index < 15) {
return eraseButton return eraseButton;
} }
} }
} }
@ -133,47 +135,55 @@ FocusScope {
id: numPadButton id: numPadButton
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
required property int index required property int index
implicitWidth: Utils.getSizeWithScreenRatio(60) implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60) implicitHeight: Utils.getSizeWithScreenRatio(60)
onClicked: { onClicked: {
mainItem.buttonPressed(text) mainItem.buttonPressed(text);
} }
KeyNavigation.left: numPadGrid.getButtonAt(index - 1) KeyNavigation.left: numPadGrid.getButtonAt(index - 1)
KeyNavigation.right: numPadGrid.getButtonAt(index + 1) KeyNavigation.right: numPadGrid.getButtonAt(index + 1)
KeyNavigation.up: numPadGrid.getButtonAt(index - 3) KeyNavigation.up: numPadGrid.getButtonAt(index - 3)
KeyNavigation.down: numPadGrid.getButtonAt(index + 3) KeyNavigation.down: numPadGrid.getButtonAt(index + 3)
style: ButtonStyle.numericPad style: ButtonStyle.numericPad
radius: Utils.getSizeWithScreenRatio(71) radius: Utils.getSizeWithScreenRatio(71)
text: index + 1 text: index + 1
textSize: Utils.getSizeWithScreenRatio(32) textSize: Utils.getSizeWithScreenRatio(32)
textWeight: Utils.getSizeWithScreenRatio(400) textWeight: Utils.getSizeWithScreenRatio(400)
} }
} }
Repeater { Repeater {
id: digitRepeater id: digitRepeater
model: [ model: [
{pressText: "*"}, {
{pressText: "0", longPressText: "+"}, pressText: "*"
{pressText: "#"} },
{
pressText: "0",
longPressText: "+"
},
{
pressText: "#"
}
] ]
BigButton { BigButton {
id: digitButton id: digitButton
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
implicitWidth: Utils.getSizeWithScreenRatio(60) implicitWidth: Utils.getSizeWithScreenRatio(60)
implicitHeight: Utils.getSizeWithScreenRatio(60) implicitHeight: Utils.getSizeWithScreenRatio(60)
onClicked: mainItem.buttonPressed(pressText.text) onClicked: mainItem.buttonPressed(pressText.text)
onPressAndHold: mainItem.buttonPressed(longPressText.text) onPressAndHold: mainItem.buttonPressed(longPressText.text)
KeyNavigation.left: numPadGrid.getButtonAt((index - 1)+9) KeyNavigation.left: numPadGrid.getButtonAt((index - 1) + 9)
KeyNavigation.right: numPadGrid.getButtonAt((index + 1)+9) KeyNavigation.right: numPadGrid.getButtonAt((index + 1) + 9)
KeyNavigation.up: numPadGrid.getButtonAt((index - 3)+9) KeyNavigation.up: numPadGrid.getButtonAt((index - 3) + 9)
KeyNavigation.down: numPadGrid.getButtonAt((index + 3)+9) KeyNavigation.down: numPadGrid.getButtonAt((index + 3) + 9)
radius: Utils.getSizeWithScreenRatio(71) radius: Utils.getSizeWithScreenRatio(71)
style: ButtonStyle.numericPad style: ButtonStyle.numericPad
//: %1 longpress %2 //: %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 { contentItem: Item {
anchors.fill: parent anchors.fill: parent
@ -184,9 +194,12 @@ FocusScope {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Component.onCompleted: {if (modelData.longPressText === undefined) anchors.centerIn= parent} Component.onCompleted: {
if (modelData.longPressText === undefined)
anchors.centerIn = parent;
}
text: modelData.pressText text: modelData.pressText
font.pixelSize: Utils.getSizeWithScreenRatio(32) font.pixelSize: Utils.getSizeWithScreenRatio(32)
} }
Text { Text {
id: longPressText id: longPressText
@ -194,11 +207,11 @@ FocusScope {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
color: digitButton.pressed ? digitButton.pressedTextColor : digitButton.textColor color: digitButton.pressed ? digitButton.pressedTextColor : digitButton.textColor
y: digitButton.height/2 y: digitButton.height / 2
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
visible: modelData.longPressText ? modelData.longPressText.length > 0 : false visible: modelData.longPressText ? modelData.longPressText.length > 0 : false
text: modelData.longPressText ? modelData.longPressText : "" text: modelData.longPressText ? modelData.longPressText : ""
font.pixelSize: Utils.getSizeWithScreenRatio(22) font.pixelSize: Utils.getSizeWithScreenRatio(22)
} }
} }
} }
@ -210,12 +223,12 @@ FocusScope {
Button { Button {
id: launchCallButton id: launchCallButton
visible: mainItem.lastRowVisible visible: mainItem.lastRowVisible
implicitWidth: Utils.getSizeWithScreenRatio(75) implicitWidth: Utils.getSizeWithScreenRatio(75)
implicitHeight: Utils.getSizeWithScreenRatio(55) implicitHeight: Utils.getSizeWithScreenRatio(55)
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
icon.width: Utils.getSizeWithScreenRatio(32) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Utils.getSizeWithScreenRatio(32) icon.height: Utils.getSizeWithScreenRatio(32)
radius: Utils.getSizeWithScreenRatio(71) radius: Utils.getSizeWithScreenRatio(71)
style: ButtonStyle.phoneGreen style: ButtonStyle.phoneGreen
//: Call //: Call
@ -231,17 +244,17 @@ FocusScope {
Button { Button {
id: eraseButton id: eraseButton
visible: mainItem.lastRowVisible visible: mainItem.lastRowVisible
leftPadding: Utils.getSizeWithScreenRatio(5) leftPadding: Utils.getSizeWithScreenRatio(5)
rightPadding: Utils.getSizeWithScreenRatio(5) rightPadding: Utils.getSizeWithScreenRatio(5)
topPadding: Utils.getSizeWithScreenRatio(5) topPadding: Utils.getSizeWithScreenRatio(5)
bottomPadding: Utils.getSizeWithScreenRatio(5) bottomPadding: Utils.getSizeWithScreenRatio(5)
Layout.Layout.alignment: Qt.AlignHCenter Layout.Layout.alignment: Qt.AlignHCenter
icon.source: AppIcons.backspaceFill icon.source: AppIcons.backspaceFill
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.width: Utils.getSizeWithScreenRatio(38) icon.width: Utils.getSizeWithScreenRatio(38)
icon.height: Utils.getSizeWithScreenRatio(38) icon.height: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(38) Layout.Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
Layout.Layout.preferredHeight: Utils.getSizeWithScreenRatio(38) Layout.Layout.preferredHeight: Utils.getSizeWithScreenRatio(38)
//: Erase //: Erase
Accessible.name: qsTr("erase_accessible_name") Accessible.name: qsTr("erase_accessible_name")
@ -256,7 +269,7 @@ FocusScope {
background: Rectangle { background: Rectangle {
width: eraseButton.width width: eraseButton.width
height: eraseButton.height height: eraseButton.height
color: "transparent" color: "transparent"
border.color: eraseButton.keyboardFocus ? eraseButton.keyboardFocusedBorderColor : "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 string label: ""
property alias errorMessage: errorText.text property alias errorMessage: errorText.text
property string placeholderText : "" property string placeholderText: ""
property bool mandatory: false property bool mandatory: false
property bool enableErrorText: true property bool enableErrorText: true
property real textInputWidth: width property real textInputWidth: width
property string initialPhoneNumber property string initialPhoneNumber
readonly property string phoneNumber: textField.text readonly property string phoneNumber: textField.text
readonly property string countryCode: combobox.text readonly property string countryCode: combobox.text
@ -31,8 +31,8 @@ ColumnLayout {
text: mainItem.label + (mainItem.mandatory ? "*" : "") text: mainItem.label + (mainItem.mandatory ? "*" : "")
color: (combobox.activeFocus || textField.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.main2_600 color: (combobox.activeFocus || textField.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
font { font {
pixelSize: Typography.p2.pixelSize pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight weight: Typography.p2.weight
} }
} }
@ -42,14 +42,11 @@ ColumnLayout {
background: Rectangle { background: Rectangle {
id: contentBackground id: contentBackground
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63) radius: Utils.getSizeWithScreenRatio(63)
color: DefaultStyle.grey_100 color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0 border.color: mainItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : (textField.activeFocus
? DefaultStyle.danger_500_main || combobox.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.grey_200
: (textField.activeFocus || combobox.activeFocus) border.width: mainItem.borderWidth
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
border.width: mainItem.borderWidth
} }
contentItem: RowLayout { contentItem: RowLayout {
CountryIndicatorCombobox { CountryIndicatorCombobox {
@ -74,13 +71,15 @@ ColumnLayout {
placeholderText: mainItem.placeholderText placeholderText: mainItem.placeholderText
background: Rectangle { background: Rectangle {
visible: textField.keyboardFocus visible: textField.keyboardFocus
radius: Utils.getSizeWithScreenRatio(63) radius: Utils.getSizeWithScreenRatio(63)
color: "transparent" color: "transparent"
border.color: mainItem.keyboardFocusedBorderColor border.color: mainItem.keyboardFocusedBorderColor
border.width: mainItem.keyboardFocusedBorderWidth border.width: mainItem.keyboardFocusedBorderWidth
} }
initialText: initialPhoneNumber initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/} validator: RegularExpressionValidator {
regularExpression: /[0-9]+/
}
//: %1 number //: %1 number
Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name) 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 QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0 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 import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope { FocusScope {
id: mainItem id: mainItem
property bool magnifierVisible: true property bool magnifierVisible: true
property var validator: RegularExpressionValidator{} property var validator: RegularExpressionValidator {}
property var numericPadPopup property var numericPadPopup
property alias numericPadButton: dialerButton property alias numericPadButton: dialerButton
readonly property bool hasActiveFocus: textField.activeFocus readonly property bool hasActiveFocus: textField.activeFocus
property alias color: backgroundItem.color property alias color: backgroundItem.color
property bool delaySearch: true // Wait some idle time after typing to start searching property bool delaySearch: true // Wait some idle time after typing to start searching
property bool handleNumericPadPopupButtonsPressed: true property bool handleNumericPadPopupButtonsPressed: true
// Border properties // Border properties
property color borderColor: "transparent" property color borderColor: "transparent"
property color focusedBorderColor: DefaultStyle.main2_500_main property color focusedBorderColor: DefaultStyle.main2_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900 property color keyboardFocusedBorderColor: DefaultStyle.main2_900
@ -25,34 +25,36 @@ FocusScope {
// Text properties // Text properties
property string placeholderText: "" property string placeholderText: ""
property color placeholderTextColor: DefaultStyle.main2_400 property color placeholderTextColor: DefaultStyle.main2_400
property real textInputWidth: Utils.getSizeWithScreenRatio(350) property real textInputWidth: Utils.getSizeWithScreenRatio(350)
property string text: textField.searchText 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() { function clearText() {
textField.text = "" textField.text = "";
} }
Connections { Connections {
enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed enabled: numericPadPopup != undefined && handleNumericPadPopupButtonsPressed
target: numericPadPopup ? numericPadPopup : null target: numericPadPopup ? numericPadPopup : null
function onButtonPressed(text) { 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 implicitWidth: mainItem.textInputWidth
implicitHeight: Utils.getSizeWithScreenRatio(50) implicitHeight: Utils.getSizeWithScreenRatio(50)
Rectangle{ Rectangle {
id: backgroundItem id: backgroundItem
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(28) radius: Utils.getSizeWithScreenRatio(28)
color: DefaultStyle.grey_100 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 border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
EffectImage { EffectImage {
@ -61,15 +63,15 @@ FocusScope {
colorizationColor: DefaultStyle.main2_500_main colorizationColor: DefaultStyle.main2_500_main
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Utils.getSizeWithScreenRatio(10) anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
imageSource: AppIcons.magnifier imageSource: AppIcons.magnifier
width: Utils.getSizeWithScreenRatio(20) width: Utils.getSizeWithScreenRatio(20)
height: Utils.getSizeWithScreenRatio(20) height: Utils.getSizeWithScreenRatio(20)
} }
Control.TextField { Control.TextField {
id: textField id: textField
anchors.left: magnifier.visible ? magnifier.right : parent.left 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.right: clearTextButton.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
@ -82,8 +84,8 @@ FocusScope {
width: mainItem.width - dialerButton.width width: mainItem.width - dialerButton.width
echoMode: (mainItem.hidden && !dialerButton.checked) ? TextInput.Password : TextInput.Normal echoMode: (mainItem.hidden && !dialerButton.checked) ? TextInput.Password : TextInput.Normal
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
} }
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
@ -96,21 +98,22 @@ FocusScope {
cursorDelegate: Rectangle { cursorDelegate: Rectangle {
visible: textField.cursorVisible visible: textField.cursorVisible
color: DefaultStyle.main2_500_main color: DefaultStyle.main2_500_main
width: Utils.getSizeWithScreenRatio(1) width: Utils.getSizeWithScreenRatio(1)
} }
Timer{ Timer {
id: delayTimer id: delayTimer
interval: 300 interval: 300
repeat: false repeat: false
onTriggered: textField.searchText = textField.text onTriggered: textField.searchText = textField.text
} }
Keys.onPressed: (event) => { Keys.onPressed: event => {
event.accepted = false event.accepted = false;
if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier || event.key === Qt.Key_Return)) { if (mainItem.numericPadPopup && mainItem.numericPadPopup.opened && (event.modifiers & Qt.KeypadModifier
mainItem.numericPadPopup.keyPadKeyPressed(event) || event.key === Qt.Key_Return)) {
event.accepted = true mainItem.numericPadPopup.keyPadKeyPressed(event);
} event.accepted = true;
} }
}
} }
Button { Button {
id: dialerButton id: dialerButton
@ -120,37 +123,38 @@ FocusScope {
icon.source: AppIcons.dialer icon.source: AppIcons.dialer
contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600 contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
width: Utils.getSizeWithScreenRatio(30) width: Utils.getSizeWithScreenRatio(30)
height: Utils.getSizeWithScreenRatio(30) height: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24) icon.height: Utils.getSizeWithScreenRatio(24)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(20) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
//: "Open dialer" //: "Open dialer"
Accessible.name: qsTr("open_dialer_acccessibility_label") Accessible.name: qsTr("open_dialer_acccessibility_label")
onClicked: { onClicked: {
if(!checked){ if (!checked) {
mainItem.openNumericPadRequested() mainItem.openNumericPadRequested();
mainItem.numericPadPopup.open() mainItem.numericPadPopup.open();
} else mainItem.numericPadPopup.close() } else
mainItem.numericPadPopup.close();
} }
} }
Button { Button {
id: clearTextButton id: clearTextButton
visible: textField.text.length > 0 && mainItem.enabled visible: textField.text.length > 0 && mainItem.enabled
width: Utils.getSizeWithScreenRatio(24) width: Utils.getSizeWithScreenRatio(24)
height: Utils.getSizeWithScreenRatio(24) height: Utils.getSizeWithScreenRatio(24)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(20) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
//: "Clear text input" //: "Clear text input"
Accessible.name: qsTr("clear_text_input_acccessibility_label") Accessible.name: qsTr("clear_text_input_acccessibility_label")
onClicked: { onClicked: {
textField.clear() textField.clear();
} }
} }
} }

View file

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

View file

@ -3,232 +3,230 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0 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 import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.TextField { Control.TextField {
id: mainItem id: mainItem
property var customWidth property var customWidth
width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360) width: Utils.getSizeWithScreenRatio(customWidth ? customWidth - 1 : 360)
height: Utils.getSizeWithScreenRatio(49) height: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(15) leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible rightPadding: eyeButton.visible ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin :
? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin Utils.getSizeWithScreenRatio(15)
: Utils.getSizeWithScreenRatio(15) echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
// Workaround for Windows slowness when first typing a password // Workaround for Windows slowness when first typing a password
// due to Qt not initializing the Password echo mode before the first letter is typed // due to Qt not initializing the Password echo mode before the first letter is typed
Component.onCompleted: { Component.onCompleted: {
text = "workaround" text = "workaround";
resetText() resetText();
} }
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600 color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
placeholderTextColor: DefaultStyle.placeholders placeholderTextColor: DefaultStyle.placeholders
font { font {
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
selectByMouse: true selectByMouse: true
activeFocusOnTab: true activeFocusOnTab: true
KeyNavigation.right: eyeButton KeyNavigation.right: eyeButton
text: initialText text: initialText
property bool controlIsDown: false property bool controlIsDown: false
property bool hidden: false property bool hidden: false
property bool isError: false property bool isError: false
property bool keyboardFocus: FocusHelper.keyboardFocus property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties // Background properties
property bool backgroundVisible: true property bool backgroundVisible: true
property color backgroundColor: DefaultStyle.grey_100 property color backgroundColor: DefaultStyle.grey_100
property color disabledBackgroundColor: DefaultStyle.grey_200 property color disabledBackgroundColor: DefaultStyle.grey_200
// Border properties // Border properties
property color backgroundBorderColor: DefaultStyle.grey_200 property color backgroundBorderColor: DefaultStyle.grey_200
property color activeBorderColor: DefaultStyle.main1_500_main property color activeBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900 property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property color errorBorderColor: DefaultStyle.danger_500_main property color errorBorderColor: DefaultStyle.danger_500_main
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Text properties // Text properties
property string initialText property string initialText
property real pixelSize: Typography.p1.pixelSize property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight property real weight: Typography.p1.weight
// Custom button on the right // Custom button on the right
property string customButtonIcon property string customButtonIcon
property var customCallback property var customCallback
property string customButtonAccessibleName property string customButtonAccessibleName
// fill propertyName and propertyOwner to check text validity // fill propertyName and propertyOwner to check text validity
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner
property var propertyOwnerGui property var propertyOwnerGui
property var initialReading: true property var initialReading: true
property var isValid: function (text) { property var isValid: function (text) {
return true return true;
} }
property bool toValidate: false property bool toValidate: false
property int idleTimeOut: 200 property int idleTimeOut: 200
property bool empty: propertyOwnerGui property bool empty: propertyOwnerGui ? mainItem.propertyOwnerGui.core != undefined
? mainItem.propertyOwnerGui.core != undefined && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 : mainItem.propertyOwner != undefined
: mainItem.propertyOwner != undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0 && mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true property bool canBeEmpty: true
signal validationChecked(bool valid) signal validationChecked(bool valid)
function resetText() { function resetText() {
text = initialText text = initialText;
} }
signal enterPressed signal enterPressed
onAccepted: { onAccepted: {
// No need to process changing focus because of TextEdited callback. // No need to process changing focus because of TextEdited callback.
idleTimer.stop() idleTimer.stop();
updateText() updateText();
} }
onTextChanged: { onTextChanged: {
if (mainItem.toValidate) { if (mainItem.toValidate) {
idleTimer.restart() idleTimer.restart();
} }
} }
function updateText() { function updateText() {
mainItem.empty = text.length == 0 mainItem.empty = text.length == 0;
if (initialReading) { if (initialReading) {
initialReading = false initialReading = false;
} }
if (mainItem.empty && !mainItem.canBeEmpty) { if (mainItem.empty && !mainItem.canBeEmpty) {
mainItem.validationChecked(false) mainItem.validationChecked(false);
return return;
} }
if (mainItem.propertyName && isValid(text)) { if (mainItem.propertyName && isValid(text)) {
if (mainItem.propertyOwnerGui) { if (mainItem.propertyOwnerGui) {
if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) { if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) {
mainItem.propertyOwnerGui.core[mainItem.propertyName] = text mainItem.propertyOwnerGui.core[mainItem.propertyName] = text;
} }
} else { } else {
if (mainItem.propertyOwner[mainItem.propertyName] != text) if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text mainItem.propertyOwner[mainItem.propertyName] = text;
} }
mainItem.validationChecked(true) mainItem.validationChecked(true);
} else } else
mainItem.validationChecked(false) mainItem.validationChecked(false);
} }
// Validation textfield functions // Validation textfield functions
Timer { Timer {
id: idleTimer id: idleTimer
running: false running: false
interval: mainItem.idleTimeOut interval: mainItem.idleTimeOut
repeat: false repeat: false
onTriggered: { onTriggered: {
mainItem.accepted() mainItem.accepted();
} }
} }
background: Rectangle { background: Rectangle {
id: inputBackground id: inputBackground
visible: mainItem.backgroundVisible visible: mainItem.backgroundVisible
anchors.fill: parent anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(79) radius: Utils.getSizeWithScreenRatio(79)
color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor
border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor : mainItem.backgroundBorderColor border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor :
} mainItem.backgroundBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
cursorDelegate: Rectangle { cursorDelegate: Rectangle {
id: cursor id: cursor
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
width: Utils.getSizeWithScreenRatio(1) width: Utils.getSizeWithScreenRatio(1)
anchors.verticalCenter: mainItem.verticalCenter anchors.verticalCenter: mainItem.verticalCenter
SequentialAnimation { SequentialAnimation {
loops: Animation.Infinite loops: Animation.Infinite
running: mainItem.cursorVisible running: mainItem.cursorVisible
PropertyAction { PropertyAction {
target: cursor target: cursor
property: 'visible' property: 'visible'
value: true value: true
} }
PauseAnimation { PauseAnimation {
duration: 600 duration: 600
} }
PropertyAction { PropertyAction {
target: cursor target: cursor
property: 'visible' property: 'visible'
value: false value: false
} }
PauseAnimation { PauseAnimation {
duration: 600 duration: 600
} }
onStopped: { onStopped: {
cursor.visible = false cursor.visible = false;
} }
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Control) if (event.key == Qt.Key_Control)
mainItem.controlIsDown = true mainItem.controlIsDown = true;
if (event.key === Qt.Key_Enter if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|| event.key === Qt.Key_Return) { enterPressed();
enterPressed() if (mainItem.controlIsDown) {}
if (mainItem.controlIsDown) { }
}
Keys.onReleased: event => {
if (event.jey == Qt.Key_Control)
mainItem.controlIsDown = false;
}
} Button {
} id: eyeButton
} KeyNavigation.left: mainItem
Keys.onReleased: event => { property real rightMargin: Utils.getSizeWithScreenRatio(15)
if (event.jey == Qt.Key_Control) z: 1
mainItem.controlIsDown = false 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 { Accessible.name: (eyeButton.checked ?
id: eyeButton //: Hide %1
KeyNavigation.left: mainItem qsTr("hide_accessible_name") :
property real rightMargin: Utils.getSizeWithScreenRatio(15) //: Show %1
z: 1 qsTr("show_accessible_name")).arg(mainItem.Accessible.name)
visible: mainItem.hidden }
checkable: true Button {
style: ButtonStyle.noBackground id: customButton
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide KeyNavigation.left: mainItem
width: Utils.getSizeWithScreenRatio(20) z: 1
height: Utils.getSizeWithScreenRatio(20) visible: mainItem.customButtonIcon !== undefined && mainItem.customButtonIcon !== ""
icon.width: width style: ButtonStyle.noBackground
icon.height: height icon.source: mainItem.customButtonIcon
anchors.verticalCenter: parent.verticalCenter width: visible ? Utils.getSizeWithScreenRatio(20) : 0
anchors.right: parent.right height: Utils.getSizeWithScreenRatio(20)
anchors.rightMargin: rightMargin icon.width: width
icon.height: height
Accessible.name: (eyeButton.checked ? anchors.verticalCenter: parent.verticalCenter
//: Hide %1 anchors.right: parent.right
qsTr("hide_accessible_name") : anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
//: Show %1 onClicked: mainItem.customCallback()
qsTr("show_accessible_name") //: %1 button of %2
).arg(mainItem.Accessible.name) Accessible.name: qsTr("textfield_custom_button_accessible_name").arg(mainItem.customButtonAccessibleName).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: { onSelectedDateTimeChanged: {
if (minTime != undefined) { if (minTime != undefined) {
if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0) if (UtilsCpp.timeOffset(minTime, selectedDateTime) < 0)
selectedDateTime = minTime selectedDateTime = minTime;
} }
if (maxTime != undefined) { if (maxTime != undefined) {
if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0) if (UtilsCpp.timeOffset(maxTime, selectedDateTime) > 0)
selectedDateTime = maxTime selectedDateTime = maxTime;
} }
} }
readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm") readonly property string selectedTimeString: Qt.formatDateTime(selectedDateTime, "hh:mm")
property int selectedHour: input.hour*1 property int selectedHour: input.hour * 1
property int selectedMin: input.min*1 property int selectedMin: input.min * 1
property alias contentText: input property alias contentText: input
property var minTime property var minTime
property var maxTime property var maxTime
popup.width: Utils.getSizeWithScreenRatio(73) popup.width: Utils.getSizeWithScreenRatio(73)
listView.model: 48 listView.model: 48
listView.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) popup.height: Math.min(Utils.getSizeWithScreenRatio(204), listView.contentHeight)
editable: true editable: true
popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside popup.closePolicy: Popup.PressOutsideParent | Popup.CloseOnPressOutside
onCurrentTextChanged: input.text = currentText onCurrentTextChanged: input.text = currentText
popup.onOpened: { popup.onOpened: {
input.forceActiveFocus() input.forceActiveFocus();
} }
contentItem: TextInput { contentItem: TextInput {
id: input id: input
validator: IntValidator{} validator: IntValidator {}
// activeFocusOnPress: false // activeFocusOnPress: false
inputMask: "00:00" inputMask: "00:00"
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
@ -46,41 +46,41 @@ ComboBox {
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
onActiveFocusChanged: { onActiveFocusChanged: {
if (activeFocus) { if (activeFocus) {
selectAll() selectAll();
} else { } else {
listView.currentIndex = -1 listView.currentIndex = -1;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
} }
} }
font { font {
pixelSize: Typography.p2l.pixelSize pixelSize: Typography.p2l.pixelSize
weight: Typography.p2l.weight weight: Typography.p2l.weight
} }
text: mainItem.selectedTimeString text: mainItem.selectedTimeString
Keys.onPressed: (event) => { Keys.onPressed: event => {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
focus = false focus = false;
} }
} }
onFocusChanged: if (!focus) { onFocusChanged: if (!focus) {
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
console.log("set time", hour, min) console.log("set time", hour, min);
} }
} }
listView.delegate: Text { listView.delegate: Text {
id: hourDelegate id: hourDelegate
property int hour: modelData /2 property int hour: modelData / 2
property int min: modelData%2 === 0 ? 0 : 30 property int min: modelData % 2 === 0 ? 0 : 30
property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min) property var currentDateTime: UtilsCpp.createDateTime(new Date(), hour, min)
text: Qt.formatDateTime(currentDateTime, "hh:mm") text: Qt.formatDateTime(currentDateTime, "hh:mm")
width: mainItem.width width: mainItem.width
visible: mainItem.minTime == undefined || UtilsCpp.timeOffset(mainItem.minTime, currentDateTime) > 0 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 verticalAlignment: TextInput.AlignVCenter
horizontalAlignment: TextInput.AlignHCenter horizontalAlignment: TextInput.AlignHCenter
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -88,9 +88,9 @@ ComboBox {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: { onClicked: {
// mainItem.text = parent.text // mainItem.text = parent.text
mainItem.listView.currentIndex = index mainItem.listView.currentIndex = index;
mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min) mainItem.selectedDateTime = UtilsCpp.createDateTime(mainItem.selectedDateTime, hour, min);
mainItem.popup.close() mainItem.popup.close();
} }
Rectangle { Rectangle {
visible: parent.containsMouse visible: parent.containsMouse

View file

@ -6,7 +6,7 @@ import QtQuick.Layouts
import Qt.labs.platform import Qt.labs.platform
Window { Window {
id: mainItem id: mainItem
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -17,73 +17,73 @@ Window {
default property alias _content: content.data default property alias _content: content.data
property bool _isOpen: false property bool _isOpen: false
signal isOpened() signal isOpened
signal isClosed() signal isClosed
signal dataChanged() signal dataChanged
on_ContentChanged: dataChanged(_content) on_ContentChanged: dataChanged(_content)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function open () { function open() {
_isOpen = true; _isOpen = true;
isOpened(); isOpened();
} }
/* /*
function close () { function close () {
_isOpen = false _isOpen = false
isClosed() isClosed()
} }
*/ */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
objectName: '__internalWindow' 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 // 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.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 opacity: 1.0
height: _content[0] != null ? _content[0].height : 0 height: _content[0] != null ? _content[0].height : 0
width: _content[0] != null ? _content[0].width : 0 width: _content[0] != null ? _content[0].width : 0
visible:true visible: true
Item { Item {
id: content id: content
anchors.fill:parent anchors.fill: parent
focus: false focus: false
property var $parent: mainItem property var $parent: mainItem
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/* /*
states: State { states: State {
name: 'opening' name: 'opening'
when: _isOpen when: _isOpen
PropertyChanges { PropertyChanges {
opacity: 1.0 opacity: 1.0
target: window target: window
} }
} }
transitions: [ transitions: [
Transition { Transition {
from: '' from: ''
to: 'opening' to: 'opening'
ScriptAction { ScriptAction {
script: { script: {
if (wrapper.requestActivate) { if (wrapper.requestActivate) {
window.requestActivate() window.requestActivate()
} }
} }
} }
}, },
Transition { Transition {
from: '*' from: '*'
to: '' to: ''
ScriptAction { ScriptAction {
script: window.close() script: window.close()
} }
} }
] ]
*/ */
} }

View file

@ -7,7 +7,7 @@ import QtQuick.Dialogs
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp 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 import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Dialog { Dialog {
@ -18,73 +18,75 @@ Dialog {
readonly property string password: passwordEdit.text readonly property string password: passwordEdit.text
property var callback// Define cb(var) function property var callback// Define cb(var) function
topPadding: Utils.getSizeWithScreenRatio(20) topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Utils.getSizeWithScreenRatio(20) bottomPadding: Utils.getSizeWithScreenRatio(20)
leftPadding: Utils.getSizeWithScreenRatio(20) leftPadding: Utils.getSizeWithScreenRatio(20)
rightPadding: Utils.getSizeWithScreenRatio(20) rightPadding: Utils.getSizeWithScreenRatio(20)
width: Utils.getSizeWithScreenRatio(637) width: Utils.getSizeWithScreenRatio(637)
modal: true modal: true
closePolicy: Popup.NoAutoClose closePolicy: Popup.NoAutoClose
onAccepted: { onAccepted: {
if( callback) callback.cb(password) if (callback)
close() callback.cb(password);
close();
} }
onRejected: close() onRejected: close()
Component.onDestruction: if(callback) callback.destroy() Component.onDestruction: if (callback)
callback.destroy()
content: ColumnLayout { content: ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(20)
id: contentLayout id: contentLayout
Text { spacing: Utils.getSizeWithScreenRatio(20)
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")
}
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(250) Layout.preferredWidth: Utils.getSizeWithScreenRatio(250)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap 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. font {
text: qsTr("account_settings_dialog_invalid_password_message").arg(mainItem.identity) pixelSize: Typography.h3.pixelSize
font.pixelSize: Utils.getSizeWithScreenRatio(16) weight: Typography.h3.weight
font { }
pixelSize: Typography.h4.pixelSize //: "Authentification requise"
weight: Typography.h4.weight 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: [ buttons: [
MediumButton { MediumButton {
id: cancelButton id: cancelButton
Layout.topMargin: Utils.getSizeWithScreenRatio(10) Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: "Annuler //: "Annuler
text: qsTr("cancel") text: qsTr("cancel")
style: ButtonStyle.secondary style: ButtonStyle.secondary
onClicked: mainItem.rejected() onClicked: mainItem.rejected()
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
@ -92,20 +94,20 @@ Dialog {
}, },
MediumButton { MediumButton {
id: connectButton id: connectButton
Layout.topMargin: Utils.getSizeWithScreenRatio(10) Layout.topMargin: Utils.getSizeWithScreenRatio(10)
//: Connexion //: Connexion
text: qsTr("assistant_account_login") text: qsTr("assistant_account_login")
style: ButtonStyle.main style: ButtonStyle.main
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
KeyNavigation.right: cancelButton KeyNavigation.right: cancelButton
onClicked: { onClicked: {
passwordItem.errorMessage = "" passwordItem.errorMessage = "";
if (passwordEdit.text.length == 0) { if (passwordEdit.text.length == 0) {
//: Veuillez saisir un mot de passe //: Veuillez saisir un mot de passe
passwordItem.errorMessage = qsTr("assistant_account_login_missing_password") passwordItem.errorMessage = qsTr("assistant_account_login_missing_password");
return return;
} }
mainItem.accepted() mainItem.accepted();
} }
} }
] ]

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