NSColorWell afffects NSTextView

Moderator
Posts: 622
Joined: 2007.09
Post: #1
Is there a way to keep this from happening? I want an NSColorWell to affect a windows background color, but it is also affecting my textView text color. I am in a Document-Based app, if that is any help.Rolleyes
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #2
Can I take this as a "Not Possible"?
Quote this message in a reply
Luminary
Posts: 5,125
Joined: 2002.04
Post: #3
You should take it as "nobody has a clue what you're talking about".
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #4
OneSadCookie Wrote:You should take it as "nobody has a clue what you're talking about".

Oh.Annoyed

I have a Document-Based app, which contains a .nib file, which contains a Window, which contains a NSTextView. The same .nib file contains a Panel, which contains a NSColorWell. The NSColorWell is mapped to an Action which changes the color of the Windows background color. When I run my app, the NSColorWell changes the background color of the window, but it also changes the TextViews text color. Is there a way to circumvent this?
Quote this message in a reply
Moderator
Posts: 1,552
Joined: 2003.10
Post: #5
That doesn't sound like normal behavior. Presumably, it's either a bug in your code, or a bug in Cocoa. Either way, you might be able to work around it by manually resetting the text color in the NSColorWell's action method.
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #6
Wait a sec… Would setting acceptsFirstResponder to NO fix the problem? I'll try out both methods.

Thanks!

LG
Quote this message in a reply
⌘-R in Chief
Posts: 1,171
Joined: 2002.05
Post: #7
There's no bug here. Color wells don't have accept first responder status, and the color picker sends changeColor: to the first responder and sends the specified action to the specified target (in this case, the color well).

Your two choices:
1) Make the text view ignore the changeColor: if there is an active color well in the window.
2) Make the color well accept first responder status when made active, and resign first responder when made inactive.
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #8
How would you implement #1? Would that include subclassing NSTextView?

I tried #2 with the following code, which changed textViews text color, but did *not* affect the window background color.
Code:
- (IBAction)colorWindow:(id)sender{
    if([colorWellOut isEnabled]){
        [colorWellOut acceptsFirstResponder];
        NSColor *windowColor = [colorWellOut color];
        [windowOut setBackgroundColor:windowColor];
    }
    else{
        [colorWellOut resignFirstResponder];
    }
}
Quote this message in a reply
⌘-R in Chief
Posts: 1,171
Joined: 2002.05
Post: #9
1) Yes, you need to subclass NSTextView and override the changeColor: method. You'll need to walk down the view hierarchy from the window's content view and look for any view that's a color well, and see if it's active (Use [view isKindOfClass:[NSColorWell class]] && [(NSColorWell *)view isActive]). If one is, then just return early, otherwise call super's implementation ([super changeColor:sender]).

2) You did this all wrong. -acceptsFirstResponder does not invoke any action. Your first clue that this is so, is that the method does not read logically as one. (IOW 'accepts' is not a verb.) Your second clue should be the description of the method in the documentation.

You can't make an object be first responder if it doesn't want to be, and NSColorWell does not want to be. You need to subclass it and override acceptsFirstResponder to return YES. You could do it a few ways, but you could probably override the activate: and deactivate: methods to then call the window's method to have the color well make itself first responder, or resign.
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #10
So I am assuming that if I have several ColorWells that affect different aspects of the graphics, number 2 would be the easiest way to go?
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #11
Alright, I tried implementing #1, and this is what I came up with. I have an outlet called "windowOut" which I declared in my LGTextView class(My subclass of NSTextView). the windowOut outlet is linked to the contentView of the panel containing my NSColorWell. I have the following code in my LGTextView.m file.
Code:
#import "LGTextView.h"

@implementation LGTextView
- (void)changeColor:(id)sender{
    [windowOut isKindOfClass:[NSColorWell class]] && [(NSColorWell *)windowOut isActive];
}
@end

The ColorWell affects the windows background color as expected, but when I deactivate the ColorWell, and click the "Colors" button I have(Which is not a ColorWell) the text color does not change(Which it did before I added the above code).

EDIT: Wait a sec… in the "changeColor" method, couldn't I add an "If" statement to detect whether the ColorWell is active or not and then perform an action from there?

Hope this makes sense…

LG
Quote this message in a reply
Moderator
Posts: 1,552
Joined: 2003.10
Post: #12
Hairball183 Wrote:Hope this makes sense…

Nope. The isKindOfClass: and isActive methods simply return information to the caller; they don't actually perform any action. What on earth are you trying to do in the above changeColor: method? I'm really curious about your thought process, because there seems to be a fundamental misunderstanding here...
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #13
I am trying to make it so when a changeColor: action is called, the textView looks around to find out if there is an active ColorWell. If there *is*, then I want it to do nothing. If there *is not*, then I want the text color of the textView to change.
Quote this message in a reply
⌘-R in Chief
Posts: 1,171
Joined: 2002.05
Post: #14
Ok, well what you're actually doing is asking the window if it's a color well... Which obviously it's not.

Quote:You'll need to walk down the view hierarchy from the window's content view and look for any view that's a color well, and see if it's active (Use [view isKindOfClass:[NSColorWell class]] && [(NSColorWell *)view isActive])

All you did was replace 'view' with 'window' and think you did it correctly. You need to loop through every view in the window starting from the window's content view like I said before.

You'll need to do a breadth first search (or depth, but breadth is likely going to hit the color well first). You should read up on it if you don't know what it is. Look at the NSView documentation to find out how to get the subviews of a view, and look at NSWindow's documentation to find out how to get the content view of the window, which will be your starting point.
Quote this message in a reply
Moderator
Posts: 622
Joined: 2007.09
Post: #15
Is there any way to say thank you for all the help and sorry for the stupidity?Sad

Anyway, THANK YOU!!!Grin

and "I'm Sorry":cry:

I got it to work using method #1. And if only I had carefully read FreakSoftwares first post carefully instead of asking him to do it for me.Sad

Anyway, Thanks again.

Lincoln
Quote this message in a reply
Post Reply