how do you say an NSColor isVisible?

Discussion in 'Mac Programming' started by Darkroom, Jun 23, 2008.

  1. Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #1
    so for windows and panels i can write:
    Code:
    if (myWindow isVisible) {bla bla bla};
    
    but if i want to say if my color is red:
    Code:
    if (NSColor = redColor) {doesn't work};
    if (NSColor isEqual:redColor) {doesn't work, etc.}; 
    
    any thoughts?
     
  2. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    The way to send a message to an object is to write for example

    Code:
    [myWindow isVisible]
    
    The way to use a result in an if-statement is to write for example

    Code:
    if (result) { ... }
    
    If you want to use the result of sending a message to an object in an if-statement, you write for example

    Code:
    if ([myWindow isVisible]) { ... }
    
     
  3. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #3
    NSColor is a class. The expression "NSColor = redColor" looks like an assignment statement trying to assign something called redColor to a class named NSColor. What is that supposed to mean?

    In the second if, we have something looking slightly like a method call. Let's change it to

    if ([NSColor isEqual:redColor])

    Now you compare send the isEqual message to the class NSColor. That doesn't make sense. The NSColor class itself cannot be red or green or blue, only objects of that class can. So say we have

    NSColor* myColor = ...;
    if ([myColor isEqual:redColor])

    then I would think that you possibly meant the class method "redColor". You would write

    if ([myColor isEqual: [NSColor redColor]]) { ... }
     
  4. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #4
    right, sorry... i forgot the square brackets...

    i have the following function:

    Code:
    - (BOOL)validateMenuItem:(NSMenuItem *)item 
    	{
    	int itemTag = [item tag];
    	if ((itemTag == 5 || itemTag == 6) && ([[NSColorPanel sharedColorPanel] isVisible]))
    		return NO;
    	if ((itemTag == 7 || itemTag == 8) && ([B][NSColor whiteColor][/B]))
    		return NO;
    	return YES;
    	}
    
    but it doesn't really do anything because im trying to say if the color is currently white, than return no... you know?
     
  5. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    What colour? Or more accurately the colour of what? There is no general nebulous concept of the current colour...
     
  6. macrumors 6502

    Joined:
    Feb 16, 2007
    Location:
    Waterloo, Ontario
    #6
    What are you trying to check for the color? My first guess would be the current color in the color panel. If this is the case, your check would be:

    Code:
    NSColorPanel *cp = [NSColorPanel sharedColorPanel];
    NSColor *cpColor = [cp color];
    if ([cpColor isEqual:[NSColor whiteColor])
    {
        // insert your code here
    }
    
    As gnasher suggested, you should be comparing against a variable instead of a class. In the example above, cpColor would be your color instance that you would check against the color white.

    Note:
    If you ever want to compare whether two colors are similar, you can get the individual color components of each, find the difference between the individual components, get the absolute values of the differences, then compare the sum of those against any tolerance.
     
  7. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #7
    the color of my NSView...
     
  8. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    NSViews don't have a single colour, unless your view has a custom attribute which is it's colour (most NSViews have at least background and foreground colours).

    Anyway you should ask your view for it's current colour and compare that with the other colour. There is no way the NSColor class can guess what the hell you are thinking there: it's not as clever as us and we couldn't :p

    So assuming your custom NSView responds to -(NSColor *) color and we have an instance variable called myView pointing at the correct instance of the view something like this:

    Code:
    if ([myView color]==[NSColor whiteColor])
    {
    }
    
     
  9. macrumors 6502

    Joined:
    Feb 16, 2007
    Location:
    Waterloo, Ontario
    #9
    robbieduncan is correct about creating an NSView color property or accessor method. For the code, however, you will need to use isEqual: instead of == . The == operator will return false as it compares the memory addresses rather than the color value. == typically is only used to compare scalar values.

    Code:
    if ([[myView color] isEqual:[NSColor whiteColor]])
    {
    
    }
    
     
  10. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #10
    In general I agree with you, but my understanding of NSColor was that any given colour was singleton. For example [NSColor whiteColor]==[NSColor whiteColor] should return true as NSColor returns the same object every time for whiteColor instead of creating a new instance which is white...
     
  11. macrumors 6502

    Joined:
    Feb 16, 2007
    Location:
    Waterloo, Ontario
    #11
    I didn't know that, thanks for the tip.
     
  12. macrumors 601

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #12
    They might be singletons, but does writing [NSColor redColor] give you the same object as, for example, [colorWithDeviceRed:1.0 green:0.0 blue:0.0 alpha:1.0]? Not sure. It's the same color but does Cocoa detect when you're trying to make red by components and hand you the singleton?
     
  13. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #13
    I'd have to say I'm not sure, but I suspect that it does not so the isEqual: method is probably safer. I'd hazard a guess that CMYK colours returned are also not equal to their RGB equivalents when using ==
     
  14. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #14
    humm... i'm sure you're right, and i've tried lots but still can't get it to work... currently, i have this code:

    Code:
    - (BOOL)validateMenuItem:(NSMenuItem *)item 
    	{
    	if ((itemTag == 7 || itemTag == 8) && ([NSView color] isEqual:[NSColor whiteColor]))
    		return NO;
    	return YES;
    	}
    
    i'm probably missing something... it seems that because the NSView is in a different class i can't access it maybe? eventhough i've imported that class at the top of this implementation file.
     
  15. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #15
    You're calling color on the *class* NSView, not a particular instance of it. That definitely won't work.
     
  16. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #16
    but if i make an instance variable in the header file
    Code:
    @interface ColorController : NSObject
    	{
    	NSView *myView;
    	}
    
    and write this:
    Code:
    - (BOOL)validateMenuItem:(NSMenuItem *)item 
    	{
    	if ((itemTag == 7 || itemTag == 8) && ([myView color]==[NSColor whiteColor]))
    		return NO;
    	return YES;
    	}
    
    it still doesn't work. it keeps saying that NSView may not respond to color... driving me crazy... totally TOTALLY lost.
     
  17. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #17
    Well, you might read up the thread to where someone pointed out that NSView doesn't have a color method... I'm really not sure where you got that method name from.
     
  18. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #18
    I don't really know what you're trying to achieve here... but maybe the reference documents will be helpful?
    NSView reference:
    http://developer.apple.com/document...it/Classes/NSView_Class/Reference/NSView.html

    Any methods with a + are called on the Class NSView. Anything with a - are called on an instance of NSView that you have instantiated.

    NSColor reference:
    http://developer.apple.com/document...lasses/NSColor_Class/Reference/Reference.html

    Reviewing the NSView document there is nothing that returns an NSColor which you could compare to, for example [NSColor whiteColor], which returns an NSColor with preset values.

    lucasgladding mentioned above something that you COULD compare an NSColor to, but I really have no idea what you're wanting to evaluate. Do you want to see if the window's background color is some value? The frame? Some text?

    -Lee
     
  19. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #19
    the window background... the NSRect... but it's in a different class than my validateMenuItem function and i can't seem t reach it
     
  20. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #20
    I don't think there's any NSRect involved here, but you can get the NSColor for your window background with:
    Code:
    NSColor *myBGColor = [[myView window] backgroundColor];
    if([myBGColor isEqual: [NSColor whiteColor]]) {
      //do something
    }
    This thread:
    http://www.cocoabuilder.com/archive/message/cocoa/2005/5/3/134581

    Discusses differences in color spaces. You may not have to worry about this, I can't say for sure.
     
  21. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #21
    thanks for the help everyone... i'm learning slowly but surely...

    one new problem is that my About window, and every other Menu Item under the APPLICATION menu bar (except for hide, hide others, show all and quit) now makes the app crash... does having more than one validateMenuItem function in different classes cause problems? these menu items that cause the app to crash have a tag of 0 because i don't need to validate them, so i'm not sure what the problem is? it acts like a memory problem, but my app only use to crash before because i forgot to retain certain objects, so i only have experience with bad memory management... any thoughts?
     
  22. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #22
    If we've resolved or mostly resolved the NSColor issue, it would be best if you posted a new question in a separate thread regarding your menu behavior. Someone who knows a great deal about menu setup may never look at a thread about NSColor.

    -Lee
     
  23. macrumors 6502

    Joined:
    Feb 16, 2007
    Location:
    Waterloo, Ontario
    #23
    Darkroom

    I'm not sure whether or not your original question was ever answered...

    Your view is likely a subclass of NSView. Assuming this to be correct, you should have an instance variable declared for the background color of the view as well as getter/setter methods (or an equivalent property).

    Code:
    @interface ColorView : NSView
    {
         NSColor *backgroundColor
    }
    - (NSColor *)backgroundColor;
    - (void)setBackgroundColor:(NSColor *)newColor;
    
    The other problem lies in the interface for your view controller. Make sure you declare your subclass not the superclass (NSView in this case). The class determines which methods are available to the object. Even if you initialize the object with your subclass, The compiler will look at the class name to determine which methods are available. You may have already written the accessors for the backgroundColor variable of the ColorView, but you have defined myView as an NSView.

    Code:
    @class ColorView;
    @interface ColorController : NSObject
    {
         ColorView *myView;
    }
    
    Regarding the other problem, set a breakpoint in the validate method and use the debugger to check for problems. If you haven't already, read through the debugging sections of the Xcode user manual.

    Best of luck
     
  24. thread starter Guest

    Darkroom

    Joined:
    Dec 15, 2006
    Location:
    Montréal, Canada
    #24
    ok... still no go... i'll post the code of the 2 classes (windowColor and ColorController)... i'm assuming that some of the posted code isn't really applicable to this problem, so i apologize for posting it if it's not (fade outs, etc.). the problem code is near the bottom of the 2nd class (bolded and red):

    NSView:
    Code:
    #import <Cocoa/Cocoa.h>
    ------------ windowColor.h ------------
    @interface windowColor : NSView
    	{
    	NSColor *fillColor;
    	}
    
    - (IBAction)changeColor:(id)sender;
    - (IBAction)changeWhite:(id)sender;
    
    @end
    
    
    ------------ windowColor.m ------------
    #import "windowColor.h"
    
    @implementation windowColor
    
    - (id)initWithFrame:(NSRect)frame
    	{
    	self = [super initWithFrame:frame];
    	if (self)
    		{
    		NSData *defaultViewColorData = [[NSUserDefaults standardUserDefaults] dataForKey:DEFAULTS_VIEW_COLOR_KEY];
    		if (defaultViewColorData != nil)
    			{
    			[fillColor release];
    			fillColor = [[NSUnarchiver unarchiveObjectWithData:defaultViewColorData] retain];
    			}
    		}
    	return self;
    	}
    
    - (void)dealloc
    	{
    	[super dealloc];
    	[fillColor release];
    	}
    
    - (IBAction)changeColor:(id)sender
    	{
    	NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[sender color]];
    	[[NSUserDefaults standardUserDefaults] setObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
    	[fillColor release];
    	fillColor = [[sender color] retain];
    	[self setNeedsDisplay:YES];
    	}
    
    - (IBAction)changeWhite:(id)sender
    	{
    	NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[NSColor whiteColor]];
    	[[NSUserDefaults standardUserDefaults] setObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
    	[fillColor release];
    	fillColor = [[NSColor whiteColor] retain];
    	[self setNeedsDisplay:YES];
    	}
    
    - (void)drawRect:(NSRect)rect
    	{
    	[fillColor set];
    	NSRectFill(rect);
    	}
    
    @end
    
    ColorController:
    Code:
    ------------ ColorController.h ------------
    #import <Cocoa/Cocoa.h>
    #import "windowColor.h"
    
    @interface ColorController : NSObject
    	{
    	IBOutlet windowColor *myColorSelection;
    	IBOutlet windowColor *myWhiteSelection;
    	NSTimer *timer;
    	}
    
    - (IBAction)selectColor:(id)sender;
    - (IBAction)selectWhite:(id)sender;
    
    @end
    
    
    ------------ ColorController.m ------------
    #import "ColorController.h"
    #import "windowColor.h"
    #import "HUDColorPanel.h"
    
    @implementation ColorController
    
    + (void)initialize
    	{
    	[[HUDColorPanel class] poseAsClass:[NSColorPanel class]];
    	NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[NSColor whiteColor]];
    	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    	NSDictionary *myDefaults = [NSDictionary dictionaryWithObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
    	[defaults registerDefaults:myDefaults];
    	}
    
    - (id)init
    	{
    	if (self = [super init])
    		{
    		[[NSColorPanel sharedColorPanel] setDelegate:self];
    		}
    	return self;
    	}
    
    - (IBAction)selectColor:(id)sender
    	{
    	if ([[NSColorPanel sharedColorPanel] isVisible])
    		{
    		[[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil];
    		}
    		else
    		{
    		[[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil];
    		[[NSColorPanel sharedColorPanel] setAlphaValue:0.0];
    		timer = [[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(colorPanelFadeIN:) userInfo:nil repeats:YES] retain];
    		}
    	}
    
    - (void)colorPanelFadeIN:(NSTimer *)theTimer
    	{
    	if ([[NSColorPanel sharedColorPanel] alphaValue] < 1.0)
    		{
    		[[NSColorPanel sharedColorPanel] setAlphaValue:[[NSColorPanel sharedColorPanel] alphaValue] + 0.1];
    		}
    		else
    		{
    		[timer invalidate];
    		[timer release];
    		timer = nil;
    		}
    	[[NSColorPanel sharedColorPanel] setTarget:myColorSelection];
    	[[NSColorPanel sharedColorPanel] setAction:@selector(changeColor:)];
    	}
    
    - (BOOL)windowShouldClose:(id)window
    	{
    	timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(colorPanelFadeOUT:) userInfo:window repeats:YES];
    	return NO;
    	}
    
    - (void)colorPanelFadeOUT:(NSTimer *)theTimer
    	{
    	NSWindow* window = [timer userInfo];
    	[window setAlphaValue:[window alphaValue] -0.1];
    	if([window alphaValue] <= 0.0)
    		{
    		[timer invalidate];
    		[window close];
    		}
    	}
    
    - (IBAction)selectWhite:(id)sender
    	{
    	[myWhiteSelection changeWhite:nil];
    	}
    
    #pragma mark Disable Menu Items
    
    - (BOOL)validateMenuItem:(NSMenuItem *)item 
    	{
    	int itemTag = [item tag];
    	if ((itemTag == 5 || itemTag == 6) && ([[NSColorPanel sharedColorPanel] isKeyWindow]))
    		return NO;
    [COLOR="Red"][B]	if ((itemTag == 7 || itemTag == 8) && (??? WHAT ??? == [color whiteColor]))
    		return NO;[/B][/COLOR]
    	return YES;
    	}
    
    @end
    
     
  25. macrumors 6502

    Joined:
    Feb 16, 2007
    Location:
    Waterloo, Ontario
    #25
    A couple notes:

    As suggested in my earlier post, try adding getter and setter methods to your view class. You can remove some duplicate code by doing so.

    Code:
    - (NSColor *)fillColor
    {
    return fillColor;
    }
    - (void)setFillColor:(NSColor *)newColor
    {
    NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:newColor];
    [[NSUserDefaults standardUserDefaults] setObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
    [fillColor release];
    fillColor = [newColor retain];
    [self setNeedsDisplay:YES];
    }
    
    From your view controller:

    Code:
    ...
    if ((itemTag == 7 || itemTag == 8) && ([myWhiteSelection fillColor] == [NSColor whiteColor]))
    ...
    
    Classes typically talk to each other through accessor methods. Take some serious time going through tutorials line for line before getting ambitious. It looks like you will also need to do some reading about class methods vs instance methods. Finally, be careful to review your own code before asking for input. Things like the missing brackets from your first post will deter help from most programmers.

    Good luck
     

Share This Page