Commit 5f1a6985 authored by Ionut Alexandrescu's avatar Ionut Alexandrescu

Initial commit of the Electric vehicle charging station

Add the general logic and the initial pages:
 - PagePromotionStop
 - PageChargeSelect
 - PagePayment
 - PageCharging
parents
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import App 1.0
Item {
id: batteryItem
width: 100
height: 280
property double initialCharge: 0
property double topUpCharge: 0
property double chargedPercentage: Variables.initialCharge
property bool chargingStarted: false
signal signalChargeCompleted();
function initializeValues()
{
propA.restart();
propA.from = Variables.initialCharge;
}
function getColor()
{
if ( chargingStarted === true )
{
if ( chargedPercentage < 25 )
{
return Qt.rgba( 1,0,0,1 );
}
else if ( chargedPercentage < 75 )
{
return Qt.rgba( 1,1,0,1 );
}
else
{
return Qt.rgba( 0,1,0,1 );
}
}
else
{
return Qt.rgba( 1,1,1,1 );
}
}
function updateColor()
{
shEffect2.colorValue = getColor();
batteryBar.colorValue = getColor();
}
PropertyAnimation
{
id: propA;
running: batteryItem.chargingStarted;
target: batteryItem;
property: "chargedPercentage";
to: 100;
duration: Variables.timeToComplete;
}
onChargedPercentageChanged:
{
if ( chargingStarted )
{
updateColor();
batteryBar.topValue = batteryItem.chargedPercentage;
if ( chargedPercentage >= topUpCharge )
{
batteryItem.chargingStarted = false;
batteryItem.signalChargeCompleted();
}
}
}
BatteryBars
{
id: batteryBar
bottomValue: 0
topValue: batteryItem.topUpCharge
}
BatteryBars
{
id: topBatteryPart
visible: batteryItem.chargingStarted
bottomValue: batteryItem.chargedPercentage
topValue: 0
opacity: 0.5
PropertyAnimation
{
id: propB;
running: batteryItem.chargingStarted;
loops: 1
target: topBatteryPart;
property: "topValue";
from: batteryItem.chargedPercentage
to: 100;
duration: 4000;
onStopped:
{
propB.from = batteryItem.chargedPercentage;
propB.start();
}
}
}
Image {
x: 0
y: 0
opacity: 0.1
width: 100
height: 280
source: "Assets/Battery/EVCS_UI_battery_100x280.png"
}
Image {
id: imageGlow
x: 0
y: 0
visible: false
width: 100
height: 280
source: "Assets/Battery/EVCS_UI_battery_frames_100x280.png"
}
ShaderEffect {
id: shEffect2;
width: 100
height: 280
x: 0;
y: 0;
property variant src: imageGlow;
property color colorValue: Qt.rgba( 1,1,1,1 );
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 coord;
void main() {
coord = qt_MultiTexCoord0;
gl_Position = qt_Matrix * qt_Vertex;
}"
fragmentShader: "
varying highp vec2 coord;
uniform lowp vec4 colorValue;
uniform sampler2D src;
uniform lowp float qt_Opacity;
void main() {
lowp vec4 tex0 = texture2D(src, coord);
gl_FragColor = tex0 *colorValue * qt_Opacity;
}"
}
}
import QtQuick 2.7
Item
{
id: root
property double chargedJump: 0.2922
property double chargedDelta: 0.01488
property double bottomValue: 0
property double topValue: 100
property alias colorValue: shEffect1.colorValue
Image {
id: imageBars
x: 0
y: 0
width: 100
height: 280
visible: false
fillMode: Image.PreserveAspectFit
source: "Assets/Battery/EVCS_UI_battery_100x280.png"
}
focus: true
Image {
id: imageGradient
x: 0
y: 0
width: 100
height: 280
visible: false
source: "Assets/Battery/EVCS_UI_battery_gradient_100x280.png"
}
ShaderEffect {
id: shEffect1;
x: 0
y: 0
width: 100
height: 280
property variant src: imageBars;
property variant src1: imageGradient;
property color colorValue: Qt.rgba( 1,1,1,1 );
property double chargedBottom: ( Math.floor( bottomValue * chargedJump ) * ( 1 / chargedJump ) )*(1-2*chargedDelta)*0.01 + chargedDelta;
property double chargedTop: ( Math.floor( topValue * chargedJump ) * ( 1 / chargedJump ) )*(1-2*chargedDelta)*0.01 + chargedDelta;
vertexShader: "
uniform highp mat4 qt_Matrix;
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 coord;
void main() {
coord = qt_MultiTexCoord0;
gl_Position = qt_Matrix * qt_Vertex;
}"
fragmentShader: "
varying highp vec2 coord;
uniform lowp vec4 colorValue;
uniform lowp float chargedBottom;
uniform lowp float chargedTop;
uniform sampler2D src;
uniform sampler2D src1;
uniform lowp float qt_Opacity;
void main() {
lowp float bottomMultiplier = step(chargedBottom, 1.0 - coord.y );
lowp float topMultiplier = 1.0 - step(chargedTop, 1.0 - coord.y );
lowp vec4 tex0 = texture2D(src, coord);
lowp vec4 tex1 = texture2D(src1, coord);
gl_FragColor = clamp( tex0 *colorValue + tex1, vec4(0,0,0,0), vec4(1,1,1,1) ) * qt_Opacity * topMultiplier * bottomMultiplier;
}"
}
}
QT += qml quick
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES +=
import QtQuick 2.8
import QtQuick.Controls 2.0
Dial {
id: dial
background: Rectangle {
x: dial.width / 2 - width / 2
y: dial.height / 2 - height / 2
width: Math.max(64, Math.min(dial.width, dial.height))
height: width
color: "transparent"
radius: width / 2
border.color: dial.pressed ? "#17a81a" : "#21be2b"
opacity: dial.enabled ? 1 : 0.3
}
handle: Image {
id: handleItem
x: dial.background.x + dial.background.width / 2 - width / 2
y: dial.background.y + dial.background.height / 2 - height / 2
width: 16
height: 16
//color: dial.pressed ? "#17a81a" : "#21be2b"
//radius: 8
source: "Assets/Select/EVCS_dial_button_16x16.png"
antialiasing: true
opacity: dial.enabled ? 1 : 0.3
transform: [
Translate {
x: -8
y: -Math.min(dial.background.width, dial.background.height) * 0.4 + handleItem.height / 2 - 8
},
Rotation {
angle: dial.angle
origin.x: handleItem.width / 2
origin.y: handleItem.height / 2
}
]
}
}
import QtQuick 2.9
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Item {
id: footer
signal leftButtonReleased
signal rightButtonReleased
property alias leftButtonText: leftButton.text
property alias leftButtonVisible: leftButton.opacity
property alias leftButtonEnabled: leftButton.enabled
property alias rightButtonText: rightButton.text
property alias rightButtonVisible: rightButton.opacity
property alias rightButtonEnabled: rightButton.enabled
property alias pageIndicatorcurrentIndex: pageIndicator.currentIndex
property alias pageIndicatorcount: pageIndicator.count
RowLayout {
anchors.fill: parent
FooterButton {
id: leftButton
Layout.preferredWidth: 150
Layout.preferredHeight: 56
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
text: qsTr("Cancel")
buttonImage: "Assets/Buttons/blue_btn_171x42.png"
onReleased: footer.leftButtonReleased()
}
PageIndicator {
id: pageIndicator
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
}
FooterButton {
id: rightButton
Layout.preferredWidth: 150
Layout.preferredHeight: 56
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
buttonImage: "Assets/Buttons/green_btn_171x42.png"
text: qsTr("Confirm")
onReleased: footer.rightButtonReleased()
}
}
}
import QtQuick 2.9
import QtQuick.Controls 2.0
import App 1.0
Button {
id: button
property alias buttonImage: backImage.source
height: 53
width: 150
font.pointSize: Variables.footerButtonPoints
flat: true
contentItem: Label {
color: "#ffffff"
text: button.text
font: button.font
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
background:
Item
{
Image {
visible: enabled
id: backImage
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: "Assets/Buttons/blue_btn_171x42.png"
}
Image {
visible: !enabled
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: "Assets/Buttons/grey_btn_171x42.png"
}
}
Behavior on opacity
{
NumberAnimation { duration: 50 }
}
}
import QtQuick 2.8
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Item {
signal openInfo
// Left Positioner
RowLayout
{
anchors.left: parent.left
height: 50
Image {
Layout.preferredWidth: 41
Layout.preferredHeight: 31
Layout.leftMargin: 20
source: "Assets/Icons/EVCS_Qt_logo_41x31.png"
}
Label {
Layout.preferredWidth: 300
Layout.preferredHeight: 31
Layout.leftMargin: 10
verticalAlignment: Text.AlignVCenter
color: "#ffffff"
text: qsTr("Electric charging station")
font.pointSize: 18
font.bold: true
}
}
// Right Positioner
RowLayout
{
anchors.right: parent.right
height: 50
spacing: 10
ComboBox
{
Layout.preferredWidth: 110
Layout.preferredHeight: 31
id: control
model: ["Assets/Icons/EVCS_icon_flag_UK_53x31.png", "Assets/Icons/EVCS_icon_flag_FR_53x31.png",
"Assets/Icons/EVCS_icon_flag_DE_53x31.png", "Assets/Icons/EVCS_icon_flag_IT_53x31.png"]
delegate: ItemDelegate {
contentItem:
Image {
width: 53
height: 31
fillMode: Image.PreserveAspectFit
source: modelData
}
//highlighted: control.highlightedIndex === index
}
indicator: Canvas {
id: canvas
x: control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
width: 12
height: 8
contextType: "2d"
Connections {
target: control
onPressedChanged: canvas.requestPaint()
}
onPaint: {
context.reset();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = "#ffffff";
context.fill();
}
}
contentItem:
Image {
width: 53
height: 31
fillMode: Image.PreserveAspectFit
source: control.displayText
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 31
color: "#09102C"
border.color: control.pressed ? "#17a81a" : "#21be2b"
border.width: 0
radius: 2
}
popup: Popup {
y: control.height +2
width: control.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
color: "#09102C"
border.color: "#21be2b"
border.width: 0
radius: 2
}
}
onActivated:
{
if ( index === 1 )
translation.selectLanguage( "fr" );
else if ( index === 2 )
translation.selectLanguage( "de" );
else if ( index === 3 )
translation.selectLanguage( "it" );
else
translation.selectLanguage( "en" );
}
}
Button
{
Layout.preferredWidth: 31
Layout.preferredHeight: 31
background: Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: "Assets/Icons/EVCS_icon_map_31x31.png"
}
flat: true
//onClicked: header.openInfo();
}
Button
{
Layout.preferredWidth: 30
Layout.preferredHeight: 31
Layout.rightMargin: 20
background: Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: "Assets/Icons/EVCS_icon_info_30x31.png"
}
flat: true
//onClicked: header.openInfo();
}
}
/**/
/*Button {
id: infoButton
x: parent.width - width - 20
y: 9
width: 30
height: 31
background: Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: "Assets/Icons/EVCS_icon_info_30x31.png"
}
flat: true
onClicked: header.openInfo();
}*/
/**/
}
import QtQuick 2.6
import QtQuick.Controls 2.1
import App 1.0
Item {
id: root
signal valueChanged( real value );
signal priceChanged( real value );
function setChargeValue( value )
{
chargeSpinBox.from = value;
chargeSpinBox.to = value;
chargeSpinBox.value = value;
}
function setTimeValue( value )
{
timeSpinBox.from = value;
timeSpinBox.to = value;
timeSpinBox.value = value;
}
function setPriceValue( value )
{
priceSpinBox.from = value;
priceSpinBox.to = value;
priceSpinBox.value = value;
}
Component.onCompleted:
{
chargeSpinBox.from = Variables.initialCharge * 100
}
function updateValues( value )
{
setSizeStep( 100 )
chargeSpinBox.updateValue( value );
timeSpinBox.updateValue( value );
priceSpinBox.updateValue( value );
}
function setSizeStep( value )
{
chargeSpinBox.stepSize = value;
timeSpinBox.stepSize = Variables.timeOnePercent * value
priceSpinBox.stepSize = Variables.priceOnePercent * value
}
SpinBoxNumber
{
id: chargeSpinBox
function updateValue( inValue )
{
chargeSpinBox.value = inValue * 100
}
onValueModified:
{
var sendValue = value / 100;
root.valueChanged( sendValue )
timeSpinBox.updateValue( sendValue )
priceSpinBox.updateValue( sendValue )
}
}
SpinBoxTime
{
id: timeSpinBox
y: 60
function updateValue( inValue )
{
var chargeToAdd = inValue - Variables.initialCharge
timeSpinBox.value = chargeToAdd * Variables.timeOnePercent * 100
}
onValueModified:
{
var chargeToAdd = value / ( Variables.timeOnePercent * 100 )
var sendValue = chargeToAdd + Variables.initialCharge;
root.valueChanged( sendValue )
chargeSpinBox.updateValue( sendValue )
priceSpinBox.updateValue( sendValue )
}
}