mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Fix: Window things
This commit is contained in:
parent
6a8477758b
commit
f84c0aafa4
2 changed files with 152 additions and 70 deletions
|
|
@ -157,6 +157,7 @@ struct ClipboardPanelView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
// Header with tabs
|
||||
ClipboardPanelHeader(
|
||||
|
|
@ -195,6 +196,27 @@ struct ClipboardPanelView: View {
|
|||
.background(VisualEffectView(material: .hudWindow, blendingMode: .behindWindow))
|
||||
.cornerRadius(12)
|
||||
.shadow(color: .black.opacity(0.4), radius: 20, x: 0, y: 10)
|
||||
|
||||
// Close button positioned in top-left corner
|
||||
VStack {
|
||||
HStack {
|
||||
Button(action: onClose) {
|
||||
Image(systemName: "xmark")
|
||||
.font(.system(size: 12, weight: .medium))
|
||||
.foregroundColor(.white)
|
||||
.frame(width: 24, height: 24)
|
||||
.background(Color.red)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.padding(.leading, 12)
|
||||
.padding(.top, 12)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,13 +256,6 @@ struct ClipboardPanelHeader: View {
|
|||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.disabled(selectedTab == .history ? clipboardManager.clipboardHistory.isEmpty : clipboardManager.pinnedItems.isEmpty)
|
||||
|
||||
Button(action: onClose) {
|
||||
Image(systemName: "xmark")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.system(size: 12, weight: .medium))
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.top, 12)
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ class ColorPickerPanelManager: ObservableObject {
|
|||
hideColorPickerPanel() // Close any existing panel
|
||||
|
||||
let newPanel = ColorPickerPanel()
|
||||
newPanel.positionPanel()
|
||||
|
||||
self.panel = newPanel
|
||||
|
||||
// Make the panel key and order front to ensure it can receive focus
|
||||
// Position the panel
|
||||
newPanel.positionPanel()
|
||||
|
||||
// Make the panel visible and focused
|
||||
newPanel.makeKeyAndOrderFront(nil)
|
||||
newPanel.orderFrontRegardless()
|
||||
|
||||
|
|
@ -60,35 +61,52 @@ class ColorPickerPanelManager: ObservableObject {
|
|||
|
||||
class ColorPickerPanel: NSPanel {
|
||||
override var canBecomeKey: Bool { true }
|
||||
override var canBecomeMain: Bool { false }
|
||||
override var canBecomeMain: Bool { true }
|
||||
|
||||
init() {
|
||||
super.init(
|
||||
contentRect: NSRect(x: 0, y: 0, width: 450, height: 600),
|
||||
styleMask: [.titled, .closable, .fullSizeContentView],
|
||||
contentRect: .zero,
|
||||
styleMask: [.borderless, .nonactivatingPanel],
|
||||
backing: .buffered,
|
||||
defer: false
|
||||
defer: true
|
||||
)
|
||||
|
||||
setupPanel()
|
||||
}
|
||||
|
||||
private func setupPanel() {
|
||||
title = "Color Picker"
|
||||
level = .floating
|
||||
isMovableByWindowBackground = true
|
||||
backgroundColor = NSColor.clear
|
||||
backgroundColor = .clear
|
||||
isOpaque = false
|
||||
hasShadow = true
|
||||
|
||||
level = .floating
|
||||
isMovableByWindowBackground = true
|
||||
titlebarAppearsTransparent = true
|
||||
titleVisibility = .hidden
|
||||
isFloatingPanel = true
|
||||
|
||||
// Allow dragging from any part of the window
|
||||
styleMask.insert(.fullSizeContentView)
|
||||
|
||||
collectionBehavior = [
|
||||
.canJoinAllSpaces,
|
||||
.stationary,
|
||||
.fullScreenAuxiliary // Float above full-screen apps
|
||||
]
|
||||
|
||||
// Accept mouse moved events for proper hover behavior
|
||||
acceptsMouseMovedEvents = true
|
||||
|
||||
let panelView = ColorPickerPanelView {
|
||||
ColorPickerPanelManager.shared.hideColorPickerPanel()
|
||||
}
|
||||
|
||||
contentView = NSHostingView(rootView: panelView)
|
||||
let hostingView = NSHostingView(rootView: panelView)
|
||||
contentView = hostingView
|
||||
|
||||
// Set initial size
|
||||
let preferredSize = CGSize(width: 450, height: 600)
|
||||
hostingView.setFrameSize(preferredSize)
|
||||
setContentSize(preferredSize)
|
||||
}
|
||||
|
||||
func positionPanel() {
|
||||
|
|
@ -97,11 +115,46 @@ class ColorPickerPanel: NSPanel {
|
|||
let screenFrame = screen.visibleFrame
|
||||
let panelFrame = frame
|
||||
|
||||
let xPosition = screenFrame.midX - panelFrame.width / 2
|
||||
let yPosition = screenFrame.midY - panelFrame.height / 2
|
||||
// Check if we have a saved position
|
||||
if let savedPosition = getSavedPosition() {
|
||||
// Validate saved position is still on screen
|
||||
let savedFrame = NSRect(origin: savedPosition, size: panelFrame.size)
|
||||
if screenFrame.intersects(savedFrame) {
|
||||
setFrameOrigin(savedPosition)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Default to center of screen (not top center)
|
||||
let xPosition = (screenFrame.width - panelFrame.width) / 2 + screenFrame.minX
|
||||
let yPosition = (screenFrame.height - panelFrame.height) / 2 + screenFrame.minY
|
||||
|
||||
setFrameOrigin(NSPoint(x: xPosition, y: yPosition))
|
||||
print("ColorPicker: Panel positioned at \(xPosition), \(yPosition)")
|
||||
}
|
||||
|
||||
private func getSavedPosition() -> NSPoint? {
|
||||
let defaults = UserDefaults.standard
|
||||
let x = defaults.double(forKey: "colorPickerPanelPositionX")
|
||||
let y = defaults.double(forKey: "colorPickerPanelPositionY")
|
||||
|
||||
// Check if we have valid saved coordinates (not default 0.0)
|
||||
if x != 0.0 || y != 0.0 {
|
||||
return NSPoint(x: x, y: y)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func saveCurrentPosition() {
|
||||
let currentOrigin = frame.origin
|
||||
let defaults = UserDefaults.standard
|
||||
defaults.set(currentOrigin.x, forKey: "colorPickerPanelPositionX")
|
||||
defaults.set(currentOrigin.y, forKey: "colorPickerPanelPositionY")
|
||||
}
|
||||
|
||||
override func setFrameOrigin(_ point: NSPoint) {
|
||||
super.setFrameOrigin(point)
|
||||
// Save position whenever it changes (user dragging)
|
||||
saveCurrentPosition()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +179,7 @@ struct ColorPickerPanelView: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 0) {
|
||||
headerSection
|
||||
|
||||
|
|
@ -136,6 +190,27 @@ struct ColorPickerPanelView: View {
|
|||
}
|
||||
.background(ColorPickerVisualEffectView(material: .hudWindow, blendingMode: .behindWindow))
|
||||
.cornerRadius(12)
|
||||
|
||||
// Close button positioned in top-left corner
|
||||
VStack {
|
||||
HStack {
|
||||
Button(action: onClose) {
|
||||
Image(systemName: "xmark")
|
||||
.font(.system(size: 12, weight: .medium))
|
||||
.foregroundColor(.white)
|
||||
.frame(width: 24, height: 24)
|
||||
.background(Color.red)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.padding(.leading, 12)
|
||||
.padding(.top, 12)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.alert("Delete Color", isPresented: $showingDeleteAlert) {
|
||||
Button("Cancel", role: .cancel) { }
|
||||
Button("Delete", role: .destructive) {
|
||||
|
|
@ -195,14 +270,6 @@ struct ColorPickerPanelView: View {
|
|||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.disabled(colorPickerManager.colorHistory.isEmpty)
|
||||
|
||||
// Close Button
|
||||
Button(action: onClose) {
|
||||
Image(systemName: "xmark")
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue