Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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?
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
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?

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]) { ... }
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
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?

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]]) { ... }
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
The way to send a message to an object is to write for example...

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?
 

lucasgladding

macrumors 6502
Feb 16, 2007
319
1
Waterloo, Ontario
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.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
the color of my NSView...

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])
{
}
 

lucasgladding

macrumors 6502
Feb 16, 2007
319
1
Waterloo, Ontario
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]])
{

}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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.

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...
 

HiRez

macrumors 603
Jan 6, 2004
6,265
2,630
Western US
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...
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?
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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?

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 ==
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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])
{
}

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.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
You're calling color on the *class* NSView, not a particular instance of it. That definitely won't work.

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.
 

Catfish_Man

macrumors 68030
Sep 13, 2001
2,579
2
Portland, OR
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.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
the window background... the NSRect... but it's in a different class than my validateMenuItem function and i can't seem t reach it

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.
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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?
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 

lucasgladding

macrumors 6502
Feb 16, 2007
319
1
Waterloo, Ontario
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
 

Darkroom

Guest
Original poster
Dec 15, 2006
2,445
0
Montréal, Canada
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
 

lucasgladding

macrumors 6502
Feb 16, 2007
319
1
Waterloo, Ontario
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.