remove blue shadow of NSButton - objective-c

Always (programmatically or via IB) i get this blue shadow on the first set button:
I want to get rid of it.. how?

That's called the focus ring, and it's to visually indicate which view is the first responder for key events.
If you don't want it to show up, you can use the -[NSView setFocusRingType:] method with the NSFocusRingTypeNone constant. This is also settable in Interface Builder.

This is to-do with the how the computer accesses windows via the keyboard. The highlight is notifying the user that this is the currently focused control.
To remove it from that control simply
[someOtherControl becomeFirstResponder];
Read more:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextEditing/Tasks/SetFocus.html

Related

NSColorWell not sending action on click?

Inside my .xib, I've placed an NSColorWell inside an NSView, and connected an IBAction in the controller to the NSColorWell's Sent Actions (via File's Owner). I figured I would respond to a click in my controller and send activate to bring up the NSColorPanel.
But unlike other my controls, I'm not getting the IBAction called. Clicking invokes a drag action on the color. I noticed this control doesn't derive from NSActionCell (like all my other controls). What's the proper control that is supposed to be used to both display a color and invoke the NSColorWell when clicked?
(note: this is Xcode/IB 3.2.x)
You listed both osx and ios in the tags, but I'm guessing this is an OS X problem.
There is a "Bordered" checkbox in IB's Attributes Inspector for NSColorWell. This toggles between a button-style color well, which is what you're asking for, and a color well which you can only drag a color swatch from. Make sure that's checked and you'll get the action like you're expecting.

NSTextField click-through?

I have a static NSTextField that overlays a large error message in my OS X app. I'm trying to get it to allow the user to click controls beneath it.
In IB I've unchecked "enabled" and I've checked "Refuses First Responder"
I've also done it in code because that wasn't working:
[largeErrorText setEnabled:NO];
[largeErrorText setRefusesFirstResponder:YES];
Still, it is getting in the way of interacting with the objects below it. Any ideas what else it might be?
The only way I have found to make an object transparent to the click is to subclass that object (in your case the NSTextField) and override the hitTest method returning nil. This way that NSTextField will not respond to the click so the NSView below will respond to the click.
- (NSView*)hitTest:(NSPoint)aPoint
{
return nil;
}
I assume you are describing a scenario like the following image shows:
The inner red rectangle is the frame outline of the NSTextField label, and you're saying that even though you've disabled the text field and set refuses first responder, your clicks do not go through to the NSButton?
This design scenario describes a condition called "Overlapping sibling views". I would generally try to avoid this if at all possible. If you can't, you can get the desired behavior by making sure that the NSTextField label is "behind" all of the other UI objects that you want to be able to interact with. You can do that by selecting the label and choosing Editor > Arrange > Send to Back. That will assure that the button is in front of the text field so that it can properly intercept mouse events.

How to force an NSWindow to be always active/focused?

I have a transparent NSWindow that follows the user's screen everywhere he goes (the NSWindowstays in front of every app, no matter what, even fullscreen apps).
In that NSWindow i have a mouseDown event that shows a popup. Let's say i'm on safari in fullscreen mode and i have my Window in front of it, i click on safari and i click again on my Window: nothing happens, the mouseDown doesn't occur. I have to click again so the mouseDown event is triggered.
How can i force my NSWindow to be always active so i don't have to click it 2x to trigger the mouseDown when i click on a background app and click in my window again?
Thank you!
I'm not sure if this is exactly what you want (it's not quite a window wide setting), but, from the documentation:
By default, a mouse-down event in a window that isn’t the key window
simply brings the window forward and makes it key; the event isn’t
sent to the NSView object over which the mouse click occurs. The
NSView can claim an initial mouse-down event, however, by overriding
acceptsFirstMouse: to return YES.
The argument of this method is the
mouse-down event that occurred in the non-key window, which the view
object can examine to determine whether it wants to receive the mouse
event and potentially become first responder. You want the default
behavior of this method in, for example, a control that affects the
selected object in a window.
However, in certain cases it’s
appropriate to override this behavior, such as for controls that
should receive mouseDown: messages even when the window is inactive.
Examples of controls that support this click-through behavior are the
title-bar buttons of a window.
Or you could try fiddling with
- (void)sendEvent:(NSEvent *)theEvent
and see if you can handle events in a custom way.
If you add a borderless NSButton instance to your window's view and set your image as the button's image (and as its alternate image, to make it more beautiful), it will work out of the box: Just connect the button's action method to your app delegate (or the object where you want to process the click action). A click on the image (i.e. the button) will then trigger the button's action method, no matter which window is active.
This worked for me, hope that will be helpful, This will keep your window always on Top of all applications
[self.window makeKeyAndOrderFront:nil];
[self.window setLevel:NSStatusWindowLevel];
I think what you really should do is use an NSPanel (a floating palette -- a special kind of NSWindow) that will do exactly what you want in a way that's consistent with the OS rather than trying to fight intended behavior.
Here's the NSPanel documentation:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/nspanel_Class/Reference/Reference.html
And here's some helpful and pithy information:
http://cocoadev.com/wiki/NSPanel
By default, an NSPanel will disappear when the application is inactive, but you can turn this off.
I apologize for not laying it out more fully ... pressed for time.
Edit:
Note that you can probably get your window to behave as desired simply:
"The NSView can claim an initial mouse-down event, however, by overriding acceptsFirstMouse: to return YES."
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html
You'll need to do this with any NSView subclass to skip the "activation click".

Setting tab order for NSTextFields of an NSView

I am trying to set the tab order for NSTextFields on a given NSView. As far as I understand it I have to connect the NSTextFields with InterfaceBuilder by setting the nextKeyView outlet to the next NSTextField. I did this - and there is no effect. When I press tab, after being in one of the NSTextFields it just loses focus and that is it. No matter how often I press tab none of the other NSTextFields regain focus.
I also read that I need to set the initialFirstResponder of the window. I don't think I can do this in this particular case, because my AppDelegate calls up a NSView which in turn acts as a Menu-Area with many different buttons, which each call up different NSViews that are loaded as subviews of a different view. Therefore the AppDelegate has no way of knowing which NSView is currently loaded.
Is there a way to set the tab-order of NSTextFields on an NSView-basis?
Thanks
You have to disable auto-recalculation of the key loop in the window. See -[NSWindow setAutorecalculatesKeyViewLoop:].
Edited to add: this can be set in Interface Builder, too.
This may or may not help for your situation, but the following worked for me when dealing with an NSView within another NSView. I had two vertical stacks of NSTextFields. Rather than traversing horizontally, I needed to tab down one stack and then the next... So I embedded each of the two vertical stacks in their own box (In IB, first select your items, Editor> Embed In> box). Works perfect.
If you don't want the look of a box, you can clear its title and set its border type to none: invisible box.

Changing focus from NSTextField to NSOpenGLView?

I am developing an interface for an OpenGL Simulation on the Mac using Interface Builder. All OpenGL stuff is being written in C++ (which I know fairly well). Unfortunately I have no idea about Objective-C.
Basically, I have a few NSTextField displaying info on an object selected on the Screen. Using these textfields the user is the able to manipulate the object on screen and then there is a Save Button and a Restore Button (which either save the new values or restore the original ones)
I have this all working. My problem is when I enter data into an NSTextField the "focus" of the windows seems to remain on the NSTextField (blue border remains around it).
I use the keyboard to interact with items within the NSOpenGLView, I need to pass the focus back to the NSOpenGLView when I hit either the Save or Restore buttons.
Sorry if this is a very straightforward question
Thanks
David
Have you tried using NSWindow makeFirstResponder method to make your NSOpenGLView the first responder?
Just managed to get it working.
I had to add the line:
[[NSApp keyWindow] makeFirstResponder: MyOpenGLView];
to the end of the function being called when I click on either of my buttons.
(Thanks Julio for pointing me in the right direction)