Rework phone keypad design.

Add phone keypad on main window and use it in smart search bar.
Add a backup text on smartsearch bar in order to avoid losing text when focus change (in the case of we want to get it).
This commit is contained in:
Julien Wadel 2022-06-07 17:41:53 +02:00
parent 4526ca7926
commit 4aad42fdc7
13 changed files with 4010 additions and 192 deletions

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="80"
height="80"
viewBox="0 0 79.999999 80.000001"
version="1.1"
id="svg10"
sodipodi:docname="tel_keypad_voicemail_custom.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview12"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.9879093"
inkscape:cx="9.3062596"
inkscape:cy="-4.5273695"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<defs
id="defs5">
<filter
id="filter_1"
x="-0.03898874"
y="-0.091859534"
width="1.0779775"
height="1.1837191">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="0 0 0 0 0.26666668 0 0 0 0 0.26666668 0 0 0 0 0.26666668 0 0 0 1 0"
color-interpolation-filters="sRGB"
id="feColorMatrix2" />
</filter>
</defs>
<g
id="g8"
transform="matrix(2.1639767,0,0,2.3524531,2.1443087,22.334821)"
filter="url(#filter_1)">
<path
d="m 14.117735,6.7224585 c 0,3.7680535 -3.101687,6.8228875 -6.9275349,6.8228875 -3.8254088,0 -6.92757212,-3.054834 -6.92757212,-6.8228875 0,-3.768531 3.10216332,-6.8233829 6.92757212,-6.8233829 3.8258479,0 6.9275349,3.0548519 6.9275349,6.8233829 z m 18.296228,0 c 0,3.7680535 -3.102617,6.8228875 -6.927507,6.8228875 -3.82638,0 -6.928069,-3.054834 -6.928069,-6.8228875 0,-3.768531 3.101689,-6.8233829 6.928069,-6.8233829 3.82489,0 6.927507,3.0548519 6.927507,6.8233829 z M 7.1902001,13.544887 H 25.486363 Z"
id="messagerie-icon"
fill="none"
fill-rule="evenodd"
stroke="#fffffe"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
style="stroke-width:2.50708;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because it is too large Load diff

View file

@ -152,6 +152,7 @@
<file>assets/images/stop_fullscreen_custom.svg</file>
<file>assets/images/timer_custom.svg</file>
<file>assets/images/tel_keypad_custom.svg</file>
<file>assets/images/tel_keypad_voicemail_custom.svg</file>
<file>assets/images/tooltip_arrow_bottom_custom.svg</file>
<file>assets/images/tooltip_arrow_left_custom.svg</file>
<file>assets/images/tooltip_arrow_right_custom.svg</file>

View file

@ -347,7 +347,6 @@ QString ChatRoomModel::getUsername () const {
}
QString ChatRoomModel::getAvatar () const {
qWarning() << getUsername() << " *> " << mChatRoom->getNbParticipants();
if( mChatRoom && mChatRoom->getNbParticipants() == 1){
auto participants = getParticipants(false);
auto contact = CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::coreStringToAppString((*participants.begin())->getAddress()->asString()));

View file

@ -123,6 +123,9 @@ class ColorListModel : public ProxyListModel {
ADD_COLOR("readonly_fg", "#B1B1B1", "Chat text area Readonly foreground")
ADD_COLOR("telkeypad_bg", "#4D5B66", "Background for phone keypad")
ADD_COLOR("telkeypad_fg", "#E4E4E4", "Foreground for phone keypad")
ADD_COLOR("telkeypad_h", "#B1B1B1", "Foreground for phone keypad")
// Keywords: 'mKeywordsMap'
// s=standard, ma=main, l=list, sc=screen, me=menu

View file

@ -82,6 +82,7 @@ Item {
signal clicked(real x, real y)
signal pressed(real x, real y)
signal released(real x, real y)
// ---------------------------------------------------------------------------
@ -121,8 +122,8 @@ Item {
function getBackgroundColor(){
var defaultColor = 'transparent'
if(isCustom){
if(wrappedButton.icon == '')
return getColor(wrappedButton.colorSet.backgroundNormalColor, defaultColor, 'backgroundNormalColor')
//if(wrappedButton.icon == '')
//return getColor(wrappedButton.colorSet.backgroundNormalColor, defaultColor, 'backgroundNormalColor')
if (wrappedButton.updating || wrappedButton.toggled)
return getColor(wrappedButton.colorSet.backgroundUpdatingColor, defaultColor, 'backgroundUpdatingColor')
if (!useStates)
@ -138,8 +139,8 @@ Item {
function getForegroundColor(){
var defaultColor = 'black'
if(isCustom){
if(wrappedButton.icon == '')
return getColor(wrappedButton.colorSet.foregroundNormalColor, defaultColor, 'foregroundNormalColor')
//if(wrappedButton.icon == '')
//return getColor(wrappedButton.colorSet.foregroundNormalColor, defaultColor, 'foregroundNormalColor')
if (wrappedButton.updating || wrappedButton.toggled)
return getColor(wrappedButton.colorSet.foregroundUpdatingColor, defaultColor, 'foregroundUpdatingColor')
if (!useStates)
@ -155,8 +156,8 @@ Item {
function getBackgroundHiddenPartColor(){
var defaultColor = 'transparent'
if(isCustom){
if(wrappedButton.icon == '')
return getColor(wrappedButton.colorSet.backgroundHiddenPartNormalColor, defaultColor, 'backgroundHiddenPartNormalColor')
//if(wrappedButton.icon == '')
//return getColor(wrappedButton.colorSet.backgroundHiddenPartNormalColor, defaultColor, 'backgroundHiddenPartNormalColor')
if (wrappedButton.updating || wrappedButton.toggled)
return getColor(wrappedButton.colorSet.backgroundHiddenPartUpdatingColor, defaultColor, 'backgroundHiddenPartUpdatingColor')
if (!useStates)
@ -172,8 +173,8 @@ Item {
function getForegroundHiddenPartColor(){
var defaultColor = '#80FFFFFF'
if(isCustom){
if(wrappedButton.icon == '')
return getColor(wrappedButton.colorSet.foregroundHiddenPartNormalColor, defaultColor, 'foregroundHiddenPartNormalColor')
//if(wrappedButton.icon == '')
//return getColor(wrappedButton.colorSet.foregroundHiddenPartNormalColor, defaultColor, 'foregroundHiddenPartNormalColor')
if (wrappedButton.updating || wrappedButton.toggled)
return getColor(wrappedButton.colorSet.foregroundHiddenPartUpdatingColor, defaultColor, 'foregroundHiddenPartUpdatingColor')
if (!useStates)
@ -214,6 +215,8 @@ Item {
hoverEnabled: !wrappedButton.updating//|| wrappedButton.autoIcon
onClicked: !wrappedButton.updating && wrappedButton.enabled && wrappedButton.clicked(pressX, pressY)
onPressed: !wrappedButton.updating && wrappedButton.enabled && wrappedButton.pressed(pressX, pressY)
onReleased: !wrappedButton.updating && wrappedButton.enabled && wrappedButton.released(pressX, pressY)
Rectangle{
id: foregroundColor
anchors.fill:parent

View file

@ -18,6 +18,8 @@ SearchBox {
property alias header : view.headerItem
property alias actions : view.actions
property alias showHeader : view.showHeader
property string previousText: text
onTextChanged: if( text != '') previousText = text;
function addAddressToIgnore(entry){
searchModel.addAddressToIgnore(entry)

View file

@ -7,19 +7,33 @@ import ColorsList 1.0
QtObject {
property string sectionName: 'TelKeypad'
property int columnSpacing: 0
property int height: 180
property int rowSpacing: 0
property int width: 180
property color color: ColorsList.add(sectionName+'', 'k').color
property int columnSpacing: 12
property int height: 240
property int rowSpacing: 12
property int width: 240
property color color: ColorsList.add(sectionName+'', 'telkeypad_bg').color
property color selectedColor : ColorsList.add(sectionName+'_c', 'm').color
property int selectedBorderWidth: 2
property real radius : 5.0
property real radius : 20
property QtObject voicemail: QtObject{
property string icon: 'tel_keypad_voicemail_custom'
property int iconSize: 20
}
property QtObject button: QtObject {
property QtObject color: QtObject {
property color normal: ColorsList.add(sectionName+'_b_n', 'q').color
property color pressed: ColorsList.add(sectionName+'_b_p', 'i').color
property QtObject colorSet: QtObject{
property int iconSize: 0
property string name : 'telButton'
property string icon : ''
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'telkeypad_fg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'telkeypad_h').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'i').color
property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'i').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'transparent').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'transparent').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'transparent').color
property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'transparent').color
}
property QtObject line: QtObject {
@ -32,8 +46,8 @@ QtObject {
}
property QtObject text: QtObject {
property color color: ColorsList.add(sectionName+'_b_text', 'd').color
property int pointSize: Units.dp * 11
property color color: ColorsList.add(sectionName+'_b_text', 'telkeypad_bg').color
property int pointSize: Units.dp * 14
}
}
}

View file

@ -9,118 +9,86 @@ import 'TelKeypad.js' as Logic
// =============================================================================
Rectangle {
id: telKeypad
id: telKeypad
property var container: parent
property var call
signal sendDtmf(var dtmf)
signal keyPressed(var event)
color: TelKeypadStyle.color // useless as it is overridden by buttons color, but keep it if buttons are transparent
onActiveFocusChanged: {if(activeFocus) selectedArea.border.width=TelKeypadStyle.selectedBorderWidth; else selectedArea.border.width=0}
Keys.onPressed: keyPressed(event)
layer {
effect: PopupShadow {}
enabled: true
}
height: TelKeypadStyle.height
width: TelKeypadStyle.width
radius:TelKeypadStyle.radius+1.0 // +1 for avoid mixing color with border slection (some pixels can be print after the line)
property var container: parent
property var call
color: TelKeypadStyle.color // useless as it is overridden by buttons color, but keep it if buttons are transparent
onActiveFocusChanged: {if(activeFocus) selectedArea.border.width=TelKeypadStyle.selectedBorderWidth; else selectedArea.border.width=0}
layer {
effect: PopupShadow {}
enabled: true
}
height: TelKeypadStyle.height
width: TelKeypadStyle.width
radius:TelKeypadStyle.radius+1.0 // +1 for avoid mixing color with border slection (some pixels can be print after the line)
Keys.onPressed: {
var index = Logic.mapKeyToButtonIndex(event.key)
if (index != null) {
event.accepted = true
Logic.sendDtmf(index)
}
}
// ---------------------------------------------------------------------------
GridLayout {
id: grid
anchors.fill: parent
columns: 4 // Not a style.
rows: 4 // Same idea.
columnSpacing: TelKeypadStyle.columnSpacing
rowSpacing: TelKeypadStyle.rowSpacing
Repeater {
model: [
'1', '2', '3', 'A',
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'*', '0', '#', 'D',
]
TelKeypadButton {
property var _timeout
Layout.fillHeight: true
Layout.fillWidth: true
text: modelData
onClicked: telKeypad.call.sendDtmf(modelData)
}
}
}
// ---------------------------------------------------------------------------
DragBox {
id: dragBox
readonly property int delta: 5
property int _id
property var _mouseX
property var _mouseY
container: telKeypad.container
draggable: parent
xPosition: (function () {
return 80
})
yPosition: (function () {
return 70
})
onPressed: {
_mouseX = mouse.x
_mouseY = mouse.y
_id = parseInt(_mouseX / (parent.width / grid.columns)) + parseInt(_mouseY / (parent.height / grid.rows)) * grid.columns
telKeypad.focus = true
}
onReleased: Math.abs(_mouseX - mouse.x) <= delta && Math.abs(_mouseY - mouse.y) <= delta &&
Logic.sendDtmf(_id)
}
Rectangle{
id: selectedArea
anchors.fill:parent
color:"transparent"
border.color:TelKeypadStyle.selectedColor
border.width:0
focus:false
enabled:false
radius:TelKeypadStyle.radius
}
MouseArea
{// Just take hover events and set popup to do its automatic close if mouse is not inside field/popup area
anchors.fill: parent
onContainsMouseChanged: (containsMouse?telKeypad.forceActiveFocus():telKeypad.focus=false)
hoverEnabled:true
preventStealing: true
propagateComposedEvents:true
onPressed: mouse.accepted=false
onReleased: mouse.accepted=false
onClicked: mouse.accepted=false
onDoubleClicked: mouse.accepted=false
onPressAndHold: mouse.accepted=false
}
// ---------------------------------------------------------------------------
MouseArea{
anchors.fill:parent
onClicked: telKeypad.forceActiveFocus()
}
GridLayout {
id: grid
anchors.fill: parent
anchors.topMargin: TelKeypadStyle.rowSpacing+5
anchors.bottomMargin: TelKeypadStyle.rowSpacing+5
anchors.leftMargin: TelKeypadStyle.columnSpacing+5
anchors.rightMargin: TelKeypadStyle.columnSpacing+5
columns: 4 // Not a style.
rows: 4 // Same idea.
columnSpacing: TelKeypadStyle.columnSpacing
rowSpacing: TelKeypadStyle.rowSpacing
Repeater {
model: [
'1', '2', '3', 'A',
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'*', '0', '#', 'D',
]
TelKeypadButton {
id: telKeypadButton
property var _timeout
showVoicemail: index === 0
auxSymbol: index === 13 ? '+' : ''
Layout.fillHeight: true
Layout.fillWidth: true
text: modelData
onSendDtmf: {
telKeypad.forceActiveFocus()
if(telKeypad.call) telKeypad.call.sendDtmf(dtmf)
telKeypad.sendDtmf(dtmf)
}
Connections{
target: telKeypad
onKeyPressed: telKeypadButton.activateEvent(event.key)
}
}
}
}
// ---------------------------------------------------------------------------
Rectangle{
id: selectedArea
anchors.fill:parent
color:"transparent"
border.color:TelKeypadStyle.selectedColor
border.width:0
focus:false
enabled:false
radius:TelKeypadStyle.radius
}
}

View file

@ -1,59 +1,118 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone.Styles 1.0
// =============================================================================
Item {
id: button
property color color: TelKeypadStyle.button.color.normal
property string text: ''
signal clicked
// ---------------------------------------------------------------------------
Rectangle {
anchors.fill: parent
color: button.color
radius:TelKeypadStyle.radius+2.0
ColumnLayout {
anchors.fill: parent
spacing: 0
Text {
Layout.fillHeight: true
Layout.fillWidth: true
color: TelKeypadStyle.button.text.color
elide: Text.ElideRight
font {
bold: true
pointSize: TelKeypadStyle.button.text.pointSize
}
text: button.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: TelKeypadStyle.button.line.height
Layout.bottomMargin: TelKeypadStyle.button.line.bottomMargin
Layout.leftMargin: TelKeypadStyle.button.line.leftMargin
Layout.rightMargin: TelKeypadStyle.button.line.rightMargin
Layout.topMargin: TelKeypadStyle.button.line.topMargin
color: TelKeypadStyle.button.line.color
}
}
}
}
property string text: ''
property bool showVoicemail: false
property string auxSymbol: ''
signal sendDtmf(var dtmf)
function activateEvent(key){
var keyString = String.fromCharCode(key)
if( keyString == text || keyString == auxSymbol){
actionButton.toggled = true;
sendDtmf(keyString)
}
}
// ---------------------------------------------------------------------------
Timer{
id: untoggledTimer
interval: 100
repeat: false
onTriggered: actionButton.toggled = false
}
ActionButton {
id: actionButton
onToggledChanged: if(toggled) untoggledTimer.start()
anchors.fill: parent
colorSet: TelKeypadStyle.button.colorSet
backgroundRadius: width/2
isCustom: true
property bool doNotSend: false
Timer{
id: longPress
interval: 500
onTriggered: { if(actionButton.doNotSend){
actionButton.doNotSend = false
}else{
if( button.auxSymbol != '' && actionButton.hovered) {
actionButton.doNotSend = true;
button.sendDtmf(button.auxSymbol)
}
}
}
}
onPressed: {actionButton.doNotSend = false;longPress.start()}
onReleased: { if(actionButton.doNotSend)
actionButton.doNotSend = false
else {
actionButton.doNotSend = true;
button.sendDtmf(button.text)
}
}
ColumnLayout {
anchors.fill: parent
spacing: 0
anchors.topMargin: 5
anchors.bottomMargin: 5
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter
Layout.leftMargin: 5
Layout.rightMargin: 5
spacing: 0
Text {
id: charText
Layout.fillHeight: true
Layout.fillWidth: true
color: TelKeypadStyle.button.text.color
elide: Text.ElideRight
font {
bold: true
pointSize: TelKeypadStyle.button.text.pointSize
}
text: button.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Icon{
icon: TelKeypadStyle.voicemail.icon
iconSize: charText.height/2
overwriteColor: TelKeypadStyle.button.text.color
visible: button.showVoicemail
}
}
Text {
visible: text != ''
Layout.fillHeight: true
Layout.fillWidth: true
color: TelKeypadStyle.button.text.color
elide: Text.ElideRight
font {
bold: true
pointSize: TelKeypadStyle.button.text.pointSize
}
text: auxSymbol
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}

View file

@ -200,9 +200,16 @@ ApplicationWindow {
onLaunchSecureChat: CallsListModel.launchChat( sipAddress,1 )
onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress, '')
}
ActionButton {
isCustom: true
backgroundRadius: 90
colorSet: MainWindowStyle.buttons.telKeyad
onClicked: telKeypad.visible = !telKeypad.visible
toggled: telKeypad.visible
}
ActionButton {
Layout.leftMargin: 30
isCustom: true
backgroundRadius: 4
colorSet: MainWindowStyle.buttons.newChatGroup
@ -355,16 +362,28 @@ ApplicationWindow {
}
// Main content.
Loader {
id: contentLoader
objectName: '__contentLoader'
Item{
Layout.fillHeight: true
Layout.fillWidth: true
source: 'Home.qml'
Component.onCompleted: if (AccountSettingsModel.accounts.length < 2) source= 'Assistant.qml' // default proxy = 1. Do not use this set diretly in source because of bindings that will override next setSource
Loader {
id: contentLoader
objectName: '__contentLoader'
anchors.fill: parent
source: 'Home.qml'
Component.onCompleted: if (AccountSettingsModel.accounts.length < 2) source= 'Assistant.qml' // default proxy = 1. Do not use this set diretly in source because of bindings that will override next setSource
}
TelKeypad {
anchors.right: parent.right
anchors.top: parent.top
id: telKeypad
onSendDtmf: smartSearchBar.text = smartSearchBar.previousText+dtmf
onVisibleChanged: if(!visible) smartSearchBar.previousText = '' // this is a way to reset search text
//call: incall.call
visible: SettingsModel.showTelKeypadAutomatically
}
}
}
}

View file

@ -130,9 +130,11 @@ QtObject {
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg').color
property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'me_u_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg').color
property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'me_u_b_fg').color
}
property QtObject secure: QtObject {
property int iconSize: 16

View file

@ -83,6 +83,19 @@ QtObject {
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'ma_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'ma_p_b_fg').color
}
property QtObject telKeyad: QtObject {
property int iconSize: 16
property string name : 'telKeypad'
property string icon : 'tel_keypad_custom'
property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'l_n_b_bg').color
property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'l_h_b_bg').color
property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'l_p_b_bg').color
property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'l_u_b_bg').color
property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'l_n_b_fg').color
property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'l_h_b_fg').color
property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'l_p_b_fg').color
property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'l_u_b_fg').color
}
property QtObject newChatGroup: QtObject {
property int iconSize: 40
property string name : 'newChatGroup'