What is alternative to NSStatusItem.popUpMenu? - cocoa

NSStatusItem.popUpMenu has been deprecated in macOS 10.14, but I can't find a nice alternative.
let m = statusItem.menu!
statusItem.popUpMenu(m) // deprecated
I tried direct pop-up using menu and the button, but it doesn't position properly.
let m1 = m.items.first!
m.popUp(positioning: m1, at: .zero, in: statusItem.button!)

Xcode suggests to use menu property instead of popupMenu. But once you set the menu property, every click on the item will only show the menu.
Instead, if you want to control when the menu is shown, say only in response to a right click, then a simple way to manually trigger the menu is by calling performClick on NSStatusBarButton in your handler.
statusItem.menu = myMenu
statusItem.button?.performClick(nil)
statusItem.menu = nil
You have to set menu back to nil, if you want to keep handling clicks yourself.

Related

Delphi FMX TMainMenu first menu item doesn't show in OSX, OK in WIndows

I created a Multi-Device Application in Delphi Seattle and added a TMainMenu with MenuItem1 and MenuItem2 (nothing else). Building and running for OSX, only MenuItem2 shows. Building and running for Windows, both menu items show. I didn't treat the two menu items any differently. Both were just added and not customized in any way. Anyone else experience this?
The top level items in a Mac menu bar typically look like this:
Apple/system menu ('About this Mac', 'System Preferences...', etc.)
Application menu ('About XXX', 'Services', 'Hide XXX', 'Hide Others',
'Show All', 'Quit XXX')
File menu
Edit Menu
...
In FMX (excepting the very first version), the first top level item in a TMainMenu represents the application menu. As such, you need to add an item before File (or whatever is your current first item) that is only show on OS X; its sub-items should then include the usual items of a Mac application menu. To implement those items' behaviour, you can utilise standard actions (TFileHideApp, TFileHideAppOthers, TFileExit). Or, in more detail:
If there isn't one already, add a TActionList component to the form
Double click the action list to bring up the action list editor
Click on the add button's dropdown arrow, and select New Standard Action...
Select all of TFileHideApp, TFileHideAppOthers and TFileExit, and click OK
Back on the form, open up the menu editor by double clicking on the TMainMenu component
Add an item immediately before the first one that currently exists; in the Object Inspector, call it (say) mnuApp
Add at least four child items to mnuApp; using the Object Inspector, assign the Action property of the first to FileHideApp1, the second to FileHideAppOthers, and the fourth to FileExit1; set the Text of the third to a hyphen (-) to make it a separator
Close the menu editor
If one doesn't already exist, create a OnCreate handler for the form by double clicking its entry in the Object Inspector
Add to FormCreate a line to hide mnuApp if not running on OS X. Conversely, if you already have a menu item for File|Exit, this should be hidden if running on OS X since the functionality is now Quit under the application menu:
...
procedure TForm1.FormCreate(Sender: TObject);
begin
mnuApp.Visible := (TOSVersion.Platform = pfMacOS);
itmExit.Visible := (TOSVersion.Platform <> pfMacOS);
end;

How to deselect the contents of a TextField in swift

I have a simple desktop app where a TextField should be focused when the window loads. I have this working, but it's a little annoying that, having loaded the users content into the TextField, the entire contents of the field become selected automatically. The user may want to start editing the content, but they will rarely/never want to replace it all at once (imagine a text editor doing this, to see what I mean).
I see there is an Action for selectAll: but what I want is the opposite Action of selectNone:
I tried passing nil to the selectText method, but that doesn't work:
textField.selectText(nil)
I found a number of answers on StackOverflow that mention a selectedTextRange, but this appears to be outdated, because Xcode 6.3 doesn't recognize this as a valid property on TextField.
Can anyone explain how I do this?
It's been a while since I've dealt with NSTextFields to this level (I work mostly in iOS these days).
After doing a little digging I found this on the net:
NSText* textEditor = [window fieldEditor:YES forObject:textField];
NSRange range = {start, length};
[textEditor setSelectedRange:range];
window is the window containing your field, textField.
This requires the field editor to be managing your field, what can be done simply by previously selecting the whole text of the field using the selectText:sender method.
Here is the final swift code that I got working based on what Duncan C posted:
if let window = NSApplication.sharedApplication().mainWindow {
let textEditor = window.fieldEditor(true, forObject: textField)!
let range = NSRange(0..<0)
textEditor.selectedRange = range
}

How can I make a CMenu TrackPopupMenu SubMenu menu-item clickable?

Normally when you hover over a sub-menu (with the little arrow) on a CMenu menu item it delays briefly then shows the sub-menu items. Also, if you click the item before the delay timeout, it shows the sub menu items. I want the delay behavior, but I want a different behavior for the click. That is, I want the sub-menu itself (the one with the arrow) to be a clickable entity too, i.e. it has an ID and results in a WM_COMMAND and menu dismissal.
The idea is, the main sub-menu menu item is a "default", and the sub-menu items are modified versions, e.g. "print->" (defaulting to default printer), and sub-menu items like "print preview" "print to file" etc. Thanks for thoughts/suggestions.
edit:
IDR_MY_MENU MENUEX
BEGIN
POPUP "menu"
BEGIN
MENUITEM "&Something Else", ID_MENU_SOMETHING_ELSE
POPUP "&Print", ID_MENU_PRINT
BEGIN
MENUITEM "Print Pre&view", ID_MENU_PRINT_PREVIEW
MENUITEM "Print to &File", ID_MENU_PRINT_TO_FILE
END
MENUITEM "", -1, MFT_SEPARATOR
MENUITEM "&Bottom", ID_MENU_BOTTOM
MENUITEM "&Done", ID_MENU_DONE
END
END
I dont know if theres a better way as I last did this 2 years ago, but the way I solved the problem had one constraint: that you own the whole menu. If you do own the whole menu what you can do is create two columns (two columns in the menu/submenu that is, not a new submenu) and use the right column as a submenu and the left column as the default.
For future StackOverflowers, here's what I did...
Added a handler for OnInitMenuPopup and corresponding
ON_WM_INITMENUPOPUP(), although doing this messed up my UPDATE_COMMAND_UI handler but I was able to resolve that by moving that code into the OnInitMenuPopup handler.
In the OnInitMenuPopup handler, set a hook for the mouse SetWindowsHookEx(WH_MOUSE,...) (checking if one isn't already set because sub-menus can cause multiple calls)... and for each menu that initializes during the hook, push the HMENU onto a linked list.
In the mouse hook proc, checking the end of the list and working toward the front, verify each HMENU is still and active menu via IsMenu and remove it if it isn't. If there are no menus left, UnhookWindowsHook.
If there are menus left in the hook proc, check for WM_LBUTTONUP or WM_RBUTTONUP and see if happened over one of your menu items (because of coordinate mapping of screen versus sub-menu that I couldn't figure out I ended up simply cycling through the menu items via GetMenuItemRect and checking PtInRect to determine this).
If there is a click hit, do GetMenuItemInfo on the item, and if there's a hSubMenu for that item and it has an wID (and the wID doesn't match the sub-menu handle), simply post the id as a WM_COMMAND, post a WM_CANCELMODE to dismiss the menu, and disable the hook... Bingo!
So, seems to work fine and everything else functions like normal. The only issue at this point is a keyboard handler for selecting the item instead opening the sub-menu but I suspect the same idea works there as well.
Also, I added the main sub-menu text as the first item in the sub-menu list with a separator which added some clarity to what the menu was doing.

VB6 + how to switch between windows/frame in form by buttons

I am very new beginner with VB6 and I hope I explain the things right
I want to create form with 2 buttons (the buttons are located on the top form position )
So each button will switch to other form/window/frame
For example
The first button will show window 1 (there I can set only parameters)
The second button will show window 2 (there I can set only IP address)
Please advice if we can do that by VB6 ?
And if yes how to do that ( step by step )
Remark - Similar example but with multiple windows in the same form is the system properties ( right click on my computer and properties ) , the we can see each button will view different window
Create a form with 2 buttons, Command1 and Command2.
On this form, create 2 frames, Frame1 and Frame2. hide Frame2 and make sure to line up both framesso that they are of the same size and located right on top of each other (Top, Left, Width and Height properties must be the same)
Now put this code in:
Private Sub Command1_Click()
Frame1.Visible = True
Frame2.Visible = False
End Sub
Private Sub Command2_Click()
Frame1.Visible = False
Frame2.Visible = True
End Sub
Now each the first button shows the first frame while hiding the 2nd. The second button hides the first frame and shows the seconds. I think this is the simplest way to implement your task.
PS: don't forget to name your objects properly, it's not a good idea to have default names like Command1 or Frame2 - should be more descriptive than that.
It sounds like you are asking about the tabbed dialog control. To use a tabbed dialog control in VB6:
Click Project -> Components
Scroll down to "Microsoft Tabbed Dialog Control 6.0" and select it.
Click the Apply button.
You should notice a new control in the component tool box. If you do not see the toolbox, click View -> ToolBox. This is the same area of the IDE where you first click to add a button to a form. The tabbed dialog control looks like the top tab of several file folders. When you hover your mouse over the control in the toolbox, you will see a tool tip text of "SSTab". Click this control and then draw a rectangle on your form.
By default, this will add a tabbed dialog control with 3 tabs, but you can change this in the properties window. You can now create any control on top of a tab of the tabbed dialog control and interact with the control exactly the same way you would if the control was placed on the form itself.
What you want is called an MDI Form. It's a form that contains other forms.
You can find a full tutorial on them here, but here's the gist of what you want to do:
Set the "MDIChild" property of all your subforms you want to use to True. Disable their minimize, maximize, and resize functions as well.
Create an MDIForm. Disable its AutoShowChildren property.
Add a toolbar to the MDIForm. Add buttons to the toolbar corresponding to the forms you'll be switching between.
Implement each button's click event, to create child form as expected (or switch to an existing one).

How do I populate a popup button with AppleScript?

I've found this snippet of code in various place around the 'net:
tell window 1
tell menu of popup button 1
delete every menu item
repeat with catListItem in catList
make new menu item at end of menu items with properties {title:catListItem}
end repeat
end tell
end tell
When I use it in my AppDelegate script in a Cocoa-AppleScript Application, Xcode gives me an error: *t2t_AppDelegate.applescript:25: error: Expected end of line but found identifier. (-2741)* (Line 25 is "tell menu...")
I'm not sure what I'm missing that would allow me to dynamically populate the popup button with a list of terms (catList) that I'm drawing from another application. Any suggestions?
Unless you are running something earlier than Snow Leopard, It looks like you are using AppleScript Studio terminology (which was deprecated in Snow Leopard). Using the current AppleScriptObjC framework, the user interface items are referenced via outlet properties, for example:
property myPopUp : missing value
From the Interface Editor, this property is connected to your popup button, which allows you to use it with various methods in the NSPopupButton class and its parents, such as addItemsWithTitles. Once everything is defined and connected, you would use something like:
set catList to {"next item", "another item", "Items added"}
myPopUp's addItemsWithTitles_(catList)

Resources