//======================================================================================================================================================================== // CONFIG_CIRCUITS.QML // Ce fichier traite la configuration des circuits. La page permet notamment de : // - Afficher, pour tous les circuits déjà configurés (et donc d'accéder à la configuration détaillée de l'un d'eux ; ou sa création) // - Accéder au menu de changement de l'ordre d'affichage sur la page d'accueil // La page est appelée depuis la page PARAMETRES_AVANCES, en cliquant sur "Circuits" //======================================================================================================================================================================== import QtQuick 2.12 import QtQuick.Controls 2.12 import qt.koriolan.shipheart 1.0 Shipheart_page { id: page_config_circuits // Mis en forme : readonly property double affichage_hauteur_utile: shipheart_hauteur_page - shipheart_hauteur_bandeau_haut - shipheart_hauteur_bandeau_bas readonly property int hauteur_bouton_droit: 80 readonly property double pourcentage_largeur_colonne_gauche: 0.75 readonly property int espace_colonnes_principales: 20 readonly property double pourcentage_bandeau_bas_largeur_zone_retour: 1.0 readonly property int nombre_circuits_affiches_sur_une_colonne: 8 readonly property int periode_init_raffraichissement_parametres: 1 // En ms readonly property int periode_raffraichissement_parametres: 100 // En ms // Affichage : property int niveau_page: 0 property bool bouton_bandeau_bas_zone_retour_actif: false // Modèles : // Note : les modèles chargés dans 'main.qml' n'ont pas à être rechargés dans les pages suivantes //=========================================================== // Timer periode raffraichissement parametres : //=========================================================== Timer { id: timer_raffraichissement_parametres interval: periode_init_raffraichissement_parametres triggeredOnStart: false running: true repeat: true onTriggered: { if (interval == periode_init_raffraichissement_parametres) // Premier passage, 1ms après le premier chargement { interval = periode_raffraichissement_parametres; init_page(); } if (stackView.depth === (niveau_page + 1)) // Désactive le raffraichissement quand la page n'est pas activée dans la pile { if (!bouton_bandeau_bas_zone_retour_actif) { } } } } //=========================================================== // Lorsque la page est sur le point d'être affichée dans la pile : //=========================================================== StackView.onActivating: { mise_a_jour_donnees(); // Permet que lors du retour sur la page, l'état des différentes variables soit mise à jour avant l'affichage proprement dit. } // Titre de la page : Shipheart_titre_1 {titre:qsTr("Configuration des circuits"); hauteur: shipheart_hauteur_bandeau_haut} //------------------------------------------------------- // Ecran de gauche (liste des circuits) : //------------------------------------------------------- Rectangle { id: zone_affichage_gauche x: 0 y: shipheart_hauteur_bandeau_haut; width: (shipheart_largeur_page * pourcentage_largeur_colonne_gauche) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" //------------------------------------------------------------------- // Grille pour afficher les circuits : GridView { id: grille_principale width: parent.width height: parent.height cellWidth: parent.width; cellHeight: height / nombre_circuits_affiches_sur_une_colonne snapMode: GridView.SnapToRow // L'arret de l'affichage se fera sur une rangée entière clip: true // Nécessaire pour que les Delegates s'arretent à l'intérieur de la GridView model: modele_grille_principale delegate: Rectangle { width: grille_principale.cellWidth height: grille_principale.cellHeight color: "transparent" // Ajout d'une ligne de sous-titre avec le nom du famille de capteurs si c'est le premier capteur de la famille : Shipheart_titre_3 {titre:model.nom_famille; hauteur: (affichage_hauteur_utile / nombre_circuits_affiches_sur_une_colonne); visible: (model.nom_famille !== "")} Rectangle { // c'est le bouton proprement dit... height: parent.height - 10 width:parent.width - 10 color: (model.adresse_module >= 0) ? shipheart_couleur_fond_bouton : couleur_rouge_transparent radius: shipheart_rayon_bouton border.color: couleur_rouge border.width: ((model.etat_systeme === 0) && (model.adresse_module >= 0)) ? 0 : 3 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter visible: (model.nom_famille === "") // Nom du circuit : Text { anchors.fill: parent horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter leftPadding: 20 text: model.nom color: couleur_blanc_casse font.pixelSize: 18 wrapMode: Label.Wrap } // Triangle bleu indiquant un circuit masqué : Image { id: image_circuit_masque // Affichage du coin inférieur-droit en couleur si le circuit est masqué source: "/images/coin_bas_droite_bleu_koriolan.png" sourceSize.height: 20 anchors { bottom: parent.bottom right: parent.right } visible: model.flag_masque ? true : false } MouseArea{ anchors.fill : parent enabled : !grille_principale.moving // Permet de bloquer le Mousearea pendant le déplacement de la grille onReleased: { // Permet déclencher à la fin d'un clic (court) sans mouvement shipheart_clic(); stackView.push("config_circuit.qml", {"id_circuit": model.id}) } } } } ListModel { id: modele_grille_principale } Label { anchors.fill: parent horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter visible: parent.count === 0 text: qsTr("Aucun circuit n'est encore configuré...") color: couleur_rouge_transparent font.pixelSize: 15 font.bold: true wrapMode: Label.Wrap } } } //------------------------------------------------------- // Ecran Droite : //------------------------------------------------------- Rectangle { id: zone_affichage_droite x: zone_affichage_gauche.width + espace_colonnes_principales y: shipheart_hauteur_bandeau_haut + 5; // Le +5 permet d'aligner le haut du premier bouton de droite avec le haut du premier bouton de la liste de gauche ( width: (shipheart_largeur_page * (1 - pourcentage_largeur_colonne_gauche)) - (espace_colonnes_principales / 2) height: affichage_hauteur_utile color: "transparent" Column { anchors.fill: parent spacing: 10 //---------------------- // Bouton + : Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: !clavier.active Text { anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } font.pixelSize: 40 text: qsTr("+") color: couleur_blanc_casse } MouseArea { anchors.fill: parent onClicked: { shipheart_clic(); stackView.push("config_circuit.qml"); } } } //---------------------- // Bouton tri : Rectangle { width: parent.width height: hauteur_bouton_droit color: shipheart_couleur_fond_bouton radius: shipheart_rayon_bouton visible: !clavier.active // && (modele_grille_principale.count > 1) // SDIR #258 Image { id: image_parametres source: "/images/tri.png" sourceSize.height: 25 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } } MouseArea { anchors.fill: parent onClicked: { shipheart_clic(); stackView.push("config_ordre_elements.qml", {"table": "TB_Circuits"}) } } } } } //------------------------------------------------------- // Bandeau bas : //------------------------------------------------------- Row { x: 0 y: shipheart_hauteur_page - shipheart_hauteur_bandeau_bas; width: shipheart_largeur_page; height: shipheart_hauteur_bandeau_bas; padding: 5 spacing: 5 //................................................. // Bouton retour //................................................. Rectangle { id: bandeau_bas_zone_retour width: (parent.width * pourcentage_bandeau_bas_largeur_zone_retour) - (2 * parent.padding) height: shipheart_hauteur_bandeau_bas - parent.topPadding - parent.bottomPadding; radius: shipheart_rayon_bouton color: shipheart_couleur_fond_bouton Image { source: "/images/icone_retour.png" sourceSize.height: 30 anchors { verticalCenter: parent.verticalCenter horizontalCenter: parent.horizontalCenter } } 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_bandeau_bas_zone_retour anchors.fill: parent onClicked: { shipheart_clic(); stackView.pop() } } } } // Note : il est inutile de prévoir un Mousearea pour sortir de l'économiseur sur cette page puisqu'il // est systématiquement bloqué pour toutes les pages lancées depuis 'Paramètres Avancés'. //============================================================================================================= // Init de la page //============================================================================================================= function init_page() { niveau_page = stackView.depth - 1; // Permet de stocker le niveau de la page dans la Stackview mise_a_jour_donnees(); } //============================================================================================================= // Mise à jour des données //============================================================================================================= function mise_a_jour_donnees() { var req, res; var sous_req, sous_res; var i, j; var nb_circuits; var prec_famille; // Grille principale (liste des capteurs configurés) : modele_grille_principale.clear(); // Recherche des valeurs en BDD : req = ' SELECT Cle_primaire, '; req += ' Adresse_module, ' req += ' Etat_systeme, ' req += ' Nom, '; req += ' Nom_famille, '; req += ' Priorite_affichage_accueil '; req += ' FROM TB_Circuits, '; req += ' (SELECT Cle_primaire AS Cle_famille, Nom AS Nom_famille, Priorite_affichage AS Priorite_famille '; req += ' FROM TB_Familles WHERE Type_source=' + shipheart_type_source_circuits + ') AS TB_Familles '; req += ' WHERE ID_Famille=Cle_famille '; req += ' AND ID_Circuit_esclave>=0 '; // On n'affiche tout simplement pas les circuits esclaves... req += ' ORDER BY Priorite_famille, ABS(Priorite_affichage_accueil)'; //console.log("Requête = [ " + req + "; ]"); nb_circuits = bdd.requete(req); prec_famille = ""; // Boucle sur tous les capteurs : for (i = 0; i < nb_circuits; i ++) { res = bdd.lecture_ligne(); if (!res.isEmpty) { // Récup de toutes les données du capteur (pas forcément super efficace mais BEAUCOUP plus simple à maintenir...) : j = 0; var cle_primaire = Number(res[j++]); var adresse_module = Number(res[j++]); var etat_systeme = Number(res[j++]); var nom = res[j++]; var nom_famille = res[j++]; var priorite_affichage_accueil = Number(res[j++]); // Ajout de le ligne de famille : if (prec_famille !== nom_famille) { modele_grille_principale.append({ "nom_famille": nom_famille, "id": 0, "adresse_module": 0, "etat_systeme": 0, "nom": "", "flag_masque": false} ); prec_famille = nom_famille; } // Entrée normale : modele_grille_principale.append({ "nom_famille": "", "id": cle_primaire, "adresse_module": adresse_module, "etat_systeme": etat_systeme, "nom": nom, "flag_masque": (priorite_affichage_accueil < 1) ? true : false } ); } else break; // Ne devrait pas arriver.... } } }