mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
SectionEditor: improved dimensions and moving across sections (for control center)
This commit is contained in:
@@ -247,8 +247,7 @@ Singleton {
|
||||
"id": "WiFi"
|
||||
}, {
|
||||
"id": "Bluetooth"
|
||||
},
|
||||
{
|
||||
}, {
|
||||
"id": "ScreenRecorder"
|
||||
}, {
|
||||
"id": "WallpaperSelector"
|
||||
|
||||
@@ -15,16 +15,16 @@ RowLayout {
|
||||
NBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.shortcutsHeight
|
||||
|
||||
|
||||
RowLayout {
|
||||
id: leftContent
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.shortcuts.left
|
||||
delegate: ControlCenterWidgetLoader {
|
||||
@@ -40,7 +40,7 @@ RowLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -50,16 +50,16 @@ RowLayout {
|
||||
NBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.shortcutsHeight
|
||||
|
||||
|
||||
RowLayout {
|
||||
id: rightContent
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.shortcuts.right
|
||||
delegate: ControlCenterWidgetLoader {
|
||||
@@ -75,10 +75,10 @@ RowLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ NBox {
|
||||
property string sectionId: ""
|
||||
property var widgetModel: []
|
||||
property var availableWidgets: []
|
||||
property bool enableMoveBetweenSections: true
|
||||
property int maxWidgets: -1 // -1 means unlimited
|
||||
property var availableSections: ["left", "center", "right"]
|
||||
property int maxWidgets: -1 // -1 means unlimited
|
||||
|
||||
property var widgetRegistry: null
|
||||
property string settingsDialogComponent: "BarWidgetSettingsDialog.qml"
|
||||
@@ -33,16 +33,26 @@ NBox {
|
||||
color: Color.mSurface
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: {
|
||||
var widgetCount = widgetModel.length
|
||||
if (widgetCount === 0)
|
||||
return 140 * Style.uiScaleRatio
|
||||
// header + minimal content area
|
||||
var absoluteMin = (Style.marginL * 2) + (Style.fontSizeL * 2) + Style.marginM + (65 * Style.uiScaleRatio)
|
||||
|
||||
var availableWidth = parent.width
|
||||
var avgWidgetWidth = 150 * Style.uiScaleRatio
|
||||
var widgetCount = widgetModel.length
|
||||
if (widgetCount === 0) {
|
||||
return absoluteMin
|
||||
}
|
||||
|
||||
// Calculate rows based on estimated widget layout
|
||||
var availableWidth = parent.width - (Style.marginL * 2)
|
||||
var avgWidgetWidth = 120 * Style.uiScaleRatio // More accurate estimate
|
||||
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
|
||||
var rows = Math.ceil(widgetCount / widgetsPerRow)
|
||||
|
||||
return ((50 + 20 + (rows * 48)) * Style.uiScaleRatio + ((rows - 1) * Style.marginS) + 20 * Style.uiScaleRatio)
|
||||
// Header height + spacing + (rows * widget height) + (spacing between rows) + margins
|
||||
var headerHeight = Style.fontSizeL * 2
|
||||
var widgetHeight = Style.baseWidgetSize * 1.15 * Style.uiScaleRatio
|
||||
var widgetAreaHeight = ((rows + 1) * widgetHeight) + ((rows - 1) * Style.marginS)
|
||||
|
||||
return Math.max(absoluteMin, (Style.marginL * 2) + headerHeight + Style.marginM + widgetAreaHeight)
|
||||
}
|
||||
|
||||
// Generate widget color from name checksum
|
||||
@@ -95,6 +105,7 @@ NBox {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NSearchableComboBox {
|
||||
id: comboBox
|
||||
model: availableWidgets
|
||||
@@ -103,8 +114,8 @@ NBox {
|
||||
placeholder: I18n.tr("bar.widget-settings.section-editor.placeholder")
|
||||
searchPlaceholder: I18n.tr("bar.widget-settings.section-editor.search-placeholder")
|
||||
onSelected: key => comboBox.currentKey = key
|
||||
popupHeight: 340
|
||||
minimumWidth: 200
|
||||
popupHeight: 300 * Style.uiScaleRatio
|
||||
minimumWidth: 200 * Style.uiScaleRatio
|
||||
enabled: !root.isAtMaxCapacity
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -128,9 +139,7 @@ NBox {
|
||||
colorBgHover: Color.mSecondary
|
||||
colorFgHover: Color.mOnSecondary
|
||||
enabled: comboBox.currentKey !== "" && !root.isAtMaxCapacity
|
||||
tooltipText: root.isAtMaxCapacity
|
||||
? I18n.tr("tooltips.max-widgets-reached")
|
||||
: I18n.tr("tooltips.add-widget")
|
||||
tooltipText: root.isAtMaxCapacity ? I18n.tr("tooltips.max-widgets-reached") : I18n.tr("tooltips.add-widget")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Style.marginS
|
||||
onClicked: {
|
||||
@@ -164,7 +173,7 @@ NBox {
|
||||
required property var modelData
|
||||
|
||||
width: widgetContent.implicitWidth + Style.marginL
|
||||
height: Style.baseWidgetSize * 1.15
|
||||
height: Style.baseWidgetSize * 1.15 * Style.uiScaleRatio
|
||||
radius: Style.radiusL
|
||||
color: root.getWidgetColor(modelData)[0]
|
||||
border.color: Color.mOutline
|
||||
@@ -200,17 +209,17 @@ NBox {
|
||||
"label": I18n.tr("tooltips.move-to-left-section"),
|
||||
"action": "left",
|
||||
"icon": "arrow-bar-to-left",
|
||||
"visible": root.sectionId !== "left"
|
||||
"visible": root.availableSections.includes("left") && root.sectionId !== "left"
|
||||
}, {
|
||||
"label": I18n.tr("tooltips.move-to-center-section"),
|
||||
"action": "center",
|
||||
"icon": "layout-columns",
|
||||
"visible": root.sectionId !== "center"
|
||||
"visible": root.availableSections.includes("center") && root.sectionId !== "center"
|
||||
}, {
|
||||
"label": I18n.tr("tooltips.move-to-right-section"),
|
||||
"action": "right",
|
||||
"icon": "arrow-bar-to-right",
|
||||
"visible": root.sectionId !== "right"
|
||||
"visible": root.availableSections.includes("right") && root.sectionId !== "right"
|
||||
}]
|
||||
|
||||
onTriggered: action => root.moveWidget(root.sectionId, index, action)
|
||||
@@ -219,7 +228,7 @@ NBox {
|
||||
// MouseArea for the context menu
|
||||
MouseArea {
|
||||
id: contextMouseArea
|
||||
enabled: enableMoveBetweenSections
|
||||
enabled: root.availableSections.length > 1 // Enable if there are other sections to move to
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.RightButton
|
||||
z: -1 // Below the buttons but above background
|
||||
@@ -603,4 +612,4 @@ NBox {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,11 +229,12 @@ ColumnLayout {
|
||||
widgetRegistry: ControlCenterWidgetRegistry
|
||||
widgetModel: Settings.data.controlCenter.shortcuts["left"]
|
||||
availableWidgets: availableWidgets
|
||||
enableMoveBetweenSections: false
|
||||
availableSections: ["left", "right"]
|
||||
onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
|
||||
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
|
||||
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
|
||||
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
|
||||
onMoveWidget: (fromSection, index, toSection) => _moveWidgetBetweenSections(fromSection, index, toSection)
|
||||
onDragPotentialStarted: root.handleDragStart()
|
||||
onDragPotentialEnded: root.handleDragEnd()
|
||||
}
|
||||
@@ -247,11 +248,12 @@ ColumnLayout {
|
||||
widgetRegistry: ControlCenterWidgetRegistry
|
||||
widgetModel: Settings.data.controlCenter.shortcuts["right"]
|
||||
availableWidgets: availableWidgets
|
||||
enableMoveBetweenSections: false
|
||||
availableSections: ["left", "right"]
|
||||
onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
|
||||
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
|
||||
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
|
||||
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
|
||||
onMoveWidget: (fromSection, index, toSection) => _moveWidgetBetweenSections(fromSection, index, toSection)
|
||||
onDragPotentialStarted: root.handleDragStart()
|
||||
onDragPotentialEnded: root.handleDragEnd()
|
||||
}
|
||||
@@ -305,6 +307,25 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
function _moveWidgetBetweenSections(fromSection, index, toSection) {
|
||||
// Get the widget from the source section
|
||||
if (index >= 0 && index < Settings.data.controlCenter.shortcuts[fromSection].length) {
|
||||
var widget = Settings.data.controlCenter.shortcuts[fromSection][index]
|
||||
|
||||
// Remove from source section
|
||||
var sourceArray = Settings.data.controlCenter.shortcuts[fromSection].slice()
|
||||
sourceArray.splice(index, 1)
|
||||
Settings.data.controlCenter.shortcuts[fromSection] = sourceArray
|
||||
|
||||
// Add to target section
|
||||
var targetArray = Settings.data.controlCenter.shortcuts[toSection].slice()
|
||||
targetArray.push(widget)
|
||||
Settings.data.controlCenter.shortcuts[toSection] = targetArray
|
||||
|
||||
//Logger.log("BarTab", `Moved widget ${widget.id} from ${fromSection} to ${toSection}`)
|
||||
}
|
||||
}
|
||||
|
||||
function _updateWidgetSettingsInSection(section, index, settings) {
|
||||
// Update the widget settings in the Settings data
|
||||
Settings.data.controlCenter.shortcuts[section][index] = settings
|
||||
|
||||
@@ -8,26 +8,22 @@ import qs.Services
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
// Size properties (matching NIconButton)
|
||||
// Public properties
|
||||
property real baseSize: Style.baseWidgetSize
|
||||
property bool applyUiScale: true
|
||||
|
||||
// Public properties
|
||||
property string icon: ""
|
||||
property string tooltipText: ""
|
||||
property string tooltipDirection: "auto"
|
||||
property bool enabled: true
|
||||
property bool allowClickWhenDisabled: false
|
||||
property bool compact: false
|
||||
|
||||
// Hot state (unique to NIconButtonHot)
|
||||
property bool hot: false
|
||||
|
||||
// Internal properties
|
||||
property bool hovering: false
|
||||
property bool pressed: false
|
||||
|
||||
// Color properties (matching NIconButton structure)
|
||||
// Color properties
|
||||
property color colorBg: Color.mSurfaceVariant
|
||||
property color colorFg: Color.mPrimary
|
||||
property color colorBgHover: Color.mTertiary
|
||||
@@ -46,11 +42,11 @@ Rectangle {
|
||||
signal rightClicked
|
||||
signal middleClicked
|
||||
|
||||
// Dimensions (matching NIconButton)
|
||||
// Dimensions
|
||||
implicitWidth: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
|
||||
implicitHeight: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
|
||||
|
||||
// Appearance (matching NIconButton)
|
||||
// Appearance
|
||||
opacity: root.enabled ? Style.opacityFull : Style.opacityMedium
|
||||
color: {
|
||||
if (pressed) {
|
||||
@@ -64,7 +60,7 @@ Rectangle {
|
||||
}
|
||||
return colorBg
|
||||
}
|
||||
radius: width * 0.5 // Circular like NIconButton
|
||||
radius: width * 0.5
|
||||
border.color: root.enabled && root.hovering ? colorBorderHover : colorBorder
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
|
||||
@@ -82,7 +78,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
// Icon (matching NIconButton positioning and sizing)
|
||||
// Icon
|
||||
NIcon {
|
||||
icon: root.icon
|
||||
pointSize: Math.max(1, root.compact ? root.width * 0.65 : root.width * 0.48)
|
||||
@@ -175,4 +171,4 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user