Commit 421eae38 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(app): many changes:

- InvertedMouseArea use a asynchronous call on pressed event
- ListForm use an external style
- ListForm supports outside click
- ...
parent 2a1d92fa
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.3.3 (12081) - http://www.bohemiancoding.com/sketch -->
<title>add_field_over copy</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="OUTILS" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="linphone_v2.0_icones_buttons" sketch:type="MSArtboardGroup" transform="translate(-6981.000000, -12382.000000)">
<g id="add_field_over-copy" sketch:type="MSLayerGroup" transform="translate(6981.045368, 12382.656515)">
<g id="Oval-1-Copy-2-+-Imported-Layers-Copy-2" sketch:type="MSShapeGroup">
<ellipse id="Oval-1-Copy-2" fill="#444444" cx="39.8422909" cy="39.5061728" rx="39.8422909" ry="39.5061728"></ellipse>
<g id="Imported-Layers-Copy-2" transform="translate(18.593069, 19.423868)" stroke="#FFFFFF" stroke-width="5" stroke-linecap="round" stroke-linejoin="round">
<path d="M35.4786114,34.191652 L7.01983221,5.97295708 M7.02457534,34.191652 L35.4738683,5.97295708" transform="translate(21.249222, 20.082305) rotate(-315.000000) translate(-21.249222, -20.082305) "></path>
</g>
</g>
</g>
</g>
</g>
</svg>
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>imgs/add_field.svg</file>
<file>imgs/call.svg</file>
<file>imgs/cam.svg</file>
<file>imgs/chat_attachment.svg</file>
......@@ -38,12 +39,12 @@
<file>ui/modules/Linphone/Dialog/ConfirmDialog.qml</file>
<file>ui/modules/Linphone/Dialog/DialogDescription.qml</file>
<file>ui/modules/Linphone/Dialog/DialogPlus.qml</file>
<file>ui/modules/Linphone/DropZone.qml</file>
<file>ui/modules/Linphone/ForceScrollBar.qml</file>
<file>ui/modules/Linphone/Form/AbstractTextButton.qml</file>
<file>ui/modules/Linphone/Form/ActionBar.qml</file>
<file>ui/modules/Linphone/Form/ActionButton.qml</file>
<file>ui/modules/Linphone/Form/CheckBoxText.qml</file>
<file>ui/modules/Linphone/Form/DropZone.qml</file>
<file>ui/modules/Linphone/Form/ExclusiveButtons.qml</file>
<file>ui/modules/Linphone/Form/ListForm.qml</file>
<file>ui/modules/Linphone/Form/SmallButton.qml</file>
......@@ -65,6 +66,7 @@
<file>ui/modules/Linphone/Styles/Form/ActionBarStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/CheckBoxTextStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/ExclusiveButtonsStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/ListFormStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/SmallButtonStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/TextButtonAStyle.qml</file>
<file>ui/modules/Linphone/Styles/Form/TextButtonBStyle.qml</file>
......
#include <cstdlib>
#include <QQmlFileSelector>
#include <QMenu>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlFileSelector>
#include <QQuickView>
#include <QSystemTrayIcon>
#include <QtDebug>
......
......@@ -9,7 +9,7 @@ Text {
// Never created.
// Private data for `lupdate`.
Item {
property variant i18n: [
property var i18n: [
QT_TR_NOOP('hangup'),
QT_TR_NOOP('incomingCall'),
QT_TR_NOOP('lostIncomingCall'),
......
......@@ -4,7 +4,7 @@ import QtQuick.Dialogs 1.2
// ===================================================================
Rectangle {
signal dropped (variant files)
signal dropped (var files)
color: '#DDDDDD'
id: dropZone
......
......@@ -5,8 +5,9 @@ import Linphone.Styles 1.0
// ===================================================================
Row {
property var texts
property int _selectedButton: 0
property variant texts
signal clicked (int button)
......
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Linphone 1.0
import Linphone.Styles 1.0
// ===================================================================
RowLayout {
readonly property int lineHeight: 30
property alias title: text.text
spacing: 0
RowLayout {
Layout.alignment: Qt.AlignTop
Layout.preferredHeight: lineHeight
spacing: 20
// Add item in list.
ActionButton {
Layout.preferredHeight: 16
Layout.preferredWidth: 16
onClicked: {
if (valuesModel.count === 0 ||
valuesModel.get(valuesModel.count - 1).$value.length !== 0) {
valuesModel.append({ $value: '' })
}
}
}
// List title.
Text {
Layout.preferredWidth: 130
id: text
}
property alias model: values.model
property alias title: text.text
function _addValue (value) {
if (model.count === 0 ||
model.get(model.count - 1).$value.length !== 0) {
model.append({ $value: value })
}
}
function _handleEditionFinished (index, text) {
if (text.length === 0) {
model.remove(index)
} else {
model.set(index, { $value: text })
}
}
spacing: 0
// Title area.
RowLayout {
Layout.alignment: Qt.AlignTop
Layout.preferredHeight: ListFormStyle.lineHeight
spacing: ListFormStyle.titleArea.spacing
// Button: Add item in list.
ActionButton {
Layout.preferredHeight: ListFormStyle.titleArea.iconSize
Layout.preferredWidth: ListFormStyle.titleArea.iconSize
icon: ListFormStyle.titleArea.icon
onClicked: _addValue('')
}
// Content list.
ListView {
Layout.fillWidth: true
Layout.preferredHeight: values.count * lineHeight
id: values
interactive: false
model: ListModel {
id: valuesModel
ListElement { $value: 'toto' }
ListElement { $value: 'abc' }
ListElement { $value: 'machin' }
ListElement { $value: 'bidule' }
ListElement { $value: 'truc' }
}
delegate: Item {
implicitHeight: textEdit.height
width: parent.width
Rectangle {
color: textEdit.focus ? '#E6E6E6' : 'transparent'
id: background
implicitHeight: textEdit.height
implicitWidth: textEdit.contentWidth +
textEdit.padding * 2
}
Text {
anchors.fill: textEdit
color: '#5A585B'
font.italic: true
padding: textEdit.padding
text: textEdit.text.length === 0 && !textEdit.focus
? qsTr('fillPlaceholder')
: ''
verticalAlignment: Text.AlignVCenter
}
TextEdit {
color: focus ? '#000000' : '#5A585B'
font.bold: !focus
height: lineHeight
id: textEdit
padding: 10
selectByMouse: true
text: $value
verticalAlignment: TextEdit.AlignVCenter
width: parent.width
// To handle editingFinished, it's necessary to set
// focus on another component.
Keys.onReturnPressed: parent.forceActiveFocus()
onEditingFinished: {
if (text.length === 0) {
valuesModel.remove(index)
} else {
// textEdit.text is not the same value than
// valuesModel.get(index)
valuesModel.set(index, { $value: text })
}
// Hack: The edition is finished but the focus
// can be set.
focus = false
}
}
}
// Title text.
Text {
id: text
Layout.preferredWidth: ListFormStyle.titleArea.text.width
color: ListFormStyle.titleArea.text.color
font.pointSize: ListFormStyle.titleArea.text.fontSize
}
}
// Values.
ListView {
id: values
Layout.fillWidth: true
Layout.preferredHeight: count * ListFormStyle.lineHeight
interactive: false
delegate: Item {
implicitHeight: textEdit.height
width: parent.width
// Background.
Rectangle {
color: textEdit.activeFocus
? ListFormStyle.value.backgroundColor.focused
: ListFormStyle.value.backgroundColor.normal
implicitHeight: textEdit.height
implicitWidth: textEdit.width
}
// Placeholder.
Text {
anchors.fill: textEdit
color: ListFormStyle.value.placeholder.color
font.italic: true
font.pointSize: ListFormStyle.value.placeholder.fontSize
padding: textEdit.padding
text: textEdit.text.length === 0 && !textEdit.activeFocus
? qsTr('fillPlaceholder')
: ''
verticalAlignment: Text.AlignVCenter
}
// Input.
TextEdit {
id: textEdit
color: activeFocus
? ListFormStyle.value.text.color.focused
: ListFormStyle.value.text.color.normal
font.bold: !activeFocus
height: ListFormStyle.lineHeight
padding: ListFormStyle.value.text.padding
selectByMouse: true
text: $value
verticalAlignment: TextEdit.AlignVCenter
width: !activeFocus
? parent.width
: contentWidth + padding * 2
Keys.onEscapePressed: focus = false
Keys.onReturnPressed: focus = false
onEditingFinished: _handleEditionFinished(index, text)
}
// Handle click outside `TextEdit` instance.
InvertedMouseArea {
enabled: textEdit.activeFocus
height: textEdit.height
parent: parent
width: textEdit.width
onPressed: textEdit.focus = false
}
}
}
}
......@@ -2,6 +2,8 @@ import QtQuick 2.7
import Linphone 1.0
import 'qrc:/ui/scripts/utils.js' as Utils
// ===================================================================
// Helper to handle button click outside a component.
// ===================================================================
......@@ -39,9 +41,9 @@ Item {
function _isInItem (point) {
return (
point.x >= item.x &&
point.y >= item.y &&
point.x <= item.x + item.width &&
point.y <= item.y + item.height
point.y >= item.y &&
point.x <= item.x + item.width &&
point.y <= item.y + item.height
)
}
......@@ -49,7 +51,7 @@ Item {
// See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal
//
// The creation order of components in a view is undefined,
// so the mouse area must be created only when `enabled == true`.
// so the mouse area must be created only when `enabled === true`.
//
// In the first render, `enabled` must be equal to false.
Component.onCompleted: enabled && _createMouseArea()
......@@ -67,6 +69,8 @@ Item {
id: builder
MouseArea {
property var _timeout
anchors.fill: parent
propagateComposedEvents: true
z: Constants.zMax
......@@ -75,11 +79,23 @@ Item {
// Propagate event.
mouse.accepted = false
// Click is outside or not.
if (!_isInItem(
mapToItem(item.parent, mouse.x, mouse.y)
)) {
// Outside!!!
item.pressed()
if (_timeout != null) {
Utils.clearTimeout(_timeout)
}
// Use a asynchronous call that is executed
// after the propagated event.
//
// It's useful to ensure the window's context is not
// modified with the mouse event before the `onPressed`
// function.
//
// The timeout is destroyed with the `MouseArea` component.
_timeout = Utils.setTimeout.call(this, 0, item.pressed.bind(this))
}
}
}
......
......@@ -12,7 +12,7 @@ ColumnLayout {
property int entryHeight
property int entryWidth
property variant entries
property var entries
property int _selectedEntry: 0
......
......@@ -11,6 +11,14 @@ Rectangle {
property int entryHeight
property int maxMenuHeight
function show () {
visible = true
}
function hide () {
visible = false
}
// Ugly. Just ugly.
// `model` is a reference on a unknown component!
// See usage with SearchBox.
......@@ -20,14 +28,6 @@ Rectangle {
}
visible: false
function show () {
visible = true
}
function hide () {
visible = false
}
Rectangle {
id: content
......
pragma Singleton
import QtQuick 2.7
import Linphone 1.0
QtObject {
property int lineHeight: 30
property QtObject value: QtObject {
property QtObject backgroundColor: QtObject {
property color focused: '#E6E6E6'
property color normal: 'transparent'
}
property QtObject placeholder: QtObject {
property color color: '#5A585B'
property int fontSize: 10
}
property QtObject text: QtObject {
property int padding: 10
property QtObject color: QtObject {
property color focused: '#000000'
property color normal: '#5A585B'
}
}
}
property QtObject titleArea: QtObject {
property int spacing: 10
property int iconSize: 16
property string icon: 'add_field'
property QtObject text: QtObject {
property color color: '#000000'
property int fontSize: 10
property int width: 130
}
}
}
......@@ -15,6 +15,7 @@ singleton AbstractTextButtonStyle 1.0 Form/AbstractTextButtonStyle.qml
singleton ActionBarStyle 1.0 Form/ActionBarStyle.qml
singleton CheckBoxTextStyle 1.0 Form/CheckBoxTextStyle.qml
singleton ExclusiveButtonsStyle 1.0 Form/ExclusiveButtonsStyle.qml
singleton ListFormStyle 1.0 Form/ListFormStyle.qml
singleton SmallButtonStyle 1.0 Form/SmallButtonStyle.qml
singleton TextButtonAStyle 1.0 Form/TextButtonAStyle.qml
singleton TextButtonBStyle 1.0 Form/TextButtonBStyle.qml
......
......@@ -25,6 +25,9 @@ ContactDescription 1.0 Contact/ContactDescription.qml
# Dialog
DialogPlus 1.0 Dialog/DialogPlus.qml
# DropZone
DropZone 1.0 DropZone.qml
# ForceScrollBar
ForceScrollBar 1.0 ForceScrollBar.qml
......@@ -32,7 +35,6 @@ ForceScrollBar 1.0 ForceScrollBar.qml
ActionBar 1.0 Form/ActionBar.qml
ActionButton 1.0 Form/ActionButton.qml
CheckBoxText 1.0 Form/CheckBoxText.qml
DropZone 1.0 Form/DropZone.qml
ExclusiveButtons 1.0 Form/ExclusiveButtons.qml
LightButton 1.0 Form/LightButton.qml
ListForm 1.0 Form/ListForm.qml
......
......@@ -76,3 +76,28 @@ function snakeToCamel (s) {
return matches[1].toUpperCase()
})
}
// -------------------------------------------------------------------
function Timer (parent) {
return Qt.createQmlObject('import QtQuick 2.7; Timer { }', parent)
}
// A copy of `Window.setTimeout` from js.
// Use setTimeout.call(parentContext, delayTime, cb) to use it.
//
// delay is in milliseconds.
function setTimeout (delay, cb) {
var timer = new Timer(this)
timer.interval = delay
timer.repeat = false
timer.triggered.connect(cb)
timer.start()
return timer
}
function clearTimeout (timer) {
timer.destroy() // Not necessary: `timer.stop()`
}
......@@ -72,18 +72,33 @@ ColumnLayout {
ListForm {
title: qsTr('sipAccounts')
model: ListModel {
ListElement { $value: 'merinos@sip.linphone.org' }
ListElement { $value: 'elisabeth.pro@sip.linphone.org' }
}
}
ListForm {
title: qsTr('address')
model: ListModel {
ListElement { $value: '312 East 10th Street - New York, NY 1009' }
}
}
ListForm {
title: qsTr('emails')
model: ListModel {
ListElement { $value: 'e.meri@gmail.com' }
ListElement { $value: 'toto@truc.machin' }
}
}
ListForm {
title: qsTr('webSites')
model: ListModel {
ListElement { $value: 'www.totogro.com' }
ListElement { $value: 'www.404.unknown' }
}
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment