Warning, /education/gcompris/src/core/GCDialog.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - GCDialog.qml 0002 * 0003 * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import GCompris 1.0 0012 0013 /** 0014 * A QML component for GCompris dialogs. 0015 * @ingroup components 0016 * 0017 * Contains the following basic layout elements: Title (message), a GCompris 0018 * cancel button (GCButtonCancel) at the top right and two optional buttons. 0019 * 0020 * Can be conveniently instantiated dynamically in conjunction with 0021 * showMessageDialog from core.js. 0022 * 0023 * GCDialog should now be used wherever you'd use a QtQuick dialog. It has 0024 * been decided to implement dialogs ourselves in GCompris because of 0025 * missing translations of labels of Qt's standard buttons for some language 0026 * supported by GCompris, as well as integration problems on some OSes 0027 * (Sailfish OS). 0028 * 0029 * @inherit QtQuick.Item 0030 * @sa showMessageDialog 0031 */ 0032 Rectangle { 0033 id: gcdialog 0034 color: "#B2808080" 0035 property int baseMargins: 5 * ApplicationInfo.ratio 0036 0037 /** 0038 * type:string 0039 * Heading instruction text. 0040 */ 0041 property alias message: instructionTxt.textIn 0042 0043 /** 0044 * type:string 0045 * Label of the first button. 0046 */ 0047 property alias button1Text: button1.text 0048 0049 /** 0050 * type:string 0051 * Label of the second button. 0052 */ 0053 property alias button2Text: button2.text 0054 0055 /** 0056 * type:bool 0057 * Check is the dialog can be destroyed 0058 */ 0059 property bool isDestructible: true 0060 0061 /** 0062 * type:bool 0063 * Set to true after clicking on one of the options 0064 */ 0065 property bool alreadyClicked: false 0066 0067 /** 0068 * Emitted when the dialog should be started. 0069 * 0070 * Triggers fading in. 0071 */ 0072 signal start 0073 0074 /** 0075 * Emitted when the dialog should be stopped. 0076 * 0077 * Triggers fading out. 0078 */ 0079 signal stop 0080 0081 /** 0082 * Emitted when the dialog has stopped. 0083 */ 0084 signal close 0085 0086 /** 0087 * Emitted when the first button has been clicked. 0088 */ 0089 signal button1Hit 0090 0091 /** 0092 * Emitted when the second button has been clicked. 0093 */ 0094 signal button2Hit 0095 0096 /** 0097 * type:Component 0098 * Content component which holds the optional content 0099 * after instructionText 0100 */ 0101 property Component content 0102 0103 focus: true 0104 opacity: 0 0105 0106 onVisibleChanged: { 0107 if(visible) { 0108 gcdialog.forceActiveFocus(); 0109 parent.Keys.enabled = false; 0110 } 0111 } 0112 0113 anchors { 0114 fill: parent 0115 } 0116 0117 onStart: { 0118 opacity = 1; 0119 gcdialog.forceActiveFocus(); 0120 parent.Keys.enabled = false; 0121 alreadyClicked = false; 0122 } 0123 onStop: { 0124 opacity = 0; 0125 parent.Keys.enabled = true; 0126 parent.forceActiveFocus(); 0127 } 0128 onClose: { 0129 if(isDestructible) 0130 destroy(); 0131 } 0132 0133 Behavior on opacity { NumberAnimation { duration: 200 } } 0134 onOpacityChanged: opacity === 0 ? close() : null 0135 0136 z: 1500 0137 0138 MultiPointTouchArea { 0139 // Just to catch mouse events 0140 anchors.fill: parent 0141 } 0142 0143 /* Message */ 0144 Item { 0145 id: instruction 0146 anchors { 0147 horizontalCenter: parent.horizontalCenter 0148 top: parent.top 0149 topMargin: buttonCancel.height + 2 * gcdialog.baseMargins 0150 bottom: parent.bottom 0151 bottomMargin: gcdialog.baseMargins 0152 } 0153 width: parent.width * 0.8 0154 0155 Rectangle { 0156 id: instructionTxtBg 0157 anchors.top: instruction.top 0158 width: parent.width 0159 height: instruction.height - button1.height * 3 - gcdialog.baseMargins * 3 0160 radius: gcdialog.baseMargins 0161 border.width: 2 * ApplicationInfo.ratio 0162 border.color: "white" 0163 color: "#EEEEEEEE" 0164 0165 Flickable { 0166 id: instructionFlick 0167 flickDeceleration: 1500 0168 anchors.fill: parent 0169 anchors.margins: gcdialog.baseMargins 0170 flickableDirection: Flickable.VerticalFlick 0171 clip: true 0172 contentHeight: instructionTxt.height + extraLoader.height + 15 * ApplicationInfo.ratio 0173 0174 GCText { 0175 id: instructionTxt 0176 fontSize: regularSize 0177 color: "#191919" 0178 anchors.horizontalCenter: parent.horizontalCenter 0179 // need to remove the anchors (left and right) else sometimes text is hidden on the side 0180 width: instructionFlick.width 0181 wrapMode: TextEdit.WordWrap 0182 textFormat: TextEdit.RichText 0183 text: style + "<body>" + textIn + "</body>" 0184 property string textIn 0185 property string style: "<HEAD><STYLE type='text/css'>A {color: #191919;}</STYLE></HEAD>" 0186 } 0187 Loader { 0188 id: extraLoader 0189 anchors.top: instructionTxt.bottom 0190 anchors.topMargin: gcdialog.baseMargins 0191 active: gcdialog.content != null 0192 sourceComponent: gcdialog.content 0193 width: instructionFlick.width 0194 } 0195 } 0196 // The scroll buttons 0197 GCButtonScroll { 0198 id: scrollInstructions 0199 opacity: 0.7 0200 visible: instructionFlick.contentHeight > instructionFlick.height 0201 anchors.right: parent.right 0202 anchors.rightMargin: 5 * ApplicationInfo.ratio 0203 anchors.bottom: parent.bottom 0204 anchors.bottomMargin: 5 * ApplicationInfo.ratio 0205 onUp: instructionFlick.flick(0, 1000) 0206 onDown: instructionFlick.flick(0, -1000) 0207 upVisible: instructionFlick.atYBeginning ? false : true 0208 downVisible: instructionFlick.atYEnd ? false : true 0209 } 0210 } 0211 0212 Rectangle { 0213 id: buttonSelector 0214 width: gcdialog.width 0215 height: button1.height + gcdialog.baseMargins * 2 0216 color: "#803ACAFF" 0217 visible: false 0218 } 0219 0220 GCButton { 0221 id: button1 0222 width: parent.width 0223 height: (visible ? 60 : 30) * ApplicationInfo.ratio 0224 anchors { 0225 horizontalCenter: parent.horizontalCenter 0226 top: instructionTxtBg.bottom 0227 topMargin: 10 0228 } 0229 theme: "highContrast" 0230 visible: text != "" 0231 property bool selected: false; 0232 enabled: !gcdialog.alreadyClicked 0233 onClicked: { 0234 gcdialog.alreadyClicked = true; 0235 gcdialog.button1Hit() 0236 gcdialog.stop() 0237 } 0238 } 0239 0240 GCButton { 0241 id: button2 0242 width: parent.width 0243 height: (visible ? 60 : 30) * ApplicationInfo.ratio 0244 anchors { 0245 horizontalCenter: parent.horizontalCenter 0246 top: button1.bottom 0247 topMargin: 10 0248 } 0249 theme: "highContrast" 0250 visible: text != "" 0251 property bool selected: false; 0252 enabled: !gcdialog.alreadyClicked 0253 onClicked: { 0254 gcdialog.alreadyClicked = true; 0255 gcdialog.button2Hit() 0256 gcdialog.stop() 0257 } 0258 } 0259 0260 states: [ 0261 State { 0262 name: "button1Selected" 0263 when: button1.selected 0264 PropertyChanges { 0265 target: buttonSelector 0266 anchors.centerIn: button1 0267 visible: true 0268 } 0269 }, 0270 State { 0271 name: "button2Selected" 0272 when: button2.selected 0273 PropertyChanges { 0274 target: buttonSelector 0275 anchors.centerIn: button2 0276 visible: true 0277 } 0278 } 0279 ] 0280 } 0281 0282 Keys.onEscapePressed: { 0283 buttonCancel.close(); 0284 } 0285 0286 Keys.onTabPressed: { 0287 return; 0288 } 0289 0290 Keys.onPressed: { 0291 if(event.key === Qt.Key_Up || event.key === Qt.Key_Left) { 0292 if(button2.visible && !button1.selected && !button2.selected) { 0293 button2.selected = true; 0294 } else if(button2.visible) { 0295 button2.selected = !button2.selected; 0296 button1.selected = !button1.selected; 0297 } else if(button1.visible) { 0298 button1.selected = true; 0299 } 0300 } 0301 if(event.key === Qt.Key_Down || event.key === Qt.Key_Right) { 0302 if(button1.visible && !button1.selected && !button2.selected) { 0303 button1.selected = true; 0304 } else if(button2.visible) { 0305 button1.selected = !button1.selected; 0306 button2.selected = !button2.selected; 0307 } else if(button1.visible) { 0308 button1.selected = true; 0309 } 0310 } 0311 if(event.key === Qt.Key_Enter || event.key === Qt.Key_Return || event.key === Qt.Key_Space) { 0312 event.accepted = true; 0313 if(button1.selected) { 0314 button1.clicked(); 0315 } else if(button2.selected) { 0316 button2.clicked(); 0317 } else { 0318 buttonCancel.close(); 0319 } 0320 } 0321 } 0322 0323 Keys.onReleased: { 0324 if(event.key === Qt.Key_Back) { 0325 buttonCancel.close(); 0326 event.accepted = true; 0327 } 0328 } 0329 0330 // The cancel button 0331 GCButtonCancel { 0332 id: buttonCancel 0333 anchors.margins: 5 * ApplicationInfo.ratio 0334 onClose: { 0335 if(button2.visible) 0336 button2.clicked(); 0337 else if(button1.visible) 0338 button1.clicked(); 0339 else 0340 parent.stop(); 0341 } 0342 } 0343 }