mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(ui): using panel opacity on all nboxes (unless marked as opaque) + launcher adjustments for a nice transluent look
This commit is contained in:
@@ -88,11 +88,20 @@ SmartPanel {
|
||||
}
|
||||
|
||||
// Preview Panel (external) - uses provider's preview component
|
||||
NDropShadow {
|
||||
source: previewBox
|
||||
anchors.fill: previewBox
|
||||
autoPaddingEnabled: true
|
||||
visible: previewBox.visible
|
||||
z: previewBox.z - 1
|
||||
}
|
||||
|
||||
NBox {
|
||||
id: previewBox
|
||||
visible: root.previewActive
|
||||
width: root.previewPanelWidth
|
||||
height: Math.round(400 * Style.uiScaleRatio)
|
||||
forceOpaque: true // no blur for now
|
||||
x: root.panelAnchorRight ? -(root.previewPanelWidth + Style.marginM) : ui.width + Style.marginM
|
||||
y: {
|
||||
var view = launcherCore.resultsView;
|
||||
@@ -150,20 +159,15 @@ SmartPanel {
|
||||
}
|
||||
|
||||
// Core launcher (state, providers, UI)
|
||||
NBox {
|
||||
LauncherCore {
|
||||
id: launcherCore
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL
|
||||
|
||||
LauncherCore {
|
||||
id: launcherCore
|
||||
anchors.fill: parent
|
||||
screen: root.screen
|
||||
isOpen: root.isPanelOpen
|
||||
onRequestClose: root.close()
|
||||
// Defer so the signal emission completes before SmartPanel
|
||||
// sets isPanelOpen=false and the contentLoader destroys us.
|
||||
onRequestCloseImmediately: Qt.callLater(root.closeImmediately)
|
||||
}
|
||||
screen: root.screen
|
||||
isOpen: root.isPanelOpen
|
||||
onRequestClose: root.close()
|
||||
// Defer so the signal emission completes before SmartPanel
|
||||
// sets isPanelOpen=false and the contentLoader destroys us.
|
||||
onRequestCloseImmediately: Qt.callLater(root.closeImmediately)
|
||||
}
|
||||
|
||||
// Update preview when selection changes
|
||||
|
||||
@@ -159,6 +159,12 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
onSearchTextChanged: {
|
||||
if (isOpen) {
|
||||
updateResults();
|
||||
}
|
||||
}
|
||||
|
||||
function onOpened() {
|
||||
ignoreMouseHover = true;
|
||||
globalMouseInitialized = false;
|
||||
@@ -188,11 +194,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
onSearchTextChanged: {
|
||||
if (isOpen)
|
||||
updateResults();
|
||||
}
|
||||
|
||||
function close() {
|
||||
requestClose();
|
||||
}
|
||||
@@ -783,7 +784,7 @@ Rectangle {
|
||||
horizontalPolicy: ScrollBar.AlwaysOff
|
||||
verticalPolicy: ScrollBar.AlwaysOff
|
||||
reserveScrollbarSpace: false
|
||||
gradientColor: Color.mSurfaceVariant
|
||||
gradientColor: Settings.data.ui.panelBackgroundOpacity < 1 ? "transparent" : Color.mSurfaceVariant
|
||||
wheelScrollMultiplier: 4.0
|
||||
|
||||
width: parent.width
|
||||
@@ -806,6 +807,12 @@ Rectangle {
|
||||
|
||||
property bool isSelected: (!root.ignoreMouseHover && mouseArea.containsMouse) || (index === root.selectedIndex)
|
||||
|
||||
width: resultsList.availableWidth
|
||||
implicitHeight: root.entryHeight
|
||||
clip: true
|
||||
color: entry.isSelected ? Color.mHover : Color.mSurface
|
||||
forceOpaque: entry.isSelected
|
||||
|
||||
// Prepare item when it becomes visible (e.g., decode images)
|
||||
Component.onCompleted: {
|
||||
var provider = modelData.provider;
|
||||
@@ -814,11 +821,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
width: resultsList.availableWidth
|
||||
implicitHeight: root.entryHeight
|
||||
clip: true
|
||||
color: entry.isSelected ? Color.mHover : Color.mSurface
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
@@ -1086,6 +1088,7 @@ Rectangle {
|
||||
NBox {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
forceOpaque: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
@@ -1131,7 +1134,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// // --------------------------
|
||||
// GRID VIEW
|
||||
Component {
|
||||
id: gridViewComponent
|
||||
@@ -1141,7 +1144,7 @@ Rectangle {
|
||||
horizontalPolicy: ScrollBar.AlwaysOff
|
||||
verticalPolicy: ScrollBar.AlwaysOff
|
||||
reserveScrollbarSpace: false
|
||||
gradientColor: Color.mSurfaceVariant
|
||||
gradientColor: Settings.data.ui.panelBackgroundOpacity < 1 ? "transparent" : Color.mSurfaceVariant
|
||||
wheelScrollMultiplier: 4.0
|
||||
trackedSelectionIndex: root.selectedIndex
|
||||
|
||||
@@ -1211,6 +1214,7 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginXXS
|
||||
color: gridEntryContainer.isSelected ? Color.mHover : Color.mSurface
|
||||
forceOpaque: gridEntryContainer.isSelected
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
|
||||
@@ -57,8 +57,8 @@ Variants {
|
||||
}
|
||||
|
||||
Region {
|
||||
x: Math.round(previewBox.visible ? launcherPanel.x + previewBox.x : 0)
|
||||
y: Math.round(previewBox.visible ? launcherPanel.y + previewBox.y : 0)
|
||||
x: Math.round(previewBox.visible ? previewBox.x : 0)
|
||||
y: Math.round(previewBox.visible ? previewBox.y : 0)
|
||||
width: Math.round(previewBox.visible ? previewBox.width : 0)
|
||||
height: Math.round(previewBox.visible ? previewBox.height : 0)
|
||||
radius: Style.radiusL
|
||||
@@ -337,83 +337,88 @@ Variants {
|
||||
Component.onCompleted: PanelService.overlayLauncherCore = launcherCore
|
||||
Component.onDestruction: PanelService.overlayLauncherCore = null
|
||||
}
|
||||
}
|
||||
|
||||
// Preview Panel - clipboard preview positioned outside panel bounds
|
||||
NDropShadow {
|
||||
source: previewBox
|
||||
anchors.fill: previewBox
|
||||
autoPaddingEnabled: true
|
||||
visible: previewBox.visible
|
||||
// Preview Panel - positioned as sibling of launcherPanel to avoid shadow bleed
|
||||
NDropShadow {
|
||||
source: previewBox
|
||||
anchors.fill: previewBox
|
||||
autoPaddingEnabled: true
|
||||
visible: previewBox.visible
|
||||
z: previewBox.z - 1
|
||||
}
|
||||
|
||||
NBox {
|
||||
id: previewBox
|
||||
visible: launcherWindow.previewActive
|
||||
width: launcherWindow.previewPanelWidth
|
||||
height: Math.round(400 * Style.uiScaleRatio)
|
||||
forceOpaque: true
|
||||
x: {
|
||||
if (panelPosition.endsWith("_right"))
|
||||
return launcherPanel.x - launcherWindow.previewPanelWidth - Style.marginM;
|
||||
return launcherPanel.x + launcherPanel.width + Style.marginM;
|
||||
}
|
||||
y: {
|
||||
var view = launcherCore.resultsView;
|
||||
if (!view)
|
||||
return launcherPanel.y + Style.marginL;
|
||||
var row = launcherCore.isGridView ? Math.floor(launcherCore.selectedIndex / launcherCore.gridColumns) : launcherCore.selectedIndex;
|
||||
var gridCellSize = Math.floor((launcherWindow.listPanelWidth - (2 * Style.marginXS) - ((launcherCore.targetGridColumns - 1) * Style.marginS)) / launcherCore.targetGridColumns);
|
||||
var itemHeight = launcherCore.isGridView ? (gridCellSize + Style.marginXXS) : (launcherCore.entryHeight + (view.spacing || 0));
|
||||
var yPos = row * itemHeight - (view.contentY || 0);
|
||||
var mapped = view.mapToItem(launcherWindow.contentItem, 0, yPos);
|
||||
return Math.max(launcherPanel.y + Style.marginL, Math.min(mapped.y, launcherPanel.y + launcherPanel.height - previewBox.height - Style.marginL));
|
||||
}
|
||||
|
||||
NBox {
|
||||
id: previewBox
|
||||
visible: launcherWindow.previewActive
|
||||
width: launcherWindow.previewPanelWidth
|
||||
height: Math.round(400 * Style.uiScaleRatio)
|
||||
x: panelPosition.endsWith("_right") ? -(launcherWindow.previewPanelWidth + Style.marginM) : launcherPanel.width + Style.marginM
|
||||
y: {
|
||||
var view = launcherCore.resultsView;
|
||||
if (!view)
|
||||
return Style.marginL;
|
||||
var row = launcherCore.isGridView ? Math.floor(launcherCore.selectedIndex / launcherCore.gridColumns) : launcherCore.selectedIndex;
|
||||
var gridCellSize = Math.floor((launcherWindow.listPanelWidth - (2 * Style.marginXS) - ((launcherCore.targetGridColumns - 1) * Style.marginS)) / launcherCore.targetGridColumns);
|
||||
var itemHeight = launcherCore.isGridView ? (gridCellSize + Style.marginXXS) : (launcherCore.entryHeight + (view.spacing || 0));
|
||||
var yPos = row * itemHeight - (view.contentY || 0);
|
||||
var mapped = view.mapToItem(launcherPanel, 0, yPos);
|
||||
return Math.max(Style.marginL, Math.min(mapped.y, launcherPanel.height - previewBox.height - Style.marginL));
|
||||
opacity: visible ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
z: -1
|
||||
}
|
||||
Behavior on y {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
opacity: visible ? 1.0 : 0.0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on y {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: previewLoader
|
||||
anchors.fill: parent
|
||||
active: launcherWindow.previewActive
|
||||
source: {
|
||||
if (!active)
|
||||
return "";
|
||||
var provider = launcherCore.activeProvider;
|
||||
if (provider && provider.previewComponentPath)
|
||||
return provider.previewComponentPath;
|
||||
Loader {
|
||||
id: previewLoader
|
||||
anchors.fill: parent
|
||||
active: launcherWindow.previewActive
|
||||
source: {
|
||||
if (!active)
|
||||
return "";
|
||||
}
|
||||
var provider = launcherCore.activeProvider;
|
||||
if (provider && provider.previewComponentPath)
|
||||
return provider.previewComponentPath;
|
||||
return "";
|
||||
}
|
||||
|
||||
onLoaded: updatePreviewItem()
|
||||
onItemChanged: updatePreviewItem()
|
||||
onLoaded: updatePreviewItem()
|
||||
onItemChanged: updatePreviewItem()
|
||||
|
||||
function updatePreviewItem() {
|
||||
if (!item || launcherCore.selectedIndex < 0 || !launcherCore.results[launcherCore.selectedIndex])
|
||||
return;
|
||||
var provider = launcherCore.activeProvider;
|
||||
if (provider && provider.getPreviewData) {
|
||||
item.currentItem = provider.getPreviewData(launcherCore.results[launcherCore.selectedIndex]);
|
||||
} else {
|
||||
item.currentItem = launcherCore.results[launcherCore.selectedIndex];
|
||||
}
|
||||
function updatePreviewItem() {
|
||||
if (!item || launcherCore.selectedIndex < 0 || !launcherCore.results[launcherCore.selectedIndex])
|
||||
return;
|
||||
var provider = launcherCore.activeProvider;
|
||||
if (provider && provider.getPreviewData) {
|
||||
item.currentItem = provider.getPreviewData(launcherCore.results[launcherCore.selectedIndex]);
|
||||
} else {
|
||||
item.currentItem = launcherCore.results[launcherCore.selectedIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update preview when selection changes
|
||||
Connections {
|
||||
target: launcherCore
|
||||
function onSelectedIndexChanged() {
|
||||
if (previewLoader.item)
|
||||
previewLoader.updatePreviewItem();
|
||||
}
|
||||
// Update preview when selection changes
|
||||
Connections {
|
||||
target: launcherCore
|
||||
function onSelectedIndexChanged() {
|
||||
if (previewLoader.item)
|
||||
previewLoader.updatePreviewItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user