NSView a frame for a NSWindow

If I understand the NSView correctly… it make a frame in the window (NSWindow)

Here is the code, not sure if its correct…

use framework "Foundation"
use framework "AppKit"
use scripting additions

property arguments : missing value

on run
	if current application's NSThread's isMainThread() as boolean then
		my performDialog:arguments
	else
		my performSelectorOnMainThread:"performDialog:" withObject:arguments waitUntilDone:true
	end if
end run

on performDialog:arguments
	set {theWidth, theHeight} to {600, 300}
	set theWindow to createWindowWithRect(0, 0, theWidth, theHeight)
	-- Set the NSRect for the NSView
	set {topLeft, top, bottom, bottomRight} to {20, 20, 300, 150}
	set viewFrame to createView(topLeft, top, bottom, bottomRight)
	theWindow's contentView()'s addSubview:viewFrame
	
	set thePopUpButton to createPopupButton({"Red", "Green", "Blue"}, topLeft, top / 2, bottom / 2, bottomRight)
	viewFrame's addSubview:thePopUpButton
	
	theWindow's |center|()
	theWindow's makeKeyAndOrderFront:me
end performDialog:

on createPopupButton(entryList, xMin, yMin, xLen, yLen)
	set popUpButtonSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set thePopup to current application's NSPopUpButton's alloc()'s initWithFrame:popUpButtonSize
	thePopup's addItemsWithTitles:entryList
	thePopup's selectItemWithTitle:(item 1 of entryList)
	return thePopup
end createPopupButton

on createWindowWithRect(xMin, yMin, xLen, yLen)
	set windowSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:yes
	return theWindow
end createWindowWithRect

on createView(xMin, yMin, xLen, yLen)
	set frameSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set theView to current application's NSView's alloc()'s initWithFrame:frameSize
end createView

Trying to understand the constantOffset between 2 controls of NSPopUpButton
If I change the constantOffset from 0 - 35 there less is greater distance between.

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html#//apple_ref/doc/uid/TP40010853-CH7-SW1

use framework "Foundation"
use framework "AppKit"
use scripting additions

property constantOffset : 8
property arguments : missing value

on run
	if current application's NSThread's isMainThread() as boolean then
		my performDialog:arguments
	else
		my performSelectorOnMainThread:"performDialog:" withObject:arguments waitUntilDone:true
	end if
end run

on performDialog:arguments
	set {windowWidth, windowHeight} to {600, 300}
	set theWindow to createWindowWithRect(0, 0, windowWidth, windowHeight)
	-- Set the NSRect for the NSView
	set {topLeft, top, bottom, bottomRight} to {constantOffset, 0, windowWidth / 2, windowHeight / 2}
	set viewFrame to createView(topLeft, top, bottom, bottomRight)
	theWindow's contentView()'s addSubview:viewFrame
	set thePopUpButton1 to createPopupButton({"Red", "Green", "Blue"}, topLeft, top / 2, bottom / 2, bottomRight)
	viewFrame's addSubview:thePopUpButton1
	---
	set {topLeft, top, bottom, bottomRight} to {bottom / 2 - constantOffset, 0, windowWidth / 2, windowHeight / 2}
	set viewFrame to createView(topLeft, top, bottom, bottomRight)
	theWindow's contentView()'s addSubview:viewFrame
	set thePopUpButton2 to createPopupButton({"Strawberry", "Rasberry", "Blackberry"}, topLeft, top / 2, bottom / 2, bottomRight)
	viewFrame's addSubview:thePopUpButton2
	
	log viewFrame's frame()
	
	theWindow's |center|()
	theWindow's makeKeyAndOrderFront:me
end performDialog:

on createPopupButton(entryList, xMin, yMin, xLen, yLen)
	set popUpButtonSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set thePopup to current application's NSPopUpButton's alloc()'s initWithFrame:popUpButtonSize
	thePopup's addItemsWithTitles:entryList
	thePopup's selectItemWithTitle:(item 1 of entryList)
	return thePopup
end createPopupButton

on createWindowWithRect(xMin, yMin, xLen, yLen)
	set windowSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:yes
	return theWindow
end createWindowWithRect

on createView(xMin, yMin, xLen, yLen)
	set frameSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set theView to current application's NSView's alloc()'s initWithFrame:frameSize
end createView

Hi, Fredrik71.

Yes, everything seems to be correct. You create NSWindow as a parent object for placing further into some kind of hierarchy of views. In your case, you put the parent view in the window, and then you put the popup button in it.

Although, every NS button is also a special case of NSView. So you could put the pop up button directly in the window.( NSView simply creates empty frame).


use framework "Foundation"
use framework "AppKit"
use scripting additions

property arguments : missing value

on run
	if current application's NSThread's isMainThread() as boolean then
		my performDialog:arguments
	else
		my performSelectorOnMainThread:"performDialog:" withObject:arguments waitUntilDone:true
	end if
end run

on performDialog:arguments
	set {theWidth, theHeight} to {600, 300}
	set theWindow to createWindowWithRect(0, 0, theWidth, theHeight)
	-- Set the NSRect for the NSView
	set {topLeft, top, bottom, bottomRight} to {20, 20, 300, 150}
	set viewFrame to createPopupButton({"Red", "Green", "Blue"}, topLeft, top / 2, bottom / 2, bottomRight)
	theWindow's setContentView:viewFrame
	theWindow's |center|()
	theWindow's makeKeyAndOrderFront:me
end performDialog:

on createPopupButton(entryList, xMin, yMin, xLen, yLen)
	set popUpButtonSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set thePopup to current application's NSPopUpButton's alloc()'s initWithFrame:popUpButtonSize
	thePopup's addItemsWithTitles:entryList
	thePopup's selectItemWithTitle:(item 1 of entryList)
	return thePopup
end createPopupButton

on createWindowWithRect(xMin, yMin, xLen, yLen)
	set windowSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:yes
	return theWindow
end createWindowWithRect

I would take the approach of creating the elements.

Window, View and Pop Up elements 1st.
Then add them.
View add subview popUpButton
Window set contentView:View.

If your adding multiple buttons you should look into
NSView’s addsubview:positioned:relativeTo:
https://developer.apple.com/documentation/appkit/nsview/1483640-addsubview?language=objc

Then only create one window, one view and two popUp Buttons.

Add the popUp1 normally.
NSview addSubView:popUp1

Then use the addSubview:popUp2 positioned:NSWindowBelow relativeTo:popUp1

Or if your already know your exact positionings.
Create a NSRect for each popUpButton.
popUp1’s setFrame:buttonFrame1
Or
popUp2’s setFrame:NSMakeRect(offsite, 150, ((windowWidth - offset x 2) / 2), windowWidth/2)
Then just add both subViews normally.

NSview addSubView:popUp1
NSview addSubView:popUp2

You can add multiple buttons as well, without creating empty NSView. Directly: 1 window, 2 popup buttons:


property arguments : missing value

on run
	if current application's NSThread's isMainThread() as boolean then
		my performDialog:arguments
	else
		my performSelectorOnMainThread:"performDialog:" withObject:arguments waitUntilDone:true
	end if
end run

on performDialog:arguments
	set {theWidth, theHeight} to {600, 300}
	set theWindow to createWindowWithRect(0, 0, theWidth, theHeight)
	-- Set the NSRect for the NSView
	set {topLeft, top, bottom, bottomRight} to {20, 20, 300, 150}
	set viewFrame to createPopupButton({"Red", "Green", "Blue"}, topLeft, top / 2, bottom / 2, bottomRight)
	theWindow's setContentView:viewFrame
	set {topLeft, top, bottom, bottomRight} to {50, 50, 300, 150}
	set viewFrame2 to createPopupButton({"Red", "Green", "Blue"}, topLeft, top / 2, bottom / 2, bottomRight)
	theWindow's contentView()'s addSubview:viewFrame2
	theWindow's |center|()
	theWindow's makeKeyAndOrderFront:me
end performDialog:

on createPopupButton(entryList, xMin, yMin, xLen, yLen)
	set popUpButtonSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set thePopup to current application's NSPopUpButton's alloc()'s initWithFrame:popUpButtonSize
	thePopup's addItemsWithTitles:entryList
	thePopup's selectItemWithTitle:(item 1 of entryList)
	return thePopup
end createPopupButton

on createWindowWithRect(xMin, yMin, xLen, yLen)
	set windowSize to current application's NSMakeRect(xMin, yMin, xLen, yLen)
	set winStyle to (current application's NSWindowStyleMaskTitled as integer) + (current application's NSWindowStyleMaskClosable as integer)
	set theWindow to current application's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:2 defer:yes
	return theWindow
end createWindowWithRect

NOTE: this approach works with method contentView’s addsubview:positioned:relativeTo: as well. I tested it. And, I found NSScrollView more useful than pure NSView.