Make sidebar collapsible
This commit is contained in:
@@ -18,6 +18,24 @@ Kirigami.ScrollablePage {
|
|||||||
id: page
|
id: page
|
||||||
|
|
||||||
property var enteredRoom
|
property var enteredRoom
|
||||||
|
property bool collapsedMode: Config.roomListPageWidth === applicationWindow().collapsedPageWidth && applicationWindow().shouldUseSidebars
|
||||||
|
|
||||||
|
onCollapsedModeChanged: if (collapsedMode) {
|
||||||
|
sortFilterRoomListModel.filterText = "";
|
||||||
|
if (page.contentItem && page.contentItem.flickableItem && page.contentItem.flickableItem.QQC2.ScrollBar.vertical) {
|
||||||
|
page.contentItem.flickableItem.QQC2.ScrollBar.vertical.visible = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
page.contentItem.flickableItem.QQC2.ScrollBar.vertical.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: the scrollbar is created with a 0 timer, so we need to set the visible flag
|
||||||
|
// after it has been created
|
||||||
|
Timer {
|
||||||
|
running: true
|
||||||
|
interval: 200
|
||||||
|
onTriggered: page.contentItem.flickableItem.QQC2.ScrollBar.vertical.visible = !collapsedMode;
|
||||||
|
}
|
||||||
|
|
||||||
function goToNextRoom() {
|
function goToNextRoom() {
|
||||||
do {
|
do {
|
||||||
@@ -33,9 +51,16 @@ Kirigami.ScrollablePage {
|
|||||||
listView.currentItem.action.trigger();
|
listView.currentItem.action.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
title: i18n("Rooms")
|
titleDelegate: collapsedMode ? empty : searchField
|
||||||
|
|
||||||
titleDelegate: Kirigami.SearchField {
|
Component {
|
||||||
|
id: empty
|
||||||
|
Item {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: searchField
|
||||||
|
Kirigami.SearchField {
|
||||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
@@ -43,6 +68,33 @@ Kirigami.ScrollablePage {
|
|||||||
onTextChanged: sortFilterRoomListModel.filterText = text
|
onTextChanged: sortFilterRoomListModel.filterText = text
|
||||||
KeyNavigation.tab: listView
|
KeyNavigation.tab: listView
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header: QQC2.ItemDelegate {
|
||||||
|
visible: page.collapsedMode
|
||||||
|
action: Kirigami.Action {
|
||||||
|
id: enterRoomAction
|
||||||
|
onTriggered: quickView.item.open();
|
||||||
|
}
|
||||||
|
topPadding: Kirigami.Units.largeSpacing
|
||||||
|
leftPadding: Kirigami.Units.largeSpacing
|
||||||
|
rightPadding: Kirigami.Units.largeSpacing
|
||||||
|
bottomPadding: Kirigami.Units.largeSpacing
|
||||||
|
width: visible ? page.width : 0
|
||||||
|
height: visible ? Kirigami.Units.gridUnit * 2 : 0
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: 22 * Kirigami.Units.devicePixelRatio
|
||||||
|
height: 22 * Kirigami.Units.devicePixelRatio
|
||||||
|
source: "search"
|
||||||
|
}
|
||||||
|
Kirigami.Separator {
|
||||||
|
width: parent.width
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listView
|
id: listView
|
||||||
@@ -64,6 +116,7 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ItemSelectionModel {
|
ItemSelectionModel {
|
||||||
id: itemSelection
|
id: itemSelection
|
||||||
model: roomListModel
|
model: roomListModel
|
||||||
@@ -97,11 +150,14 @@ Kirigami.ScrollablePage {
|
|||||||
level: 3
|
level: 3
|
||||||
text: roomListModel.categoryName(section)
|
text: roomListModel.categoryName(section)
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
visible: !page.collapsedMode
|
||||||
}
|
}
|
||||||
Kirigami.Icon {
|
Kirigami.Icon {
|
||||||
source: roomListModel.categoryVisible(section) ? "go-up" : "go-down"
|
source: page.collapsedMode ? roomListModel.categoryIconName(section) : (roomListModel.categoryVisible(section) ? "go-up" : "go-down")
|
||||||
implicitHeight: Kirigami.Units.iconSizes.small
|
implicitHeight: Kirigami.Units.iconSizes.small
|
||||||
implicitWidth: Kirigami.Units.iconSizes.small
|
implicitWidth: Kirigami.Units.iconSizes.small
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +165,51 @@ Kirigami.ScrollablePage {
|
|||||||
reuseItems: true
|
reuseItems: true
|
||||||
currentIndex: -1 // we don't want any room highlighted by default
|
currentIndex: -1 // we don't want any room highlighted by default
|
||||||
|
|
||||||
delegate: Kirigami.BasicListItem {
|
delegate: page.collapsedMode ? collapsedModeListComponent : normalModeListComponent
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: collapsedModeListComponent
|
||||||
|
|
||||||
|
QQC2.ItemDelegate {
|
||||||
|
action: Kirigami.Action {
|
||||||
|
id: enterRoomAction
|
||||||
|
onTriggered: {
|
||||||
|
RoomManager.enterRoom(currentRoom);
|
||||||
|
itemSelection.setCurrentIndex(sortFilterRoomListModel.mapToSource(
|
||||||
|
sortFilterRoomListModel.index(index, 0)), ItemSelectionModel.SelectCurrent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEnterPressed: enterRoomAction.trigger()
|
||||||
|
Keys.onReturnPressed: enterRoomAction.trigger()
|
||||||
|
topPadding: Kirigami.Units.largeSpacing
|
||||||
|
leftPadding: Kirigami.Units.largeSpacing
|
||||||
|
rightPadding: Kirigami.Units.largeSpacing
|
||||||
|
bottomPadding: Kirigami.Units.largeSpacing
|
||||||
|
width: ListView.view.width
|
||||||
|
height: ListView.view.width
|
||||||
|
|
||||||
|
contentItem: Kirigami.Avatar {
|
||||||
|
source: avatar ? "image://mxc/" + avatar : ""
|
||||||
|
name: model.name || i18n("No Name")
|
||||||
|
sourceSize.width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||||
|
sourceSize.height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.ToolTip {
|
||||||
|
enabled: text.length !== 0
|
||||||
|
text: name ?? ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: roomListContextMenu
|
||||||
|
RoomListContextMenu {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: normalModeListComponent
|
||||||
|
Kirigami.BasicListItem {
|
||||||
id: roomListItem
|
id: roomListItem
|
||||||
visible: model.categoryVisible || sortFilterRoomListModel.filterText.length > 0 || Config.mergeRoomList
|
visible: model.categoryVisible || sortFilterRoomListModel.filterText.length > 0 || Config.mergeRoomList
|
||||||
topPadding: Kirigami.Units.largeSpacing
|
topPadding: Kirigami.Units.largeSpacing
|
||||||
@@ -182,14 +282,11 @@ Kirigami.ScrollablePage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
|
||||||
id: roomListContextMenu
|
|
||||||
RoomListContextMenu {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
footer: QQC2.ToolBar {
|
footer: QQC2.ToolBar {
|
||||||
visible: accountList.count > 1
|
visible: accountList.count > 1 && !collapsedMode
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
rightPadding: 0
|
rightPadding: 0
|
||||||
|
|||||||
65
qml/main.qml
65
qml/main.qml
@@ -166,7 +166,70 @@ Kirigami.ApplicationWindow {
|
|||||||
handleVisible: enabled && pageStack.layers.depth < 2 && pageStack.depth < 3
|
handleVisible: enabled && pageStack.layers.depth < 2 && pageStack.depth < 3
|
||||||
}
|
}
|
||||||
|
|
||||||
pageStack.columnView.columnWidth: Kirigami.Units.gridUnit * 17
|
readonly property int defaultPageWidth: Kirigami.Units.gridUnit * 17
|
||||||
|
readonly property int minPageWidth: Kirigami.Units.gridUnit * 10
|
||||||
|
readonly property int collapsedPageWidth: Kirigami.Units.gridUnit * 3 - Kirigami.Units.smallSpacing * 3
|
||||||
|
readonly property bool shouldUseSidebars: (Config.roomListPageWidth > minPageWidth ? root.width >= Kirigami.Units.gridUnit * 35 : root.width > Kirigami.Units.gridUnit * 27) && roomListLoaded
|
||||||
|
readonly property int pageWidth: {
|
||||||
|
if (Config.roomListPageWidth === -1) {
|
||||||
|
return defaultPageWidth;
|
||||||
|
} else if (Config.roomListPageWidth < minPageWidth) {
|
||||||
|
return collapsedPageWidth;
|
||||||
|
} else {
|
||||||
|
return Config.roomListPageWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageStack.defaultColumnWidth: pageWidth
|
||||||
|
pageStack.columnView.columnResizeMode: shouldUseSidebars ? Kirigami.ColumnView.FixedColumns : Kirigami.ColumnView.SingleColumn
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
visible: root.pageStack.wideMode
|
||||||
|
z: 500
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
x: root.pageStack.defaultColumnWidth - (width / 2)
|
||||||
|
width: Kirigami.Units.devicePixelRatio * 2
|
||||||
|
|
||||||
|
property int _lastX: -1
|
||||||
|
enabled: !Kirigami.Settings.isMobile
|
||||||
|
|
||||||
|
cursorShape: !Kirigami.Settings.isMobile ? Qt.SplitHCursor : undefined
|
||||||
|
|
||||||
|
onPressed: _lastX = mouseX
|
||||||
|
onReleased: Config.save();
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
if (_lastX == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse.x > _lastX) {
|
||||||
|
// we moved to the right
|
||||||
|
if (Config.roomListPageWidth === root.collapsedPageWidth && root.pageWidth + (mouse.x - _lastX) >= root.minPageWidth) {
|
||||||
|
// Here we get back directly to a more wide mode.
|
||||||
|
Config.roomListPageWidth = root.minPageWidth;
|
||||||
|
if (root.width < Kirigami.Units.gridUnit * 35) {
|
||||||
|
root.width = Kirigami.Units.gridUnit * 35;
|
||||||
|
}
|
||||||
|
} else if (Config.roomListPageWidth !== root.collapsedPageWidth) {
|
||||||
|
// Increase page width
|
||||||
|
Config.roomListPageWidth = Math.min(root.defaultPageWidth, root.pageWidth + (mouse.x - _lastX));
|
||||||
|
}
|
||||||
|
} else if (mouse.x < _lastX) {
|
||||||
|
const tmpWidth = root.pageWidth - (_lastX - mouse.x);
|
||||||
|
|
||||||
|
if (tmpWidth < root.minPageWidth) {
|
||||||
|
Config.roomListPageWidth = root.collapsedPageWidth;
|
||||||
|
} else {
|
||||||
|
Config.roomListPageWidth = tmpWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
globalDrawer: Kirigami.GlobalDrawer {
|
globalDrawer: Kirigami.GlobalDrawer {
|
||||||
property bool hasLayer
|
property bool hasLayer
|
||||||
|
|||||||
@@ -41,6 +41,9 @@
|
|||||||
<label>"Show your messages on the right</label>
|
<label>"Show your messages on the right</label>
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="RoomListPageWidth" type="int">
|
||||||
|
<default>-1</default>
|
||||||
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
<group name="Timeline">
|
<group name="Timeline">
|
||||||
<entry name="ShowAvatarInTimeline" type="bool">
|
<entry name="ShowAvatarInTimeline" type="bool">
|
||||||
|
|||||||
@@ -432,6 +432,24 @@ QString RoomListModel::categoryName(int section)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString RoomListModel::categoryIconName(int section)
|
||||||
|
{
|
||||||
|
switch (section) {
|
||||||
|
case 1:
|
||||||
|
return QStringLiteral("user-invisible");
|
||||||
|
case 2:
|
||||||
|
return QStringLiteral("favorite");
|
||||||
|
case 3:
|
||||||
|
return QStringLiteral("dialog-messages");
|
||||||
|
case 4:
|
||||||
|
return QStringLiteral("group");
|
||||||
|
case 5:
|
||||||
|
return QStringLiteral("object-order-lower");
|
||||||
|
default:
|
||||||
|
return QStringLiteral("tools-report-bug");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RoomListModel::setCategoryVisible(int category, bool visible)
|
void RoomListModel::setCategoryVisible(int category, bool visible)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
Q_INVOKABLE [[nodiscard]] static QString categoryName(int section);
|
Q_INVOKABLE [[nodiscard]] static QString categoryName(int section);
|
||||||
|
Q_INVOKABLE [[nodiscard]] static QString categoryIconName(int section);
|
||||||
Q_INVOKABLE void setCategoryVisible(int category, bool visible);
|
Q_INVOKABLE void setCategoryVisible(int category, bool visible);
|
||||||
Q_INVOKABLE [[nodiscard]] bool categoryVisible(int category) const;
|
Q_INVOKABLE [[nodiscard]] bool categoryVisible(int category) const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user