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