Files

193 lines
7.2 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import qs.Common
import qs.Services
import qs.DCommon.Widgets
import qs.Widgets
import qs.Modals.DLauncherV2.Components
Item {
id: root
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
property var section: null
property var controller: null
property string viewMode: "list"
property bool canChangeViewMode: true
property bool canCollapse: true
property bool popupAbove: false
property Item popupAboveItem: null
property Item focusReturnTarget: null
property var transientSurfaceTracker: null
readonly property bool hasAppCategories: section?.id === "apps" && (controller?.appCategories?.length ?? 0) > 0
readonly property var viewModes: [
{
mode: "list",
icon: "view_list",
label: I18n.tr("List", "noun, list view mode option")
},
{
mode: "grid",
icon: "grid_view",
label: I18n.tr("Grid", "noun, grid view mode and layout option")
},
{
mode: "tile",
icon: "view_module",
label: I18n.tr("Tile")
}
]
signal viewModeToggled
width: parent?.width ?? Theme.fieldDefaultWidth
height: LauncherMetrics.sectionHeight
clip: true
readonly property string categoryLabel: controller?.appCategory || (controller?.appCategories?.[0] ?? "")
Item {
id: labelArea
anchors.left: parent.left
anchors.right: controls.left
anchors.leftMargin: LauncherMetrics.headerInset
anchors.rightMargin: Theme.spacingS
height: parent.height
Row {
id: labelContent
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
readonly property bool _iconVisible: root.section?.iconVisible ?? true
readonly property string _iconType: root.section?.iconType ?? "material"
readonly property bool _iconSpaceReserved: root.hasAppCategories || _iconVisible
DIcon {
anchors.verticalCenter: parent.verticalCenter
visible: root.hasAppCategories || (labelContent._iconVisible && labelContent._iconType !== "image")
name: root.hasAppCategories ? AppSearchService.getCategoryIcon(root.categoryLabel) : (root.section?.icon ?? "folder")
size: Theme.iconSizeSmall
color: Theme.primary
}
Loader {
id: imageIconLoader
anchors.verticalCenter: parent.verticalCenter
active: !root.hasAppCategories && labelContent._iconVisible && labelContent._iconType === "image"
visible: active
width: active ? Theme.iconSizeSmall : 0
height: Theme.iconSizeSmall
sourceComponent: AppIconRenderer {
width: Theme.iconSizeSmall
height: Theme.iconSizeSmall
iconValue: root.section?.icon ?? ""
iconSize: Theme.iconSizeSmall
iconColor: Theme.primary
fallbackRadius: Theme.fullRadius(Theme.iconSizeSmall, Theme.iconSizeSmall)
fallbackBackgroundColor: Theme.primaryContainer
fallbackTextColor: Theme.onPrimaryContainer
fallbackText: (root.section?.title ?? "").charAt(0).toUpperCase() || "?"
}
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
width: Math.min(implicitWidth, labelArea.width - (labelContent._iconSpaceReserved ? Theme.iconSizeSmall + Theme.spacingS : 0) - (chevron.visible ? chevron.width + Theme.spacingS : 0))
text: root.hasAppCategories ? root.categoryLabel : (root.section?.title ?? "")
font.pixelSize: Theme.fontSizeSmall
font.weight: Theme.fontWeightMedium
color: Theme.primary
elide: Text.ElideRight
}
DIcon {
id: chevron
visible: root.hasAppCategories
anchors.verticalCenter: parent.verticalCenter
name: "arrow_drop_down"
size: Theme.iconSizeSmall
color: Theme.primary
}
}
MouseArea {
anchors.fill: labelContent
enabled: root.hasAppCategories
cursorShape: Qt.PointingHandCursor
onClicked: categoryDropdown.item?.openDropdownMenu()
}
Loader {
id: categoryDropdown
active: root.hasAppCategories
sourceComponent: DDropdown {
showTrigger: false
focusPolicy: Qt.NoFocus
popupWidth: Math.min(Theme.fieldDefaultWidth, root.width)
compactMode: true
options: root.controller?.appCategories ?? []
optionIcons: options.map(category => AppSearchService.getCategoryIcon(category))
currentValue: root.categoryLabel
openUpwards: root.popupAbove
popupAnchorItem: root.popupAbove ? root.popupAboveItem : labelContent
focusReturnTarget: root.focusReturnTarget
transientSurfaceTracker: root.transientSurfaceTracker
maxPopupHeight: LauncherMetrics.maxVisibleRows * Theme.menuItemHeight
onValueChanged: value => root.controller?.setAppCategory(value)
}
}
}
Row {
id: controls
anchors.right: parent.right
anchors.rightMargin: 0
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.groupedListGap
DActionButton {
readonly property var current: root.viewModes.find(entry => entry.mode === root.viewMode) ?? root.viewModes[0]
focusPolicy: Qt.NoFocus
visible: root.canChangeViewMode && !root.section?.collapsed
iconName: current.icon
tooltipText: current.label
iconSize: Theme.iconSizeSmall
onClicked: {
if (!root.controller || !root.section)
return;
const index = root.viewModes.indexOf(current);
root.controller.setSectionViewMode(root.section.id, root.viewModes[(index + 1) % root.viewModes.length].mode);
}
}
DActionButton {
focusPolicy: Qt.NoFocus
visible: root.canCollapse
iconName: root.section?.collapsed ? "expand_more" : "expand_less"
Accessible.name: root.section?.collapsed ? I18n.tr("Expand") : I18n.tr("Collapse")
iconSize: Theme.iconSizeSmall
onClicked: {
if (!root.controller || !root.section)
return;
root.controller.toggleSection(root.section.id);
}
}
}
MouseArea {
anchors.fill: parent
anchors.rightMargin: controls.width + Theme.spacingS
enabled: root.canCollapse && !root.hasAppCategories
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!root.controller || !root.section)
return;
root.controller.toggleSection(root.section.id);
}
}
}