Skip to content
Snippets Groups Projects
Commit 4d8b006c authored by Aline Gondim Santos's avatar Aline Gondim Santos
Browse files

settingssidepanel: use ListView

Change-Id: I034edd72522badee2adb1ca558518854938b6deb
parent 58a96d14
No related branches found
No related tags found
No related merge requests found
...@@ -26,13 +26,13 @@ QtObject { ...@@ -26,13 +26,13 @@ QtObject {
// The number of views loaded (`views` is only resized). // The number of views loaded (`views` is only resized).
function viewCount() { function viewCount() {
return Object.keys(views).length; return Object.keys(views).length
} }
// Destroy all views. // Destroy all views.
function destroyAllViews() { function destroyAllViews() {
for (var path in views) { for (var path in views) {
destroyView(path); destroyView(path)
} }
} }
...@@ -40,50 +40,50 @@ QtObject { ...@@ -40,50 +40,50 @@ QtObject {
if (views.hasOwnProperty(path)) { if (views.hasOwnProperty(path)) {
// an instance of <path> already exists // an instance of <path> already exists
if (cb !== null) { if (cb !== null) {
cb(views[path]); cb(views[path])
} }
return views[path]; return views[path]
} }
const component = Qt.createComponent(Qt.resolvedUrl(path)); const component = Qt.createComponent(Qt.resolvedUrl(path))
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
const obj = component.createObject(parent, props); const obj = component.createObject(parent, props)
if (obj === null) { if (obj === null) {
print("error creating object"); print("error creating object")
return null; return null
} }
views[path] = obj; views[path] = obj
// Set the view name to the object name if it has one. // Set the view name to the object name if it has one.
const viewName = obj.objectName.toString() !== '' ? obj.objectName : path.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""); const viewName = obj.objectName.toString() !== '' ? obj.objectName : path.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "")
viewPaths[viewName] = path; viewPaths[viewName] = path
if (cb !== null) { if (cb !== null) {
cb(obj); cb(obj)
} }
return views[path]; return views[path]
} }
print("error creating component", path); print("error creating component", path)
console.error(component.errorString()); console.error(component.errorString())
Qt.exit(1); Qt.exit(1)
return null; return null
} }
function destroyView(path) { function destroyView(path) {
// The view may already have been destroyed. // The view may already have been destroyed.
if (!views.hasOwnProperty(path)) { if (!views.hasOwnProperty(path)) {
return false; return false
} }
views[path].destroy(); views[path].destroy()
delete views[path]; delete views[path]
// Remove the view name from the viewPaths map. // Remove the view name from the viewPaths map.
for (var viewName in viewPaths) { for (var viewName in viewPaths) {
if (viewPaths[viewName] === path) { if (viewPaths[viewName] === path) {
delete viewPaths[viewName]; delete viewPaths[viewName]
break; break
} }
} }
return true; return true
} }
function getView(viewName) { function getView(viewName) {
return views[viewPaths[viewName]] || null; return views[viewPaths[viewName]] || null
} }
} }
...@@ -32,47 +32,14 @@ SidePanelBase { ...@@ -32,47 +32,14 @@ SidePanelBase {
color: JamiTheme.backgroundColor color: JamiTheme.backgroundColor
property int currentIndex property int currentIndex
property bool isSinglePane
function createChild() {
if (page.menu === undefined) {
return;
}
page.menu.createChild();
}
Page {
id: page
anchors.fill: parent
background: null
header: AccountComboBox {
}
// Bind to requests for a settings page to be selected via shorcut.
Connections {
target: JamiQmlUtils
function onSettingsPageRequested(index) {
viewCoordinator.present("SettingsView");
root.indexSelected(index);
root.currentIndex = index;
}
}
property var menu: undefined
Flickable {
id: flick
width: root.width
height: childrenRect.height
clip: true
contentHeight: col.implicitHeight
function getHeaders() { function getHeaders() {
return [{ return [{
"title": JamiStrings.accountSettingsMenuTitle, "title": JamiStrings.accountSettingsMenuTitle,
"icon": JamiResources.account_24dp_svg, "icon": JamiResources.account_24dp_svg,
"first": 0,
"last": 4,
"children": [{ "children": [{
"id": 0, "id": 0,
"title": JamiStrings.manageAccountSettingsTitle "title": JamiStrings.manageAccountSettingsTitle
...@@ -82,7 +49,7 @@ SidePanelBase { ...@@ -82,7 +49,7 @@ SidePanelBase {
}, { }, {
"id": 2, "id": 2,
"title": JamiStrings.linkedDevicesSettingsTitle, "title": JamiStrings.linkedDevicesSettingsTitle,
"visible": "isJamiAccount" "visible": CurrentAccount.type !== Profile.Type.SIP
}, { }, {
"id": 3, "id": 3,
"title": JamiStrings.callSettingsTitle "title": JamiStrings.callSettingsTitle
...@@ -93,6 +60,8 @@ SidePanelBase { ...@@ -93,6 +60,8 @@ SidePanelBase {
}, { }, {
"title": JamiStrings.generalSettingsTitle, "title": JamiStrings.generalSettingsTitle,
"icon": JamiResources.gear_black_24dp_svg, "icon": JamiResources.gear_black_24dp_svg,
"first": 5,
"last": 11,
"children": [{ "children": [{
"id": 5, "id": 5,
"title": JamiStrings.system "title": JamiStrings.system
...@@ -114,11 +83,13 @@ SidePanelBase { ...@@ -114,11 +83,13 @@ SidePanelBase {
}, { }, {
"id": 11, "id": 11,
"title": JamiStrings.updatesTitle, "title": JamiStrings.updatesTitle,
"visible": "isUpdatable" "visible": UpdateManager.isUpdaterEnabled()
}] }]
}, { }, {
"title": JamiStrings.audioVideoSettingsTitle, "title": JamiStrings.audioVideoSettingsTitle,
"icon": JamiResources.media_black_24dp_svg, "icon": JamiResources.media_black_24dp_svg,
"first": 12,
"last": 14,
"children": [{ "children": [{
"id": 12, "id": 12,
"title": JamiStrings.audio "title": JamiStrings.audio
...@@ -132,6 +103,8 @@ SidePanelBase { ...@@ -132,6 +103,8 @@ SidePanelBase {
}, { }, {
"title": JamiStrings.pluginSettingsTitle, "title": JamiStrings.pluginSettingsTitle,
"icon": JamiResources.plugins_24dp_svg, "icon": JamiResources.plugins_24dp_svg,
"first": 15,
"last": 15,
"children": [{ "children": [{
"id": 15, "id": 15,
"title": JamiStrings.pluginSettingsTitle "title": JamiStrings.pluginSettingsTitle
...@@ -139,127 +112,138 @@ SidePanelBase { ...@@ -139,127 +112,138 @@ SidePanelBase {
}]; }];
} }
Column { function updateModel() {
id: col if (visible) {
anchors.left: parent.left listView.model = {}
Component.onCompleted: { listView.model = getHeaders()
page.menu = clv.createObject(this, {
"base": flick.getHeaders()
});
} }
} }
Component {
id: clv
Repeater {
id: repeater
property var base: ({}) Connections {
property var selected: null target: UtilsAdapter
model: Object.keys(base)
Layout.fillWidth: true
function createChild() { function onChangeLanguage() {
itemAt(0).children[0].createChild(); updateModel()
root.currentIndex = 0;
} }
ColumnLayout {
id: clvButtons
spacing: 0
Layout.fillWidth: true
PushButton {
id: btn
property var sprite: null
property bool showFocusMargin: true
property var isChildren: {
var ob = base[modelData];
var c = ob["children"];
return c === undefined;
} }
function updateVisibility() { // Bind to requests for a settings page to be selected via shorcut.
var currentVisibility = visible; Connections {
var ob = base[modelData]; target: JamiQmlUtils
var c = ob["visible"]; function onSettingsPageRequested(index) {
if (c === undefined) viewCoordinator.present("SettingsView")
return true; root.indexSelected(index)
var res = false; root.currentIndex = index
if (c === "isUpdatable") {
res = UpdateManager.isUpdaterEnabled();
} else if (c === "isJamiAccount") {
res = CurrentAccount.type !== Profile.Type.SIP;
} else {
console.warn("Visibility condition not managed");
}
if (currentVisibility !== res && root.currentIndex === ob["id"]) {
// If a menu disappears, go to the first index
root.currentIndex = 0;
root.indexSelected(0);
} }
return res;
} }
function createChild() { onIsSinglePaneChanged: {
var ob = base[modelData]; if (visible && !isSinglePane)
if (sprite === null) { select(root.currentIndex)
//deselect the current selection and collapse menu
if (repeater.selected)
repeater.selected.destroy();
var c = ob["children"];
if (c !== undefined) {
sprite = clv.createObject(parent, {
"base": c
});
repeater.selected = sprite;
indexSelected(c[0]["id"]);
root.currentIndex = c[0]["id"];
} else {
indexSelected(ob["id"]);
root.currentIndex = ob["id"];
} }
function open(index) {
indexSelected(index)
root.currentIndex = index
} }
function select(index) {
if (!root.isSinglePane)
indexSelected(index)
root.currentIndex = index
} }
visible: updateVisibility() Page {
id: page
property bool isOpen: !isChildren && sprite != null anchors.fill: parent
property bool isChildOpen: isChildren && (base[modelData]["id"] === root.currentIndex)
alignement: Text.AlignLeft background: null
Layout.preferredWidth: root.width - (isChildren ? 28 : 0)
Layout.leftMargin: isChildren ? 28 : 0
preferredLeftMargin: isChildren ? 47 : 25
imageContainerWidth: !isChildren ? 30 : 0 header: AccountComboBox {
height: isChildren ? JamiTheme.settingsMenuChildrenButtonHeight : JamiTheme.settingsMenuHeaderButtonHeight }
ListView {
id: listView
width: page.width
height: page.height
clip: true
contentHeight: contentItem.childrenRect.height
model: getHeaders()
delegate: ColumnLayout {
id: col
width: page.width
property bool isChildSelected: root.currentIndex >= modelData.first && root.currentIndex <= modelData.last
PushButton {
buttonText: modelData.title
circled: false circled: false
radius: 0 radius: 0
buttonText: { alignement: Text.AlignLeft
return base[modelData]["title"]; Layout.preferredWidth: parent.width
} Layout.leftMargin: 0
preferredLeftMargin: 25
buttonTextFont.pixelSize: !isChildren ? JamiTheme.settingsDescriptionPixelSize : JamiTheme.settingMenuPixelSize imageContainerWidth: 30
buttonTextColor: isOpen || isChildOpen ? JamiTheme.tintedBlue : JamiTheme.primaryForegroundColor height: JamiTheme.settingsMenuHeaderButtonHeight
buttonTextFont.weight: isOpen || isChildOpen ? Font.Medium : Font.Normal
buttonTextFont.pixelSize: JamiTheme.settingsDescriptionPixelSize
buttonTextColor: isChildSelected ? JamiTheme.tintedBlue : JamiTheme.primaryForegroundColor
buttonTextFont.weight: isChildSelected ? Font.Medium : Font.Normal
buttonTextEnableElide: true buttonTextEnableElide: true
normalColor: isOpen ? JamiTheme.smartListSelectedColor : "transparent" normalColor: isChildSelected ? JamiTheme.smartListSelectedColor : "transparent"
hoveredColor: JamiTheme.smartListHoveredColor hoveredColor: JamiTheme.smartListHoveredColor
imageColor: !isChildren ? JamiTheme.tintedBlue : null imageColor: JamiTheme.tintedBlue
source: modelData.icon
source: { onClicked: select(modelData.first)
if (!isChildren) Keys.onPressed: function (keyEvent) {
return base[modelData]["icon"]; if (keyEvent.key === Qt.Key_Enter || keyEvent.key === Qt.Key_Return) {
else clicked();
return ""; keyEvent.accepted = true;
}
} }
}
ListView {
id: childListView
width: parent.width
height: childrenRect.height
clip: true
visible: isChildSelected
model: modelData.children
delegate: ColumnLayout {
id: childCol
width: childListView.width
property bool isSelected: root.currentIndex == modelData.id
PushButton {
buttonText: modelData.title
circled: false
radius: 0
visible: modelData.visible ? modelData.visible : true
alignement: Text.AlignLeft
Layout.preferredWidth: parent.width - 28
Layout.leftMargin: 28
preferredLeftMargin: 47
imageContainerWidth: 0
height: JamiTheme.settingsMenuChildrenButtonHeight
buttonTextFont.pixelSize: JamiTheme.settingMenuPixelSize
buttonTextColor: isSelected ? JamiTheme.tintedBlue : JamiTheme.primaryForegroundColor
buttonTextFont.weight: isSelected ? Font.Medium : Font.Normal
buttonTextEnableElide: true
normalColor: "transparent"
hoveredColor: JamiTheme.smartListHoveredColor
onClicked: createChild() onClicked: open(modelData.id)
Keys.onPressed: function (keyEvent) { Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Enter || keyEvent.key === Qt.Key_Return) { if (keyEvent.key === Qt.Key_Enter || keyEvent.key === Qt.Key_Return) {
......
...@@ -31,6 +31,7 @@ import "../mainview/js/contactpickercreation.js" as ContactPickerCreation ...@@ -31,6 +31,7 @@ import "../mainview/js/contactpickercreation.js" as ContactPickerCreation
ListSelectionView { ListSelectionView {
id: viewNode id: viewNode
objectName: "SettingsView" objectName: "SettingsView"
selectionFallback: true
// A map of view names to file paths for QML files that define each view. // A map of view names to file paths for QML files that define each view.
property variant resources: { property variant resources: {
...@@ -57,6 +58,18 @@ ListSelectionView { ...@@ -57,6 +58,18 @@ ListSelectionView {
leftPaneItem: viewCoordinator.getView("SettingsSidePanel") leftPaneItem: viewCoordinator.getView("SettingsSidePanel")
Component.onCompleted: {
leftPaneItem.updateModel()
}
Connections {
target: viewNode
function onIsSinglePaneChanged() {
leftPaneItem.isSinglePane = viewNode.isSinglePane
}
}
onDismissed: { onDismissed: {
// Trigger an update to messages if needed. // Trigger an update to messages if needed.
// Currently needed when changing the show link preview setting. // Currently needed when changing the show link preview setting.
...@@ -68,10 +81,6 @@ ListSelectionView { ...@@ -68,10 +81,6 @@ ListSelectionView {
} }
} }
Component.onCompleted: {
leftPaneItem.createChild();
}
property int selectedMenu: index property int selectedMenu: index
rightPaneItem: StackView { rightPaneItem: StackView {
...@@ -83,8 +92,7 @@ ListSelectionView { ...@@ -83,8 +92,7 @@ ListSelectionView {
signal stopBooth signal stopBooth
initialItem: ManageAccountPage { initialItem: ManageAccountPage {}
}
onCurrentIndexChanged: { onCurrentIndexChanged: {
switch (currentIndex) { switch (currentIndex) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment