I need to add a menu item at the place where for example XCode place's the "Window" -> "Developers Documentation" menu item is available. This Menu Item needs a short cut and a checkmark if the window is open. Also the menu Item should close the window when chosen again.
For now I use.
import SwiftUI
import Foundation
import Combine
@main
struct Navigate_DetailApp: App {
@StateObject var listItemsViewModel : ItemModelView = ItemModelView()
@StateObject var appState = AppState()
@State var isProductWindowOpen = false
let someWindow = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 380, height: 300), styleMask: [.titled, .closable], backing: .buffered, defer: false)
var body: some Scene {
WindowGroup ("New") {
ContentView(appState: appState)
.frame(minWidth: 800, maxWidth: 900, minHeight: 500, maxHeight: 600)
.environmentObject(listItemsViewModel)
}
WindowGroup("Products") {
ProductsView()
}
Toggle("Products-toggle", isOn: $isProductWindowOpen)
.onChange(of: isProductWindowOpen) { ison in
print("isON")
if ison {
print("open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print("close")
someWindow.close()
}
}
.keyboardShortcut("0")
Button("Products-but open") {
//OpenWindows.ProductsView.open()
print("Menu Button Open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
}
.keyboardShortcut("1")
Button("Products-but close") {
print("Menu Button Close")
someWindow.close()
}
.keyboardShortcut("2")
Button("Products-but open/") {
print("Menu Button OpenClose Toggle")
isProductWindowOpen.toggle()
if isProductWindowOpen == true {
print("open")
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print("close")
someWindow.close()
}
}
.keyboardShortcut("3")
.... OLD CODE
func openProductsWindow() {
someWindow.contentView = NSHostingView(rootView: ProductsView())
self.someWindow.makeKeyAndOrderFront(nil)
}
func closeProductsWindow() {
.... ?? how to close the window
}
....
struct ProductsView: View {
var body: some View {
Text("Products")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}
What do I need to change to accomplish the placement of the menu item and let it close the window.
EDIT =================
Again thank you, it clarifies some issue's. Unfortunate it doesn't work. Did change some code to try to get it working but same effect; nothings happens. Looking with the debugger, it never comes to the action or print statement.
With the added Buttons and their code it works, for only one time. Meaning if I use the 'button open' it opens the ProductsView, if I use 'Button Close', it closes the window, but then it doesn't open it any more, however it shows the print statement in the debugger. What can I do to get both working, the Toggle and multiply using the Buttons ( No Checkmark ) ?
With the Button and then let it toggle, it works also only one time. Open and Close, but then its over, no more open or close window. The debugger shows:
Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
close
Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
open
Menu Button OpenClose Toggle
close
=========
Step Forward - New Code that works, but..
I did move the State to a StateObject blah blah, and that works okay, I show the code. But why does your code works for you but not for me?
@main
struct menuItemInsertWindowApp: App {
@StateObject var productMenuState = MenuState()
var body: some Scene {
WindowGroup {
ContentView()
}
WindowGroup("Products") {
ProductsView()
}
.commands {
CommandGroup(replacing: .windowList) {
ProductMenuItem(productMenuState: productMenuState)
}
}
}
}
struct ContentView: View {
var body: some View {
Text("ContentView")
.frame(minWidth: 600, maxWidth: 600, minHeight: 400, maxHeight: 400)
}
}
struct ProductsView: View {
var body: some View {
Text("Products")
.frame(minWidth: 500, maxWidth: 600, minHeight: 300, maxHeight: 400)
}
}
class MenuState : ObservableObject {
@Published var isProductWindowOpen = false
}
struct ProductMenuItem : View {
let someWindow = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 600, height: 400), styleMask: [.titled, .closable], backing: .buffered, defer: false)
@ObservedObject var productMenuState : MenuState
var body: some View {
Toggle("Products - Toggle That Works", isOn: $productMenuState.isProductWindowOpen)
.onChange(of: productMenuState.isProductWindowOpen) { value in
print( "change isProductWindowOpen" )
if value {
print( "ProductWindow Opens" )
someWindow.contentView = NSHostingView(rootView: ProductsView())
someWindow.makeKeyAndOrderFront(nil)
} else {
print( "ProductWindow Closes" )
someWindow.close()
}
}
}
}
It Works however if you look at the XCode log it shows some strange double called line's. Is this because of a macOS bug or XCode compiling bug or.... Is this solvable?
change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
change isProductWindowOpen
ProductWindow Opens
change isProductWindowOpen
ProductWindow Opens
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
onChange(of: Bool) action tried to update multiple times per frame.
change isProductWindowOpen
ProductWindow Closes
change isProductWindowOpen
ProductWindow Closes
Also later, duplicate windows of the window shows up, as well when I rapidly pressing the shortkeys.
Any suggestions?