Files
shipheart-qt/Shipheart_boite_dialogue_minuteur.qml
T

552 lines
23 KiB
QML

import QtQuick 2.12
import QtQuick.Controls 2.12
Popup {
id: boite_dialogue_minuteur
// Propriétés fixes :
readonly property double pourcentage_largeur_page_popup: 0.8
readonly property double pourcentage_hauteur_page_popup: 0.8
readonly property int padding_popup: 20
readonly property double pourcentage_boite_dialogue_titre: 0.2
readonly property double pourcentage_boite_dialogue_message: 1 - pourcentage_boite_dialogue_titre - pourcentage_boite_dialogue_ligne_boutons
readonly property double pourcentage_boite_dialogue_ligne_boutons: 0.15
readonly property int bouton_hauteur: 60
readonly property double pourcentage_zone_tumblers: 0.75
readonly property int bouton_largeur: 200
readonly property int espace_tumblers: 20
// Propriétés :
property bool flag_init: true
property int valeur_tumbler_heure: 0
property int valeur_tumbler_minute: 0
property int valeur_tumbler_seconde: 0
// Propriétés alias :
//-------------------------------------------------
// Signaux :
//-------------------------------------------------
signal clicked(int bouton, int heure, int minute, int seconde) // Valeurs à lire lorsque le "OnClicked' est activé
//-------------------------------------------------
// Ouverture :
//-------------------------------------------------
onAboutToShow: { // Activé une fois quand le popup va être affiché
init(); // L'init n'a d'utilité que lorsqu'on va l'afficher...
}
onOpened: { // Quand la page est affichée
mise_a_jour(); // Nb : si on le fait à la suite de l'init, la première maj ne se fait pas car la page n'est pas encore ouverte...
}
//-------------------------------------------------
// Fermeture :
//-------------------------------------------------
onAboutToHide: {
}
x: (shipheart_largeur_page * (1 - pourcentage_largeur_page_popup)) / 2;
y: (shipheart_hauteur_page * (1 - pourcentage_hauteur_page_popup)) / 2;
width: shipheart_largeur_page * pourcentage_largeur_page_popup;
height: shipheart_hauteur_page * pourcentage_hauteur_page_popup;
padding: padding_popup
modal: true
// focus: true // SDIR # 224 : Il ne faut PAS activer le focus. Sinon, à la fermeture, le focus précédent est réactivé (comme le dernier TextField par exemple)
closePolicy: Popup.NoAutoClose //Popup.CloseOnPressOutside
background: Rectangle {
color: shipheart_couleur_fond_boite_dialogue_niveau_0
radius: 20
}
Column {
id: affichage_boite_dialogue
spacing: 20
//=========================================================================
// Titre :
//=========================================================================
Rectangle {
id: titre_boite_dialogue
width: boite_dialogue_minuteur.width - (2 * padding_popup)
height: (boite_dialogue_minuteur.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_boite_dialogue_titre
color: "transparent"
Image {
id: image_titre
source: "/images/sablier.png"
sourceSize.height: 100
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
}
}
//=========================================================================
// Zone principale :
//=========================================================================
Rectangle {
id: zone_principale
width: boite_dialogue_minuteur.width - (2 * padding_popup)
height: (boite_dialogue_minuteur.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_boite_dialogue_message
color: "transparent"
//------------------------------------------
// Tumblers de sélection manuelle :
//------------------------------------------
Row {
id: zone_tumblers
width: parent.width * pourcentage_zone_tumblers
height: parent.height
spacing: espace_tumblers
//-----------------------------------
// Heure :
//-----------------------------------
Rectangle {
width: zone_tumblers.width * 0.3
height: zone_tumblers.height
color: "transparent"
Text {
anchors.top: parent.top
width: parent.width
height: parent.height - tumbler_heure.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr("Heures")
color: couleur_blanc_casse
font.pixelSize: 18
}
Tumbler {
id: tumbler_heure
width: parent.width
height: parent.height * 0.85
anchors {
bottom: parent.bottom
}
visibleItemCount: 5
model: ListModel { }
delegate: bouton_heure
Component {
id: bouton_heure
Rectangle {
color: couleur_gris_fonce
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
Text {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
text: model.libelle
color: (index === tumbler_heure.currentIndex) ? couleur_blanc_casse : couleur_gris_pale
font.family: "Montserrat"
font.pixelSize: 26
font.bold: (index === tumbler_heure.currentIndex)
}
}
}
background: Rectangle {
color: couleur_gris_tres_fonce
radius: shipheart_grand_rayon_bouton
}
}
}
//-----------------------------------
// Minute :
//-----------------------------------
Rectangle {
width: zone_tumblers.width * 0.3
height: zone_tumblers.height
color: "transparent"
Text {
anchors.top: parent.top
width: parent.width
height: parent.height - tumbler_minute.height
visible: (tumbler_heure.model.get(tumbler_heure.currentIndex) !== undefined) ? // Sinon, génère un warning au démarrage...
(tumbler_heure.model.get(tumbler_heure.currentIndex).valeur <= 23) :
true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr("Minutes")
color: couleur_blanc_casse
font.pixelSize: 18
}
Tumbler {
id: tumbler_minute
width: parent.width
height: parent.height * 0.85
anchors {
bottom: parent.bottom
}
visibleItemCount: 5
model: ListModel { }
delegate: bouton_minute
opacity : (tumbler_heure.model.get(tumbler_heure.currentIndex) !== undefined) ? // Sinon, génère un warning au démarrage...
((tumbler_heure.model.get(tumbler_heure.currentIndex).valeur <= 23) ? 1.0 : 0) :
1.0
Component {
id: bouton_minute
Rectangle {
color: couleur_gris_fonce
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
Text {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
text: model.libelle
color: (index === tumbler_minute.currentIndex) ? couleur_blanc_casse : couleur_gris_pale
font.family: "Montserrat"
font.pixelSize: 26
font.bold: (index === tumbler_minute.currentIndex)
}
}
}
background: Rectangle {
color: couleur_gris_tres_fonce
radius: shipheart_grand_rayon_bouton
}
}
}
//-----------------------------------
// Secondes :
//-----------------------------------
Rectangle {
width: zone_tumblers.width * 0.3
height: zone_tumblers.height
color: "transparent"
Text {
anchors.top: parent.top
width: parent.width
height: parent.height - tumbler_minute.height
visible: (tumbler_heure.model.get(tumbler_heure.currentIndex) !== undefined) ? // Sinon, génère un warning au démarrage...
(tumbler_heure.model.get(tumbler_heure.currentIndex).valeur <= 23) :
true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr("Secondes")
color: couleur_blanc_casse
font.pixelSize: 18
}
Tumbler {
id: tumbler_seconde
width: parent.width
height: parent.height * 0.85
anchors {
bottom: parent.bottom
}
visibleItemCount: 5
model: ListModel { }
delegate: bouton_seconde
opacity : (tumbler_heure.model.get(tumbler_heure.currentIndex) !== undefined) ? // Sinon, génère un warning au démarrage...
((tumbler_heure.model.get(tumbler_heure.currentIndex).valeur <= 23) ? 1.0 : 0) :
1.0
Component {
id: bouton_seconde
Rectangle {
color: couleur_gris_fonce
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
Text {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
text: model.libelle
color: (index === tumbler_seconde.currentIndex) ? couleur_blanc_casse : couleur_gris_pale
font.family: "Montserrat"
font.pixelSize: 26
font.bold: (index === tumbler_seconde.currentIndex)
}
}
}
background: Rectangle {
color: couleur_gris_tres_fonce
radius: shipheart_grand_rayon_bouton
}
}
}
}
//------------------------------------------
// Boutons de droite :
//------------------------------------------
Column {
id: colonne_boutons
height: parent.height
width: parent.width * (1 - pourcentage_zone_tumblers)
anchors.right: parent.right
spacing: 5
Repeater {
model: ListModel { id: modele_boutons_preprogrammes }
// Bouton proprement dit :
Rectangle {
width: parent.width
height: (colonne_boutons.height - ((modele_boutons_preprogrammes.count - 1) * colonne_boutons.spacing)) / modele_boutons_preprogrammes.count
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce
Label {
anchors.centerIn: parent
text: model.libelle
color: couleur_blanc_casse
font.pixelSize:18
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
valeur_tumbler_heure = model.heure;
valeur_tumbler_minute = model.minute;
valeur_tumbler_seconde = model.seconde;
mise_a_jour();
}
}
}
}
}
}
//=========================================================================
// Boutons de bas de fenêtre :
//=========================================================================
Row {
height: (boite_dialogue_minuteur.height - (2 * padding_popup) - (2 * affichage_boite_dialogue.spacing)) * pourcentage_boite_dialogue_ligne_boutons
anchors.horizontalCenter: parent.horizontalCenter
spacing: 20
//.......................................................
// Bouton Annuler :
//.......................................................
Rectangle {
id: bouton_annuler
width: bouton_largeur
height: bouton_hauteur
anchors.verticalCenter: parent.verticalCenter
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce
Label {
id: bouton_annuler_label
anchors.centerIn: parent
text: qsTr("Annuler")
color: couleur_blanc_casse
font.pixelSize:20
}
MouseArea {
anchors.fill: parent
onClicked: {
shipheart_clic();
boite_dialogue_minuteur.clicked(shipheart_boite_dialogue_bouton_2, 0, 0, 0);
}
}
}
//.......................................................
// Bouton Ok / Démarrer :
//.......................................................
Rectangle {
id: bouton_ok
width: bouton_largeur
height: bouton_hauteur
anchors.verticalCenter: parent.verticalCenter
radius: shipheart_rayon_bouton
color: couleur_gris_tres_fonce
Label {
anchors.centerIn: parent
text: qsTr("Démarrer")
color: mousearea_demarrer.enabled ? couleur_blanc_casse : couleur_gris_moyen
font.pixelSize:20
}
MouseArea {
id: mousearea_demarrer
anchors.fill: parent
enabled: (!flag_init) &&
( (tumbler_heure.model.get(tumbler_heure.currentIndex).valeur !== 0)
|| (tumbler_minute.model.get(tumbler_minute.currentIndex).valeur !== 0)
|| (tumbler_seconde.model.get(tumbler_seconde.currentIndex).valeur !== 0) )
onClicked: {
shipheart_clic();
boite_dialogue_minuteur.clicked(shipheart_boite_dialogue_bouton_1,
tumbler_heure.model.get(tumbler_heure.currentIndex).valeur,
tumbler_minute.model.get(tumbler_minute.currentIndex).valeur,
tumbler_seconde.model.get(tumbler_seconde.currentIndex).valeur);
}
}
}
}
}
//=============================================================================================================
// Transitions d'ouverture et de fermeture de la boite de dialogue
//=============================================================================================================
enter: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 0.0
to: 1.0
//easing.type: Easing.InElastic
duration: 200
}
NumberAnimation {
property: "scale"
from: 0.0
to: 1.0
// easing.type: Easing.OutBack
duration: 200
}
}
}
exit: Transition {
ParallelAnimation {
NumberAnimation {
property: "opacity"
from: 1.0
to: 0.0
duration: 200
}
NumberAnimation {
property: "scale"
from: 1.0
to: 0.0
duration: 200
}
}
}
//=============================================================================================================
// Init des données de la boite de dialogue
//=============================================================================================================
function init()
{
var i;
flag_init = true; // On est obligé de le renseigne manuellement car la fonction 'init()' est appelée à chaque ouverture (et la valeur par défaut, qu'à l'ouverture initiale...)
//-------------------------------------
// Heures :
//-------------------------------------
tumbler_heure.model.clear();
for (i = 0; i < 24; i ++)
{
tumbler_heure.model.append( { "valeur": i, "libelle": ((i < 10) ? "0"+i : ""+i)} );
}
//-------------------------------------
// Minutes :
//-------------------------------------
tumbler_minute.model.clear();
for (i = 0; i < 60; i ++)
{
tumbler_minute.model.append( { "valeur": i, "libelle": ((i < 10) ? "0"+i : ""+i) } );
}
//-------------------------------------
// secondes :
//-------------------------------------
tumbler_seconde.model.clear();
for (i = 0; i < 60; i ++)
{
tumbler_seconde.model.append( { "valeur": i, "libelle": ((i < 10) ? "0"+i : ""+i) } );
}
modele_boutons_preprogrammes.clear();
modele_boutons_preprogrammes.append( {"libelle": "00:01:00", "heure": 0, "minute": 1, "seconde": 0 } );
modele_boutons_preprogrammes.append( {"libelle": "00:03:00", "heure": 0, "minute": 3, "seconde": 0 } );
modele_boutons_preprogrammes.append( {"libelle": "00:05:00", "heure": 0, "minute": 5, "seconde": 0 } );
modele_boutons_preprogrammes.append( {"libelle": "00:15:00", "heure": 0, "minute": 15, "seconde": 0 } );
modele_boutons_preprogrammes.append( {"libelle": "00:30:00", "heure": 0, "minute": 30, "seconde": 0 } );
modele_boutons_preprogrammes.append( {"libelle": "01:00:00", "heure": 1, "minute": 0, "seconde": 0 } );
flag_init = false;
}
//=============================================================================================================
// Mise à jour des données de la boite de dialogue
//=============================================================================================================
function mise_a_jour()
{
var i;
//-------------------------------------
// Heures :
//-------------------------------------
// Rercherche de la valeur courante :
for (i = 0; i < tumbler_heure.model.count; i ++)
{
if (tumbler_heure.model.get(i).valeur === valeur_tumbler_heure)
{
tumbler_heure.currentIndex = i;
break;
}
}
//-------------------------------------
// Minutes :
//-------------------------------------
// Rercherche de la valeur courante :
for (i = 0; i < tumbler_minute.model.count; i ++)
{
if (tumbler_minute.model.get(i).valeur === valeur_tumbler_minute)
{
tumbler_minute.currentIndex = i;
break;
}
}
//-------------------------------------
// Secondes :
//-------------------------------------
// Rercherche de la valeur courante :
for (i = 0; i < tumbler_seconde.model.count; i ++)
{
if (tumbler_seconde.model.get(i).valeur === valeur_tumbler_seconde)
{
tumbler_seconde.currentIndex = i;
break;
}
}
}
}