1/**
2 * \file AbstractSettingsPage.qml
3 * Base component for settings page.
4 *
5 * \b Project: Kid3
6 * \author Urs Fleisch
7 * \date 16 Feb 2015
8 *
9 * Copyright (C) 2015-2018  Urs Fleisch
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; version 3.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24import QtQuick 2.11
25import QtQuick.Layouts 1.11
26import QtQuick.Controls 2.4
27
28Page {
29  id: page
30
31  signal clicked(int index)
32  property list<SettingsElement> model
33
34  function activateAll() {
35    for (var i = 0; i < model.length; i++) {
36      if (model[i].onActivated) {
37        model[i].onActivated()
38      }
39    }
40  }
41
42  function deactivateAll() {
43    for (var i = 0; i < model.length; i++) {
44      if (model[i].onDeactivated) {
45        model[i].onDeactivated()
46      }
47    }
48  }
49
50  header: ToolBar {
51    IconButton {
52      id: prevButton
53      anchors.left: parent.left
54      anchors.verticalCenter: parent.verticalCenter
55      iconName: "go-previous"
56      color: titleLabel.color
57      width: visible ? height : 0
58      visible: page.StackView.view && page.StackView.view.depth > 1
59      onClicked: page.StackView.view.pop()
60    }
61    Label {
62      id: titleLabel
63      anchors.left: prevButton.right
64      anchors.right: parent.right
65      anchors.verticalCenter: parent.verticalCenter
66      clip: true
67      text: page.title
68    }
69  }
70
71  Item {
72    anchors.fill: parent
73
74    Component {
75      id: booleanDelegate
76      SettingsItem {
77        text: _modelData.name
78        control: CheckBox {
79          checked: _modelData.value
80          onClicked: _modelData.value = checked
81        }
82      }
83    }
84    Component {
85      id: booleanEditDelegate
86      SettingsItem {
87        id: settingsItem
88        text: _modelData.name
89        control: RowLayout {
90          IconButton {
91            iconName: "edit"
92            color: settingsItem.labelColor
93            onClicked: _modelData.onEdit()
94          }
95          CheckBox {
96            checked: _modelData.value
97            onClicked: _modelData.value = checked
98          }
99        }
100      }
101    }
102    Component {
103      id: stringDelegate
104      SettingsItem {
105        text: _modelData.name
106        control: TextField {
107          width: Math.min(_modelData.width || constants.gu(40), page.width - 2 * constants.margins)
108          text: _modelData.value
109          selectByMouse: true
110          onAccepted: {
111            focus = false
112          }
113          onActiveFocusChanged: {
114            if (!activeFocus) {
115              _modelData.value = text
116            }
117          }
118        }
119      }
120    }
121    Component {
122      id: numberDelegate
123      SettingsItem {
124        text: _modelData.name
125        control: TextField {
126          width: Math.min(_modelData.width || constants.gu(40), page.width - 2 * constants.margins)
127          text: _modelData.value
128          selectByMouse: true
129          onAccepted: {
130            focus = false
131          }
132          onActiveFocusChanged: {
133            if (!activeFocus) {
134              var nr = parseInt(text)
135              if (!isNaN(nr)) {
136                _modelData.value = nr
137              }
138            }
139          }
140        }
141      }
142    }
143    Component {
144      id: selectionDelegate
145      SettingsItem {
146        text: _modelData.name
147        control: ComboBox {
148          width: Math.min(_modelData.width || constants.gu(40), page.width - 2 * constants.margins)
149          currentIndex: _modelData.value
150          model: _modelData.dropDownModel
151          onCurrentIndexChanged: _modelData.value = currentIndex
152        }
153      }
154    }
155    Component {
156      id: selectionEditDelegate
157      SettingsItem {
158        id: settingsItem
159        text: _modelData.name
160        control: RowLayout {
161          width: Math.min(_modelData.width || constants.gu(40), page.width - 2 * constants.margins)
162          IconButton {
163            iconName: "edit"
164            color: settingsItem.labelColor
165            onClicked: _modelData.onEdit()
166          }
167          ComboBox {
168            Layout.fillWidth: true
169            currentIndex: _modelData.value
170            model: _modelData.dropDownModel
171            onCurrentIndexChanged: _modelData.value = currentIndex
172          }
173        }
174      }
175    }
176    Component {
177      id: clickDelegate
178      Standard {
179        text: _modelData.name
180        progression: true
181        onClicked: page.clicked(_index)
182      }
183    }
184
185    ListView {
186      id: listView
187
188      clip: true
189      anchors.fill: parent
190      model: page.model
191      delegate: Loader {
192        width: ListView.view.width
193        property int _index: index
194        property variant _modelData: modelData
195        sourceComponent:
196            if (modelData.dropDownModel)
197              if (onEdit)
198                selectionEditDelegate
199              else
200                selectionDelegate
201            else if (typeof modelData.value === "boolean")
202              if (onEdit)
203                booleanEditDelegate
204              else
205                booleanDelegate
206            else if (typeof modelData.value === "string")
207              stringDelegate
208            else if (typeof modelData.value === "number")
209              numberDelegate
210            else
211              clickDelegate
212      }
213    }
214  }
215}
216