Creating a Color Meter Using Cocoa
Pages: 1, 2
The controller object
In object-oriented programming, there are several paradigms for organizing objects and classes in an application. Our application is simple so our needs for organization are simple.
We will employ what is known as the Model-View-Controller paradigm. "View" is the interface of your application -- the sliders, text fields, and color well in our application. "Model" is the data model for our application.
Our application doesn’t deal with data at all, so we won’t have a model object. "Controller" is an object that that links your interface to the data model. In this paradigm, the interface should not know anything about how the data is stored and managed, and the model should have no knowledge of how to display the interface. It's the controller object’s responsibility to communicate between these two realms. Let's make our controller object.
From the classes tabbed view, find the NSObject class in the list of available classes. We want to create a subclass of it. Do this by selecting "Subclass" from the Classes menu, and name it "Controller".
Now add the objects and actions shown in the picture below with the same names. New objects and actions can be created from the same Classes menu.
|
The next step is to instantiate our new class so we can connect the outlets and actions to their appropriate interface objects. The names should explain how to wire them up. Remember, wire actions by starting at the interface object -- a slider -- and control-drag to the instance of the Controller. Objects are wired in the opposite direction. Remember, wire in the direction messages would travel.
Once you have made all the connections, you need to add the interface and implementation files of our controller class to our project in Project Builder. This is done easily enough by going back to the Classes tab, selecting the Controller class, and then selecting Create Files from the Classes menu.
Close Interface Builder and return to Project Builder.
Coding
The way our color meter application operates is as follows: The user of the application will be able to slide the color sliders about for each component of the final color: red, green, blue, and alpha. As the user manipulates the controls, the color will update in real time. Additionally, the value of the slider will be displayed in the text field to the right of each slider. Now, all we have to do is supply the code that will create a color in the color well that corresponds to the values of red, green, blue, and alpha.
The first thing we want to do is declare four instance variables of type "float" that store values of each component of the final color. In the interface file Controller.h insert after the IBOutlet instance variables the following four variables:
float redValue;
float greenValue;
float blueValue;
float alphaValue;
Additionally, we want to add a method to this class that will update the color displayed in the color well. That method is
- (void)updateColor;
So our code should look like this:
#import <Cocoa/Cocoa.h>
@interface Controller : NSObject
{
IBOutlet id alphaField;
IBOutlet id alphaSlider;
IBOutlet id blueField;
IBOutlet id blueSlider;
IBOutlet id colorWell;
IBOutlet id greenField;
IBOutlet id greenSlider;
IBOutlet id redField;
IBOutlet id redSlider;
float redValue;
float greenValue;
float blueValue;
float alphaValue;
}
- (IBAction)setAlpha:(id)sender;
- (IBAction)setBlue:(id)sender;
- (IBAction)setGreen:(id)sender;
- (IBAction)setRed:(id)sender;
- (void)updateColor;
@end
The four action methods that set the color components will all have the same structure.
Here is the code for setBlue:
- (IBAction)setBlue:(id)sender
{
blueValue = [sender floatValue];
[blueField setFloatValue:blueValue];
[blueSlider setFloatValue:blueValue];
[self updateColor];
}
In the first line, we are asking the sender who is invoking the setBlue method for the floatValue of its data, and storing that in blueValue. In this case, the sender can be one of two objects in the interface.
If you recall, we wired both the Blue slider control and the Blue text field to the same action. Depending on the user's actions, either of these objects can be the sender of the message invoking this method. This is nature of all IBAction methods. That is, the action method argument is the sender object. This makes it easy to get information from the interface, while maintaining a good deal of flexibility in our code, as was demonstrated here. It also means we don’t have to write an additional action methods for additional controls to interact with. We can add as many controls as we want to change the blue color value and wire them all to this same action. This is also the power of polymorphism, as all Cocoa controls respond to the floatValue method in the same way, by returning a float-typed number.
The purpose of the middle two lines is to synchronize the values displayed in the slider and the text field. Thus, if the slider was the sender, the text field would take on the appropriate value, and vice versa. The setFloatValue: method does the exact opposite as floatValue. Where floatValue returns the value of the control as a float, setFloatValue: takes a float argument and sets the controls data value to the argument.
The last line simply tells the controller object (self, since this method is sending a message from itself to itself) to update the color displayed in the color well. We could have put the appropriate code to update the color in the color well in each of the "set...methods", but one of the goals of object-oriented programming is to reuse as much code as possible. Thus, by extracting the update code from each method and placing it in its own method, which is called by the "set...methods", we are reusing that code. The clear benefit of this is that if we want to change that code for whatever reason, we need only do it in one place, rather than four.
The setGreen:, setRed:, and setAlpha commands are exactly the same as setBlue:, except everywhere you see Blue, you replace it with Red, Green, or Alpha; and everywhere you see blue, you replace it with red, green, or alpha.
Since updateColor is not an Interface Builder action method like the others, we have to define it manually (that's why we had to add it to the interface file earlier as well). Here is the code for the updateColor: method:
- (void)updateColor
{
NSColor *aColor = [NSColor colorWithCalibratedRed:redValue green:greenValue blue:blueValue alpha:alphaValue];
[colorWell setColor:aColor];
}
What we do first is create a new color by calling the colorWithCalibratedRed: green: blue: alpha: method and store the returned color object in the aColor variable, which is declared locally on the same line. The NSColor method we invoke here is one of many that are available for creating colors. There are some NSColor class methods that return a present color, such as redColor. If you want to read more about NSColor, check out its class reference page here: NSColor (Objective-C).
Finally, in the same way we display a number in a text field using setFloatValue:, we display a color in the color well object by sending it a setColor: message with the newly created color object.
The end
And that’s it! Compile your code (hopefully, you won’t have any errors), run it, and play around with it. If you want to see another cool freebie in Cocoa, click on the color well and before your very eyes watch the system color-picker appear. Now we didn’t add any code to update the text fields and sliders to reflect the new color being set in the color well through the picker, but I encourage you to read the class references for the classes we talked about, and see if you can’t make that work (if you get stuck, write it up as a Talk Back and we'll figure it out online).
|
In the next few columns, I’m going to be doing less complete applications, and talk more about individual classes from the Foundation framework that deal with strings, numbers, and collections. Hope you enjoyed this one. Talk to you next time!
Michael Beam is a software engineer in the energy industry specializing in seismic application development on Linux with C++ and Qt. He lives in Houston, Texas with his wife and son.
Read more Programming With Cocoa columns.
Return to the Mac DevCenter.
-
How to display the Colervalues in Hex oder %?
2005-01-23 08:22:00 Humunculus [View]
-
I just completed my assignment...
2004-09-21 14:04:13 clsanchez [View]
-
Nice series
2003-10-27 05:14:29 anonymous2 [View]
-
Can't get a decent build
2003-08-19 11:06:36 anonymous2 [View]
-
Can't get a decent build
2003-08-19 11:46:15 anonymous2 [View]
-
? What kind of application and whats up with the classes tab
2003-08-03 09:44:02 anonymous2 [View]
-
I just made it through this tutorial
2003-08-04 11:45:47 the_doug [View]
-
Really Annoying...
2003-07-24 15:42:29 anonymous2 [View]
-
Color Wheel does not affect Color Well
2003-07-06 18:13:44 anonymous2 [View]
-
Color Meter compiling problems
2003-07-06 11:02:48 anonymous2 [View]
-
Color Meter compiling problems
2004-01-02 16:49:48 anonymous2 [View]
-
Color Meter compiling problems
2003-07-06 10:59:27 anonymous2 [View]
-
Parse Error
2003-03-29 18:48:55 anonymous2 [View]
-
Java Version - Solution
2002-05-25 15:08:31 jsumnertx [View]
-
Extending ColorMeter
2001-12-27 02:47:04 michele [View]
-
Color Meter[971] *** -[NSImageView setColor:]: selector not recognized
2001-10-07 18:25:38 jorgeherrera [View]
-
Color Meter[971] *** -[NSImageView setColor:]: selector not recognized
2001-10-08 22:28:00 jorgeherrera [View]
-
Solved
2001-10-09 13:46:20 jorgeherrera [View]
-
awakeFromNib
2001-09-16 13:49:15 sork [View]
-
awakeFromNib
2001-10-02 20:09:05 rick1138 [View]
-
Problems with Color Meter
2001-07-19 14:02:22 iansloman [View]
-
Problems with Color Meter
2001-07-22 03:26:08 pengo98 [View]
-
Problems with Color Meter
2001-07-23 11:38:02 iansloman [View]
-
Problems with Color Meter cont'd.
2001-07-19 14:09:33 iansloman [View]
-
Nothing Works
2001-07-04 13:21:53 kjl007 [View]
-
oops
2001-07-04 13:56:49 kjl007 [View]
-
Unknown class `Controller'
2001-06-29 20:36:12 spfirman [View]
-
Wierd build problem
2001-06-22 14:57:30 canyonrat [View]
-
RE:Wierd build problem
2001-06-27 15:28:24 larryvp [View]
-
RE:Wierd build problem
2001-06-28 08:28:53 canyonrat [View]
-
Color wheel...
2001-06-20 06:31:33 rainwadj [View]
-
Color wheel...
2001-06-20 07:46:12 rainwadj [View]
-
init code
2001-06-19 13:59:30 rainwadj [View]
-
re: init code
2001-06-19 14:11:51 davidmasters [View]
-
re: init code
2001-06-20 06:25:16 rainwadj [View]
-
Drag and Drop caused some problems
2001-06-18 19:56:09 kinger [View]
-
Drag and Drop caused some problems
2001-06-18 20:43:41 psheldon [View]
-
controls not visible in color meter run
2001-06-18 19:01:38 psheldon [View]
-
made controls visible
2001-06-18 20:37:43 psheldon [View]
-
I'm missing something
2001-06-18 00:15:46 rdomidion [View]
-
I'm missing something
2001-06-18 07:13:05 Michael Beam |
[View]
-
Works great!
2001-06-16 12:30:53 donarb [View]
-
Works great!
2001-06-19 22:43:24 johnts [View]
-
Debugging
2001-06-16 07:58:40 retro [View]
-
Reply to thebod's posts, and correction
2001-06-16 03:46:57 Michael Beam |
[View]
-
Reply to thebod's posts, and correction
2001-06-22 14:28:40 canyonrat [View]
-
Reply to thebod's posts, and correction
2001-06-17 21:28:13 thebod [View]
-
doesn't build
2001-06-15 21:40:54 thebod [View]



