TweetFollow Us on Twitter

Color
Volume Number:10
Issue Number:10
Column Tag:Getting Started

Related Info: Color Quickdraw

Working With Color

By Dave Mark, MacTech Magazine Regular Contributing Author

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

This month’s column combines two of my favorite activities: working with color and rewriting Primer, Volume II code (bringing it from the Pliocene era to full PowerPC squishiness). This month’s program is a floor to ceiling rewrite of ColorTutor. ColorTutor is a hands-on color blending environment. You specify the foreground and background colors and patterns, then select a Color Quickdraw drawing mode. ColorTutor uses CopyBits() to mix the foreground and background colors. Figure 1 shows a sample.

Figure 1. The ColorTutor window.

ColorTutor first copies the Background image to the lower-right rectangle, then copies the Source image on top of the Background using the current Mode and OpColor. Since this program is so large, we’ll get into the details in next month’s column. For now, we’ll focus on putting the project together and getting ColorTutor up and running.

The ColorTutor Resources

ColorTutor uses six different resource types: an ALRT, a CNTL, a DITL, an MBAR, a MENU, and a WIND. Start by creating a folder named ColorTutor in your Projects folder. Next, fire up ResEdit or Resorcerer and create a new file named ColorTutor.Π.rsrc in the ColorTutor folder.

Create an ALRT resource with an ID of 128, a top of 40, left of 40, bottom of 156 and right of 332. Make sure the DITL ID is set to 128.

Next, create a DITL with an ID of 128. Figure 2 shows the specifications for item 1, the OK button, and Figure 3 shows the specs for item 2, the static text field. The alert you just created is used to display an error message.

Figure 2. Specifications for the OK button.

Figure 3. Specifications for item 2, the static text field.

Next, you’ll create a CNTL resource with an ID of 128. The CNTL will be used to implement the OpColor button in the lower-left corner of the ColorTutor window. The ProcID of 0 specifies a pushButtonProc control.

Figure 4. Specifications for the CNTL resource.

Now create an MBAR resource with an ID of 128. Add the menu IDs 128, 129, and 130 (the •, File, and Edit menus) to the MBAR. Though we’ll be creating 5 menus, don’t be fooled. Only the first three will be added to the menu bar.

Next, you’ll create five MENU resources. The first four are shown in Figure 5, and the fifth in Figure 6. MENUs 128, 129, and 130 will be used to create the menu bar. The last two implement the ColorTutor popup menus. Note that the popup menus don’t have titles. Note also that MENU 132 has 17 items including the separator line (the 9th item).

Figure 5. Specifications for the first four MENUs.

Figure 6. Specifications for the two popup MENUs.

The last resource is a WIND with a resource ID of 128. Figure 7 shows the ResEdit WIND editing screen for my WIND. This WIND implements the main ColorTutor window.

Figure 7. Specifications for the WIND resource.

Finally, save your changes and quit your resource editor.

The ColorTutor Project

Next, pick your development environment and create a new project. From now on, I’ll test all my source code to make sure it compiles in both THINK C and CodeWarrior, so it shouldn’t matter which environment you pick. Create your new project with the name ColorTutor.Π inside the ColorTutor folder.

Next, add MacTraps to the project if you are using THINK C, or MacOS.lib if you are using CodeWarrior.

Finally, create a new source code file, save it as ColorTutor.c, and add it to the project. Here’s the source code:


/* 1 */
#include <Picker.h>
#include <GestaltEqu.h>


#define kBaseResID 128
#define kErrorALRTid 128
#define kNullFilterProc   NULL
#define kMoveToFront (WindowPtr)-1L
#define kNotNormalMenu    -1
#define kSleep   60L

#define mApple   kBaseResID
#define iAbout   1

#define mFile    kBaseResID+1
#define iQuit    1

#define mColorsPopup kBaseResID+3
#define iBlackPattern1
#define iGrayPattern 2
#define iColorRamp 4
#define iGrayRamp5
#define iSingleColor 6

#define mModePopup kBaseResID+4

Globals
Boolean gDone;

Rect    gSrcRect, gBackRect, gDestRect, gSrcMenuRect,
 gBackMenuRect, gModeMenuRect, gOpColorRect;
 
intgSrcPattern, gBackPattern, gCopyMode, gSrcType,
 gBackType;

RGBColorgSrcColor, gBackColor, gOpColor;

MenuHandlegSrcMenu, gBackMenu, gModeMenu;

Functions
void    ToolboxInit( void );
void    MenuBarInit( void );
void    CreateWindow( void );
void    SetUpGlobals( void );
void    EventLoop( void );
void    DoEvent( EventRecord *eventPtr );
void    HandleMouseDown( EventRecord *eventPtr );
void    HandleMenuChoice( long menuChoice );
void    HandleAppleChoice( short item );
void    HandleFileChoice( short item );
void    DoUpdate( WindowPtr window );
void    DrawContents( WindowPtr window );
void    DrawColorRamp( Rect *rPtr );
void    DrawGrayRamp( Rect *rPtr );
void    DrawLabel( Rect *boundsPtr, Str255 s );
void    DoContent( WindowPtr window, Point globalPoint );
void    UpdateSrcMenu( void );
void    UpdateBackMenu( void );
void    UpdateModeMenu( void );
void    DoSrcChoice( short item );
void    DoBackChoice( short item );
void    DoModeChoice( short item );
short   DoPopup( MenuHandle menu, Rect *boundsPtr );
Boolean PickColor( RGBColor *colorPtr );
Boolean HasColorQD( void );
void    DoError( Str255 errorString );

main
void  main( void )
{
 ToolboxInit();
 MenuBarInit();
 
 if ( ! HasColorQD() )
 DoError( "\pThis machine does not support Color QuickDraw!" );

 CreateWindow();
 SetUpGlobals();
 
 EventLoop();
}

ToolboxInit
void  ToolboxInit( void )
{
 InitGraf( &qd.thePort );
 InitFonts();
 InitWindows();
 InitMenus();
 TEInit();
 InitDialogs( 0L );
 InitCursor();
}

MenuBarInit
void  MenuBarInit( void )
{
 Handle menuBar;
 MenuHandle menu;
 
 menuBar = GetNewMBar( kBaseResID );
 
 if ( menuBar == NULL )
 DoError( "\pCouldn't load the MBAR resource..." );
 
 SetMenuBar( menuBar );

 menu = GetMHandle( mApple );
 AddResMenu( menu, 'DRVR' );
 
 DrawMenuBar();
}

CreateWindow
void  CreateWindow( void )
{
 WindowPtrwindow;

 window = GetNewCWindow( kBaseResID, NULL, kMoveToFront );

 GetNewControl( kBaseResID, window );

 SetPort( window );
 
 TextFont( systemFont );
}

SetUpGlobals
void  SetUpGlobals( void )
{
 SetRect( &gSrcRect, 15, 6, 95, 86 );
 SetRect( &gBackRect, 125, 6, 205, 86 );
 SetRect( &gDestRect, 125, 122, 205, 202 );
 SetRect( &gOpColorRect, 15, 122, 95, 202 );
 
 SetRect( &gSrcMenuRect, 7, 90, 103, 108 );
 SetRect( &gBackMenuRect, 117, 90, 213, 108 );
 SetRect( &gModeMenuRect, 117, 206, 213, 224 );
 
 gSrcPattern = iBlackPattern;
 gBackPattern = iBlackPattern;
 
 gCopyMode = srcCopy;
 
 gSrcColor.red = 65535;
 gSrcColor.green = gSrcColor.blue = 0;
 gSrcType = iSingleColor;
 
 gBackColor.blue = 65535;
 gBackColor.red = gBackColor.green = 0;
 gBackType = iSingleColor;
 
 gOpColor.green = 32767;
 gOpColor.red = 32767;
 gOpColor.blue = 32767;
 OpColor( &gOpColor );
 
 gSrcMenu = GetMenu( mColorsPopup );
 InsertMenu( gSrcMenu, kNotNormalMenu );
 
 gBackMenu = GetMenu( mColorsPopup );
 InsertMenu( gBackMenu, kNotNormalMenu );
 
 gModeMenu = GetMenu( mModePopup );
 InsertMenu( gModeMenu, kNotNormalMenu );
}


EventLoop
void  EventLoop( void )
{
 EventRecordevent;
 
 gDone = false;
 while ( gDone == false )
 {
 if ( WaitNextEvent( everyEvent, &event, kSleep, NULL ) )
 DoEvent( &event );
 }
}

DoEvent
void  DoEvent( EventRecord *eventPtr )
{
 char   theChar;
 
 switch( eventPtr->what )
 {
 case mouseDown: 
 HandleMouseDown( eventPtr );
 break;
 case keyDown:
 case autoKey:
 theChar = eventPtr->message & charCodeMask;
 
 if ( (eventPtr->modifiers & cmdKey) != 0 ) 
 HandleMenuChoice( MenuKey( theChar ) );
 break;
 case updateEvt:
 DoUpdate( (WindowPtr)eventPtr->message );
 break;
 }
}

HandleMouseDown
void  HandleMouseDown( EventRecord *eventPtr )
{
 WindowPtrwindow;
 short  thePart;
 long   menuChoice;
 
 thePart = FindWindow( eventPtr->where, &window );
 
 switch ( thePart )
 {
 case inMenuBar:
 menuChoice = MenuSelect( eventPtr->where );
 HandleMenuChoice( menuChoice );
 break;
 case inSysWindow : 
 SystemClick( eventPtr, window );
 break;
 case inContent:
 if ( window != FrontWindow() )
 SelectWindow( window );
 else
 DoContent( window, eventPtr->where );
 break;
 case inDrag : 
 DragWindow( window, eventPtr->where, &qd.screenBits.bounds );
 break;
 }
}

HandleMenuChoice
void  HandleMenuChoice( long menuChoice )
{
 short  menu;
 short  item;
 
 if ( menuChoice != 0 )
 {
 menu = HiWord( menuChoice );
 item = LoWord( menuChoice );
 
 switch ( menu )
 {
 case mApple:
 HandleAppleChoice( item );
 break;
 case mFile:
 HandleFileChoice( item );
 break;
 }
 HiliteMenu( 0 );
 }
}

HandleAppleChoice
void  HandleAppleChoice( short item )
{
 MenuHandle appleMenu;
 Str255 accName;
 short  accNumber;
 
 switch ( item )
 {
 case iAbout:
 SysBeep( 20 );
 break;
 default:
 appleMenu = GetMHandle( mApple );
 GetItem( appleMenu, item, accName );
 accNumber = OpenDeskAcc( accName );
 break;
 }
}

HandleFileChoice
void  HandleFileChoice( short item )
{
 switch ( item )
 {
 case iQuit:
 gDone = true;
 break;
 }
}

DoUpdate
void  DoUpdate( WindowPtr window )
{
 BeginUpdate( window );
 
 DrawContents( window );
 DrawControls( window );
 
 EndUpdate( window );
}

DrawContents
void  DrawContents( WindowPtr window )
{
 RGBColor rgbBlack;
 Rect   source, dest;
 
 rgbBlack.red = rgbBlack.green = rgbBlack.blue = 0;
 
 if ( gSrcPattern == iBlackPattern )
 PenPat( &qd.black );
 else
 PenPat( &qd.gray );
 
 if ( gSrcType == iColorRamp )
 DrawColorRamp( &gSrcRect );
 else if ( gSrcType == iGrayRamp )
 DrawGrayRamp( &gSrcRect );
 else
 {
 RGBForeColor( &gSrcColor );
 PaintRect( &gSrcRect );
 }
 
 if ( gBackPattern == iBlackPattern )
 PenPat( &qd.black );
 else
 PenPat( &qd.gray );
 
 if ( gBackType == iColorRamp )
 DrawColorRamp( &gBackRect );
 else if ( gBackType == iGrayRamp )
 DrawGrayRamp( &gBackRect );
 else
 {
 RGBForeColor( &gBackColor );
 PaintRect( &gBackRect );
 }
 
 PenPat( &qd.black );
 
 RGBForeColor( &gOpColor );
 PaintRect( &gOpColorRect );
 
 RGBForeColor( &rgbBlack );
 DrawLabel( &gSrcMenuRect, "\pSource" );
 DrawLabel( &gBackMenuRect, "\pBackground" );
 DrawLabel( &gModeMenuRect, "\pMode" );
 
 PenSize( 2, 2 );
 FrameRect( &gSrcRect );
 FrameRect( &gBackRect );
 FrameRect( &gDestRect );
 FrameRect( &gOpColorRect );
 
 PenNormal();
 
 source = gBackRect;
 InsetRect( &source, 2, 2 );
 
 dest = gDestRect;
 InsetRect( &dest, 2, 2 );
 
 CopyBits( (BitMap *)&(((CGrafPtr)window)->portPixMap),
   (BitMap *)&(((CGrafPtr)window)->portPixMap),
   &source, &dest, srcCopy, NULL );
 
 source = gSrcRect;
 InsetRect( &source, 2, 2 );
 
 CopyBits( (BitMap *)&(((CGrafPtr)window)->portPixMap),
 (BitMap *)&(((CGrafPtr)window)->portPixMap),
 &source, &dest, gCopyMode, NULL );
}

DrawColorRamp
void  DrawColorRamp( Rect *rPtr )
{
 long   numColors, i;
 HSVColor hsvColor;
 RGBColor rgbColor;
 Rect   r;
 
 r = *rPtr;
 
 InsetRect( &r, 2, 2 );
 numColors = ( rPtr->right - rPtr->left - 2 ) / 2;
 hsvColor.value = hsvColor.saturation = 65535;
 
 for ( i = 0; i < numColors; i++ )
 {
 hsvColor.hue = i * 65535 / numColors;
 HSV2RGB( &hsvColor, &rgbColor );
 RGBForeColor( &rgbColor );
 
 FrameRect( &r );
 InsetRect( &r, 1, 1 );
 }
}

DrawGrayRamp
void  DrawGrayRamp( Rect *rPtr )
{
 long   numColors, i;
 RGBColor rgbColor;
 Rect   r;
 
 r = *rPtr;
 InsetRect( &r, 2, 2 );
 numColors = ( rPtr->right - rPtr->left - 2 ) / 2;
 
 for ( i = 0; i < numColors; i++ )
 {
 rgbColor.red = i * 65535 / numColors;
 rgbColor.green = rgbColor.red;
 rgbColor.blue = rgbColor.red;
 
 RGBForeColor( &rgbColor );
 
 FrameRect( &r );
 InsetRect( &r, 1, 1 );
 }
}

DrawLabel
void  DrawLabel( Rect *boundsPtr, Str255 s )
{
 Rect r;
 int    size;
 
 r = *boundsPtr;
 r.bottom -= 1;
 r.right -= 1;
 FrameRect( &r );
 
 MoveTo( r.left + 1, r.bottom );
 LineTo( r.right, r.bottom );
 LineTo( r.right, r.top + 1 );
 
 size = boundsPtr->right - boundsPtr->left - StringWidth(s);
 MoveTo( boundsPtr->left + size / 2, boundsPtr->bottom - 6);
 
 DrawString( s );
}

DoContent
void  DoContent( WindowPtr window, Point globalPoint )
{
 int    choice;
 ControlHandle control;
 RGBColor rgbColor;
 Point  p;
 
 p = globalPoint;
 GlobalToLocal( &p );
 
 if ( FindControl( p, window, &control ) )
 {
 if ( TrackControl( control, p, NULL ) )
 {
 rgbColor = gOpColor;
 
 if ( PickColor( &rgbColor ) )
 {
 gOpColor = rgbColor;
 
 InvalRect( &gOpColorRect );
 InvalRect( &gDestRect );
 
 OpColor( &gOpColor );
 }
 }
 }
 else if ( PtInRect( p, &gSrcMenuRect ) )
 {
 UpdateSrcMenu();
 
 choice = DoPopup( gSrcMenu, &gSrcMenuRect );
 
 if ( choice > 0 )
 {
 DoSrcChoice( choice );
 
 InvalRect( &gSrcRect );
 InvalRect( &gDestRect );
 }
 }
 else if ( PtInRect( p, &gBackMenuRect ) )
 {
 UpdateBackMenu();
 
 choice = DoPopup( gBackMenu, &gBackMenuRect );
 
 if ( choice > 0 )
 {
 DoBackChoice( choice );
 
 InvalRect( &gBackRect );
 InvalRect( &gDestRect );
 }
 }
 else if ( PtInRect( p, &gModeMenuRect ) )
 {
 UpdateModeMenu();
 
 choice = DoPopup( gModeMenu, &gModeMenuRect );
 
 if ( choice > 0 )
 {
 DoModeChoice( choice );
 
 InvalRect( &gDestRect );
 }
 }
}

UpdateSrcMenu
void  UpdateSrcMenu( void )
{
 int    i;
 
 for ( i = 1; i <= 6; i++ )
 CheckItem( gSrcMenu, i, false );
 
 if ( gSrcPattern == iBlackPattern )
 CheckItem( gSrcMenu, iBlackPattern, true );
 else
 CheckItem( gSrcMenu, iGrayPattern, true );
 
 if ( gSrcType == iColorRamp )
 CheckItem( gSrcMenu, iColorRamp, true );
 else if ( gSrcType == iGrayRamp )
 CheckItem( gSrcMenu, iGrayRamp, true );
 else if ( gSrcType == iSingleColor )
 CheckItem( gSrcMenu, iSingleColor, true );
}

UpdateBackMenu
void  UpdateBackMenu( void )
{
 int    i;
 
 for ( i = 1; i <= 6; i++ )
 CheckItem( gBackMenu, i, false );
 
 if ( gBackPattern == iBlackPattern )
 CheckItem( gBackMenu, iBlackPattern, true );
 else
 CheckItem( gBackMenu, iGrayPattern, true );
 
 if ( gBackType == iColorRamp )
 CheckItem( gBackMenu, iColorRamp, true );
 else if ( gBackType == iGrayRamp )
 CheckItem( gBackMenu, iGrayRamp, true );
 else if ( gBackType == iSingleColor )
 CheckItem( gBackMenu, iSingleColor, true );
}

UpdateModeMenu
void  UpdateModeMenu( void )
{
 int    i;
 
 for ( i = 1; i <= 17; i++ )
 CheckItem( gModeMenu, i, false );
 
 if ( ( gCopyMode >= 0 ) && ( gCopyMode <= 7 ) )
 CheckItem( gModeMenu, gCopyMode + 1, true );
 else
 CheckItem( gModeMenu, gCopyMode - 22, true );
}

DoSrcChoice
void  DoSrcChoice( short item )
{
 RGBColor rgbColor;
 
 switch ( item )
 {
 case iBlackPattern:
 case iGrayPattern:
 gSrcPattern = item;
 break;
 case iColorRamp:
 case iGrayRamp:
 gSrcType = item;
 break;
 case iSingleColor:
 gSrcType = iSingleColor;
 rgbColor = gSrcColor;
 
 if ( PickColor( &rgbColor ) )
 gSrcColor = rgbColor;
 break;
 }
}

DoBackChoice
void  DoBackChoice( short item )
{
 RGBColor rgbColor;
 
 switch ( item )
 {
 case iBlackPattern:
 case iGrayPattern:
 gBackPattern = item;
 break;
 case iColorRamp:
 case iGrayRamp:
 gBackType = item;
 break;
 case iSingleColor:
 gBackType = iSingleColor;
 rgbColor = gBackColor;
 
 if ( PickColor( &rgbColor ) )
 gBackColor = rgbColor;
 break;
 }
}

DoModeChoice
void  DoModeChoice( short item )
{
 if ( ( item >= 1 ) && ( item <= 8 ) )
 gCopyMode = item - 1;
 else
 gCopyMode = item + 22;
}

DoPopup
short DoPopup( MenuHandle menu, Rect *boundsPtr )
{
 Point  corner;
 long theChoice = 0L;
 
 corner.h = boundsPtr->left;
 corner.v = boundsPtr->bottom;
 
 LocalToGlobal( &corner );
 
 InvertRect( boundsPtr );
 
 theChoice = PopUpMenuSelect(menu,corner.v-1,corner.h+1,0);    
 InvertRect( boundsPtr );
 return( LoWord( theChoice ) );
}

PickColor
Boolean PickColor( RGBColor *colorPtr )
{
 Point  where;
 
 where.h = -1;
 where.v = -1;
 
 return( GetColor( where, "\pChoose a color...", colorPtr,
 colorPtr ) );
}

HasColorQD
Boolean HasColorQD( void )
{
 unsigned char version[ 4 ];
 OSErr  err;
 
 err = Gestalt( gestaltQuickdrawVersion, (long *)version );
 
 if ( version[ 2 ] > 0 )
 return( true );
 else
 return( false );
}

DoError
void  DoError( Str255 errorString )
{
 ParamText( errorString, "\p", "\p", "\p" );
 StopAlert( kErrorALRTid, kNullFilterProc );
 ExitToShell();
}

Running ColorTutor

Save your code, and run ColorTutor. The ColorTutor window will appear, as shown in Figure 8.

Figure 8. The ColorTutor WIndow.

The Source and Background menus are identical, as shown in Figure 9. Play with these selections till you get the source and background that you want.

Figure 9. The Source and Background menus.

The real fun comes when you play with the Mode popup (Figure 10). Basically, the mode is passed as the fifth parameter to the CopyBits() call that copies the source rectangles over the destination rectangle which had been previously copied to the lower right corner of the ColorTutor window. Some of the modes take an OpColor, which you can set using the OpColor button.

Figure 10. The Mode popup menu.

Till Next Month

Confused? Experiment! We’ll get into all the hows and whys next month. Till then, read up on the Color Quickdraw transfer modes in THINK Reference and Inside Macintosh.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

OmniGraffle Pro 7.2.2 - Create diagrams,...
OmniGraffle Pro helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use... Read more
OmniGraffle 7.2.2 - Create diagrams, flo...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
Spotify 1.0.44.100. - Stream music, crea...
Spotify is a streaming music service that gives you on-demand access to millions of songs. Whether you like driving rock, silky R&B, or grandiose classical music, Spotify's massive catalogue puts... Read more
Microsoft OneNote 15.29 - Free digital n...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more
WALTR 2 2.0.8 - $39.95
WALTR 2 helps you wirelessly drag-and-drop any music, ringtones, videos, PDF, and ePub files onto your iPhone, iPad, or iPod without iTunes. It is the second major version of Softorino's critically-... Read more
Dropbox 16.3.27 - Cloud backup and synch...
Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more
EtreCheck 3.1.5 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Carbon Copy Cloner 4.1.12 - Easy-to-use...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
VueScan 9.5.62 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
SpamSieve 2.9.27 - Robust spam filter fo...
SpamSieve is a robust spam filter for major email clients that uses powerful Bayesian spam filtering. SpamSieve understands what your spam looks like in order to block it all, but also learns what... Read more

Latest Forum Discussions

See All

Track Santa with these three festive app...
Christmas is fast approaching and that means it's time to prepare for Santa's yearly pilgrimage around the globe. Christmas Eve is an exciting time as parents help their kids get ready to welcome Santa. You've got the cookies and milk all planned... | Read more »
Galaxy on Fire 3 and four other fantasti...
Galaxy on Fire 3 - Manticore brings the series back for another round of daring space battles. It's familiar territory for folks who are familiar with the franchise. If you've beaten the game and are looking to broaden your horizons, might we... | Read more »
The best apps for your holiday gift exch...
What's that, you say? You still haven't started your holiday shopping? Don't beat yourself up over it -- a lot of people have been putting it off, too. It's become easier and easier to procrastinate gift shopping thanks to a number of apps that... | Read more »
Toca Hair Salon 3 (Education)
Toca Hair Salon 3 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Winter comes to Darkwood as Seekers Note...
MyTona, based in the chilly Siberian city of Yakutsk, has brought a little festive fun to its hidden object game Seekers Notes: Hidden Mystery. The Christmas update introduces some new inhabitants to players, and with them a chance to win plenty of... | Read more »
Bully: Anniversary Edition (Games)
Bully: Anniversary Edition 1.03.1 Device: iOS Universal Category: Games Price: $6.99, Version: 1.03.1 (iTunes) Description: *** PLEASE NOTE: This game is officially supported on the following devices: iPhone 5 and newer, iPod Touch... | Read more »
PINE GROVE (Games)
PINE GROVE 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: A pine grove where there are no footsteps of people due to continuous missing cases. The case is still unsolved and nothing has... | Read more »
Niantic teases new Pokémon announcement...
After rumors started swirling yesterday, it turns out there is an official Pokémon GO update on its way. We’ll find out what’s in store for us and our growing Pokémon collections tomorrow during the Starbucks event, but Niantic will be revealing... | Read more »
3 reasons why Nicki Minaj: The Empire is...
Nicki Minaj is as business-savvy as she is musically talented and she’s proved that by launching her own game. Designed by Glu, purveyors of other fine celebrity games like cult favorite Kim Kardashian: Hollywood, Nicki Minaj: The Empire launched... | Read more »
Clash of Clans is getting its own animat...
Riding on its unending wave of fame and success, Clash of Clans is getting an animated web series based on its Clash-A-Rama animated shorts.As opposed to the current shorts' 60 second run time, the new and improved Clash-A-Rama will be comprised of... | Read more »

Price Scanner via MacPrices.net

New 2016 13-inch Touch Bar MacBook Pros on sa...
B&H Photo the new 2016 Apple 13″ 2.9GHz/256GB Touch Bar MacBook Pros on sale for $50 off MSRP, each including free shipping plus NY sales tax only: - 13″ 2.9GHz/256GB Touch Bar MacBook Pro Space... Read more
12-inch 1.2GHz Space Gray Retina MacBook on s...
B&H Photo has dropped their price on the 2016 Apple 12″ 1.2GHz Space Gray Retina MacBook (MLH82LL/A) to $1399 including free shipping plus NY sales tax only. Their price is $200 off MSRP, and it’... Read more
Never Settle for Low Performing Wifi With iOS...
AppYogi Software has announced the release of WiFi Signal Strength Status App 1.0, the company’s new utility developed exclusively for macOS. WiFi Signal Strength Status App features a unique, single... Read more
New 2016 13-inch Touch Bar MacBook Pros in st...
B&H Photo has stock of new 2016 Apple 13″ Touch Bar MacBook Pro models, each including free shipping plus NY sales tax only: - 13″ 2.9GHz/512GB Touch Bar MacBook Pro Space Gray: $1999 - 13″ 2.... Read more
New 2016 15″ Touch Bar MacBook Pros in stock...
B&H Photo has new 2016 Apple 15″ Touch Bar MacBook Pro models in stock today including free shipping plus NY sales tax only: - 15″ 2.7GHz Touch Bar MacBook Pro Space Gray: $2799 - 15″ 2.7GHz... Read more
DietSensor App Targeting Diabetes and Obesity...
DietSensor, Inc., a developer of smart food and nutrition applications designed to fight diabetes and obesity and help improve overall fitness, has announced the launch of its DietSensor app for... Read more
Holiday 2016 13-inch 2.0GHz MacBook Pro sales...
B&H has the non-Touch Bar 13″ MacBook Pros in stock today for $50-$100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.0GHz MacBook Pro Space Gray (MLL42LL/A): $1449 $... Read more
Holiday sale: Apple TVs for $51-$40 off MSRP,...
Best Buy has dropped their price on the 64GB Apple TV to $159.99 including free shipping. That’s $40 off MSRP. 32GB Apple TVs are on sale right now for $98 on Sams Club’s online store. That’s $51 off... Read more
12-inch Retina MacBooks, Apple refurbished, n...
Apple has restocked a full line of Certified Refurbished 2016 12″ Retina MacBooks, now available for $200-$260 off MSRP. Refurbished 2015 models are available starting at $929. Apple will include a... Read more
Holiday sale: 12-inch Retina MacBook for $100...
B&H has 12″ Retina MacBooks on sale for $100 off MSRP as part of their Holiday sale. Shipping is free, and B&H charges NY sales tax only: - 12″ 1.1GHz Space Gray Retina MacBook: $1199 $100... Read more

Jobs Board

Integration Technician, *Apple* - Zones, In...
…at Zones and for our customers each day. Position Overview The Apple Integration Technician will be responsible for performing customer specific configuration Read more
*Apple* Brand Ambassador (Macy's) - The...
…(T-ROC), is proud of its unprecedented relationship with our partner and client, APPLE ,in bringing amazing" APPLE ADVOCATES"to "non" Apple store locations. Read more
*Apple* Retail - Multiple Positions- Trumbul...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
US- *Apple* Store Leader Program - Apple (Un...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.