//----------------------------------------------------------------------------------------------------- // Fichier définissant un bouton de type Circuit sur la page d'accueil // A priori, appelé depuis "home.qml" //----------------------------------------------------------------------------------------------------- import QtQuick 2.12 //======================================================= // Ensemble du bouton //======================================================= Item { id: bouton_circuit // Paramètres d'affichage : readonly property int largeur_bouton: circuits_grid.cellWidth - espace_colonnes_secondaires; readonly property int hauteur_bouton: circuits_grid.cellHeight - espace_lignes_secondaires; readonly property double pourcentage_largeur_zone_affichage_nom: 0.60 readonly property double pourcentage_largeur_zone_affichage_consigne: 0.25 readonly property int espace_interne: 5 // | zone affichage nom | cdes auto | consigne | // | zone affichage intensité | | | width: largeur_bouton height: hauteur_bouton Rectangle { width: parent.width height: parent.height color: (model.Etat_systeme === 0) ? "transparent" : shipheart_couleur_fond_bouton // On ne peut pas mettre l'opacité sur celui-ci, sinon tous ses enfants sont aussi semi-transparents... radius: shipheart_rayon_bouton border.color: couleur_rouge border.width: (model.Etat_systeme === 0) ? 0 : 3 //------------------------------------------------------------------------------------------ // Zone de parametres (toute la partie gauche, hors consigne et hors cde AUTO s'il y en a : //------------------------------------------------------------------------------------------ Rectangle { id: zone_parametres x: 0 y: 0 width: ((model.Type_circuit === shipheart_type_module_shipbase) && (model.No_circuit === 0)) ? parent.width : // Cas du circuit #0 de ShipBase (model.Validation_cdes_events >= 0) ? // Cas général : (parent.width * pourcentage_largeur_zone_affichage_nom) - espace_interne : // Avec commandes AUTO parent.width * (1 - pourcentage_largeur_zone_affichage_consigne) // Sans commandes AUTO height: parent.height; color: (model.Etat_systeme === 0) ? shipheart_couleur_fond_bouton : "transparent" radius: shipheart_rayon_bouton Image { // Affichage du coin inférieur-droit en rouge ou orange si alarme ou alerte source: ( (Etat_circuit === shipheart_etat_circuit_limitation) || (Etat_circuit === shipheart_etat_circuit_protection) || (Etat_circuit === shipheart_etat_circuit_disjonte) || (Etat_circuit === shipheart_etat_circuit_absence_terre) || (Etat_circuit === shipheart_etat_circuit_absence_masse) ) ? "/images/coin_bas_droite_rouge.png" : "/images/coin_bas_droite_orange.png" // (Etat_commande_carte === shipheart_etat_commande_module_test) || // (Etat_commande_carte === shipheart_etat_commande_module_undervoltage) || // (Etat_circuit === shipheart_etat_circuit_cc_batterie) || // (Etat_circuit === shipheart_etat_circuit_deleste) || // (Etat_circuit === shipheart_etat_circuit_inversion_phase_neutre) || // (Etat_circuit === shipheart_etat_circuit_undervoltage) || // (Etat_events > 0) sourceSize.height: 20 anchors { bottom: parent.bottom right: parent.right } visible: ( (Etat_commande_carte !== shipheart_etat_commande_module_ok) || (Etat_circuit !== shipheart_etat_circuit_ok) || (Etat_events > 0) ) && (model.Etat_systeme === 0) // SDIR #285 } MouseArea { // Zone d'interaction Paramètres du circuit id: mouse_area_zone_parametres x: 0 y: 0 anchors.fill: parent onClicked: { shipheart_clic(); stackView.push("circuit.qml", {"id_circuit": model.Cle_primaire, "consigne": model.Consigne }) } } } //------------------------------------------------------- // Zone du nom (en haut à gauche et au milieu) : //------------------------------------------------------- Rectangle { id: nom color: "transparent" x: 0 y: 0 width: (parent.width * pourcentage_largeur_zone_affichage_nom) - espace_interne height: parent.height / 2; Text { text: model.Nom anchors.fill: parent // Permet que le texte occupe tout l'espace du parent (et que le centrage vertical qui suit fonctionne...) verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft leftPadding: 10 font.pixelSize: 15 font.weight: Font.Bold color: couleur_blanc_casse } } //------------------------------------------------------- // Zone de cdes auto (en haut au centre) : //------------------------------------------------------- Rectangle { id: cdes_auto x: parent.width * pourcentage_largeur_zone_affichage_nom y: 0; width: (parent.width * (1 - pourcentage_largeur_zone_affichage_nom - pourcentage_largeur_zone_affichage_consigne)); height: parent.height; radius: shipheart_rayon_bouton color: shipheart_couleur_fond_bouton visible: (model.Etat_systeme === 0) && (model.Validation_cdes_events >= 0) Text { text: "Auto" // Attention : Non traduit... anchors.fill: parent // Permet que le texte occupe tout l'espace du parent (et que le centrage vertical qui suit fonctionne...) verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter font.pixelSize: 15 font.weight: Font.Bold color : (model.Validation_cdes_events === 0) ? couleur_gris_moyen : couleur_green_yellow } MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille. id: mouse_area_cdes_auto x: 0 y: 0 width: parent.width height: parent.height pressAndHoldInterval: shipheart_mouse_press_and_hold_interval_long onPressAndHold: { shipheart_clic(); toggle_cdes_auto(); timer_home.restart(); // Permet de réarmer le timer (qui ne doit PAS être 'triggeredOnStart' !) afin de reporter la prochaine mise à jour à une période entière de timer. Cela évite qu'un raffraichissement arrive trop tôt, avant que la nouvelle consigne ne soit prise en compte => On>Off>On ou Off>On>Off... } } // Halo autour du bouton pendant l'appui : Rectangle { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } width: Math.max(parent.width, parent.height) + 100 height: width radius: width / 2 color : (model.Validation_cdes_events === 0) ? couleur_gris_moyen : couleur_green_yellow opacity: 0.2 visible: mouse_area_cdes_auto.pressed } } //------------------------------------------------------- // Zone du courant instantané (en bas à gauche) : //------------------------------------------------------- Rectangle { id: courant_instantane color: "transparent" // Sinon, le fond du rectangle est blanc... x: 0 y: hauteur_bouton / 2; width: parent.width * pourcentage_largeur_zone_affichage_nom; height: parent.height / 2; visible: (model.Etat_systeme === 0) ? (consigne_principale.text !== qsTr("Off")) : 0 Image { source: "/images/icone_consommation_electrique.png" sourceSize.height: 20 anchors.left: courant_instantane.left anchors.leftMargin: 5 anchors.verticalCenter: courant_instantane.verticalCenter } Text { text: (model.Type_circuit !== shipheart_type_module_shippower4AC ? "DC " + model.Tension.toFixed(2) + " V " + (model.Intensite > shipheart_plancher_intensite_circuit_sp8xx ? " | " + model.Intensite.toFixed(2) + " A | " + (model.Tension * model.Intensite).toFixed(0) + " W" : "") : "AC " + model.Tension.toFixed(0) + " V | " + model.Frequence.toFixed(1) + " Hz " + (model.Intensite > shipheart_plancher_intensite_circuit_sp4ac ? " | " + model.Intensite.toFixed(1) + " A | " + (model.Tension * model.Intensite).toFixed(0) + " VA" : "")) anchors.fill: parent // Permet que le texte occupe tout l'espace du parent (et que le centrage vertical qui suit fonctionne...) verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft leftPadding: 20 font.pixelSize: 12 color: couleur_gris_tres_tres_pale } } //------------------------------------------------------- // Zone de consigne (au milieu, à droite) : //------------------------------------------------------- Rectangle { id: consigne x: (parent.width * (1 - pourcentage_largeur_zone_affichage_consigne)) + espace_interne width: (parent.width * pourcentage_largeur_zone_affichage_consigne) - espace_interne height: parent.height; //color: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? ((model.Consigne === 0) ? couleur_rouge_transparent : couleur_vert_transparent) : "transparent" color: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? ((model.Consigne === 0) ? shipheart_couleur_fond_bouton : couleur_vert_transparent) : "transparent" // SDIR #207 radius: shipheart_rayon_bouton border.width: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? 0 : 3 border.color: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? // SDIR #182 ((model.Consigne === 0) ? couleur_rouge : couleur_green_yellow) : // SDIR #159. En pratique, inutile car dans ce cas, border.width=0 // ((model.Mode_test === 0) ? couleur_rouge : couleur_green_yellow) // SDIR #182 ((model.Mode_test === 0) ? shipheart_couleur_fond_bouton : couleur_green_yellow) // SDIR #182 & SDIR #207 visible: (model.Etat_systeme === 0) && ((model.Type_circuit !== shipheart_type_module_shipbase) || (model.No_circuit !== 0)) Text { id: consigne_principale text: (model.Etat_commande_carte === shipheart_etat_commande_module_undervoltage) ? "Off" : ((model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? ((model.Consigne === 0) ? qsTr("Off") : qsTr("On")) : ((model.Mode_test === 0) ? qsTr("Off") : qsTr("On"))) anchors.verticalCenter: consigne.verticalCenter anchors.verticalCenterOffset: ((model.Etat_commande_carte === shipheart_etat_commande_module_ok) && (model.Consigne > 0) && (model.Consigne < 100)) ? -10 : 0 anchors.horizontalCenter: consigne.horizontalCenter font.pixelSize: 20 font.weight: Font.Bold color: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? // SDIR #182 ((model.Consigne === 0) ? couleur_gris_pale : couleur_green_yellow) : // SDIR #159 & SDIR #207 ((model.Mode_test === 0) ? couleur_gris_pale : couleur_green_yellow) // SDIR #182 & SDIR #207 } Text { id: consigne_secondaire text: (model.Etat_commande_carte === shipheart_etat_commande_module_undervoltage) ? "" : ((model.Etat_commande_carte === shipheart_etat_commande_module_ok) ? ((model.Consigne === 0) ? "" : ((model.Consigne === 100) ? "" : (model.Consigne + "%"))) : "" ) anchors.top: consigne_principale.bottom anchors.horizontalCenter: consigne.horizontalCenter font.pixelSize: 16 color: (model.Consigne === 0) ? couleur_gris_pale : couleur_green_yellow // SDIR #159 & SDIR #207 } MouseArea { // Zone d'interaction. On est obligé de la mettre dans la grille pour que Rectangle et MouseArea soient frères ou parent/enfant ET qu'on n'occupe qu'un espace dans la grille. id: mouse_area_consigne anchors.fill: parent enabled: (model.Etat_commande_carte === shipheart_etat_commande_module_ok) // Si on est en Undelvoltage ou en Test, on rend le bouton inoppérant... pressAndHoldInterval: shipheart_mouse_press_and_hold_interval_long onClicked: { shipheart_clic(); var new_consigne; if (model.Consigne === 0) { if (model.Old_consigne === 0) new_consigne = 100; // Si OLD = 0, on passe la consigne à 100% else new_consigne = model.Old_consigne; // Sinon, on applique OLD à NEW } else new_consigne = 0; // Mise à jour de la nouvelle consigne : changement_consigne(new_consigne, -1); timer_home.restart(); // Permet de réarmer le timer (qui ne doit PAS être 'triggeredOnStart' !) afin de reporter la prochaine mise à jour à une période entière de timer. Cela évite qu'un raffraichissement arrive trop tôt, avant que la nouvelle consigne ne soit prise en compte => On>Off>On ou Off>On>Off... } onPressAndHold: { shipheart_clic(); if ((model.Consigne > 0) && (model.Consigne <100)) // On ne traite l'appui long que si on est ON [ET] en gradateur { // Mise à jour des nouvelles Consigne et Old_consigne : changement_consigne(100, 100); timer_home.restart(); // Permet de réarmer le timer (qui ne doit PAS être 'triggeredOnStart' !) afin de reporter la prochaine mise à jour à une période entière de timer. Cela évite qu'un raffraichissement arrive trop tôt, avant que la nouvelle consigne ne soit prise en compte => On>Off>On ou Off>On>Off... } } } } // Fin de 'Zone de consigne' //------------------------------------------------------- //------------------------------------------------------- // Zone d'interaction du circuit lorsque le circuit est ABSENT : //------------------------------------------------------- MouseArea { id: mouse_area_absence anchors.fill: parent width: largeur_bouton * pourcentage_largeur_zone_affichage_nom; height: hauteur_bouton; enabled: (model.Etat_systeme !== 0) onClicked: { shipheart_clic(); stackView.push("circuit.qml", {"id_circuit": model.Cle_primaire }) } } // Fin de 'mouse_area_absence' //------------------------------------------------------- } //============================================================================================================= // Mise à jour de la valeuer de consigne //============================================================================================================= function changement_consigne(new_consigne, old_consigne) { var req; // Mise à jour immédiate du modèle pour que l'affichage réagisse immédiatement : modele_circuits.setProperty(index , "Consigne", new_consigne); // Mise à jour dans la BDD : req = "UPDATE TB_Circuits SET New_consigne=" + new_consigne + " "; if (old_consigne !== -1) req += ", Old_consigne=" + old_consigne + " "; req += " WHERE Cle_primaire='" + model.Cle_primaire + "'"; //console.log("Requête = [" + req + "]"); bdd.requete_unique(req); synchro_bdd(shipheart_type_synchro_data); } //============================================================================================================= // Mise à jour de Cdes Auto //============================================================================================================= function toggle_cdes_auto() { var req; var mode; if (model.Validation_cdes_events === 0) mode = 1; else mode = 0; // Mise à jour immédiate du modèle pour que l'affichage réagisse immédiatement : modele_circuits.setProperty(index , "Validation_cdes_events", mode); // Mise à jour dans la BDD : bdd.requete_unique("UPDATE TB_Circuits SET Validation_cdes_events=" + mode + " WHERE Cle_primaire='" + model.Cle_primaire + "'") // Note : le modèle sera ensuite remis à jour par la routine périodique dans HOME. en l'occurence, le modèle sera déjà à jour sur ce champ... } }