TweetFollow Us on Twitter

AppleGuide with PowerPlant

Volume Number: 13 (1997)
Issue Number: 10
Column Tag: Electronic Documentation

Using Apple Guide with PowerPlant and MacApp

by Marcelo Lombardi

About the Apple Guide Framework

The provided Apple Guide framework can be used to minimize the code-writing effort required to incorporate Apple Guide into MacApp or PowerPlant applications. It includes support for coaching views, panes, and default context-checking classes for both frameworks. Two examples are provided. This article, was divided into four main sections: (1) Understanding the framework: explains the components of the Apple Guide Framework; (2) Using the framework: provides an overview of the sample applications that are available on-line; (3) PowerPlant example: shows how to use the framework to incorporate Apple Guide in PowerPlant applications; (4) MacApp example: shows how to use the framework to incorporate Apple Guide in MacApp applications; (5) Creating a guide file: provides very simple introduction to writing guide files. This article assumes a basic knowledge of PowerPlant and/or MacApp.

Requirements

CodeWarrior 9 or higher, and either MacApp 3.3 or PowerPlant.

Understanding the Framework

The framework is composed of three sets of classes (see Figure 1). First, the Apple Guide classes implement the required toolbox initialization calls, determine the availability of Apple Guide, manage coach and context replies, open and close the help window, and terminate the Apple Guide session. Secondly, the utility classes are very simple classes that implement common programming tasks. In this area CA5World gets the current A5 and restores the global A5. CHandleLock, locks and restates the state of a handle. COSType is a class implementation of the OSType data type, and converts char*'s to OSTypes and viceversa. CProcess obtains information about the current process. Finally, if you are using PowerPlant, CBroadcasterWindow broadcasts a message to tell its listener when it becomes active or inactive; TBroadcasterWindowMA accomplishes the same function using MacApp's dependency mechanism.

In this section, a brief overview of the AppleGuide, and the MacApp/PowerPlant subclasses will be provided.

Figure 1. Apple Guide Framework Class Tree.

Your application will only create one CAppleGuide object. To create it, you must initialize it by calling Initialize with the name of the Apple Guide file and the four-byte identifier of the context handler. Initialize calls InstallContextHandler and InstallCoachHandler which installs the context-checking and coach handling procedures respectively. InstallContextHandler calls AGInstallContextHandler passing a reference to the CAppleGuide object. InstallCoachHandler calls AGInstallCoachHandler passing a reference to the CAppleGuide object. Now, when the static proc pointers ReplyToContext or ReplyToCoach are called, they can use the reference to the CAppleGuide to call DoReplyToContext or DoReplyToCoach. This is done for two reasons: First, you need to be able to dispatch the call to the current reply object associated with the frontmost document. Secondly, it provide a means for mimicking a "virtual proc pointer", should the need for overriding CAppleGuide ever arise. Finally, SetCoachHandler and SetContextHandler install the appropriate coach-handling and context-handling objects depending on which window is in front. Here is how this works:

//
//   Replying mechanism from CAppleGuide.cp
//

// ReplyToCoach dispatches the call to the virtual member
// DoReplyToCoach
pascal OSErr
CAppleGuide::ReplyToCoach(Rect* pItemRect, Ptr pName, long refCon)
{
  OSErr    result    =  kAGErrItemNotFound;     
  CA5World     anA5World; 
  CAppleGuide*   anAppleGuide  =  (CAppleGuide*) refCon;
  if(anAppleGuide)
  {
    if(anAppleGuide->DoReplyToCoach(pName, pItemRect))
      result = noErr;
  } 
  return(result);  
}

// DoReplyToCoach lets the appropriate fCoachHandler ( perhaps the one assoicated with 
// the frontmost document ) handle the reply
Boolean CAppleGuide::DoReplyToCoach( Ptr inName, Rect* ioItemRect)
{
  if(fCoachHandler)
    return fCoachHandler->DoReplyToCoach( inName, ioItemRect);
  return false;
}

//
//   Header file CAppleGuide.h
//
class CAppleGuide
{
public:
  
  /
  // construction/destruction
  CAppleGuide();
  virtual ~CAppleGuide();
  void Initialize( Str63& inName, OSType inContextID);
  
  // API
  virtual void OpenGuide();  
  virtual Boolean IsFrontProcess();  
  void SetCoachHandler(CCoachHandler * inCoachHandler);  
  void SetContextHandler(CContextHandler * inContextHandler);
  
  // Accessor (can we run apple Guide ? )
  Boolean CanRun(); 
  
protected:

  virtual void   GetProcessInfo();
  virtual OSErr   InstallContextHandler();
  virtual OSErr   InstallCoachHandler();
  static pascal   OSErr ReplyToContext(  Ptr pInput, 
                  Size inputDataSize,
                  Ptr *ppOutput, 
                  Size *pOutputDataSize,
                  AGAppInfoHdl hAppInfo );
  static pascal   OSErr ReplyToCoach(    Rect* pItemRect, 
                  Ptr pName, 
                  long  refCon );
  
  // You can override DoReplyToContext and/or DoReplyToCoach but 
  // it is better if you subclass CCoachHandler and/or   
  // CContextHandler

  virtual Boolean DoReplyToContext(  const AEEventID&   inEventID, 
                const OSType&    inID);
  virtual Boolean DoReplyToCoach(   Ptr inName, 
                Rect* ioItemRect);
    
private:
Boolean   fCanRun;        
ProcessSerialNumber  fProcessNumber;
FSSpec  fGuideSpec;       
AGRefNum  fAGRefNum;   
AGRefNum  fAGCoachRefNum;    
AGRefNum  fAGContextRefNum;    
OSType  fContextID;      
CCoachHandler *  fCoachHandler;
CContextHandler *  fContextHandler;
CProcess  fProcess;
  
};

Now is time to look at the Coach reply objects. CCoachHandler is the base-class and it is used to coach any item for which you can pass their rectangle and their identifier. CCoachHandlerMacApp can be used to coach any MacApp object that is a subclass of TView. CCoachHandlerPPlant can be used to coach any PowerPlant object that is a subclass of LPane.

Coach handlers don't require any initialization steps. All you need to do is call the overloaded method InsertObject for every object that you want to coach. DoReplyToCoach will handle the coaching reply. Notice that the insertion of panes and views is defined in the subclasses CCoachHandlerPPlant and CCoachHandlerMacApp. Likewise, the subclasses override DoReplyToCoach to implement the appropriate reply. Also notice that InsertObject can be called with a pane, a view, or a pair<Rect, OSType>. The items are inserted in STL lists and removed at destruction time. It is also important to know that when you insert TView objects and LPane objects the conversion of coordinates is handled automatically. If you need to insert a pair<Rect, OSType>, you need to handle coordiante conversion yourself.

Here is the header file for CCoachHandler:

class CCoachHandler
{
public:
  // Construction/destruction
  CCoachHandler();
  virtual ~CCoachHandler();
  virtual Boolean DoReplyToCoach( Ptr inName, Rect* ioItemRect);
  
  // API
  #ifdef __PowerPlant__
  virtual void InsertObject(const LPane* inPane){ }
  #endif
  #ifdef qMacApp
  virtual void InsertObject(const TView* inView){ } 
  #endif
  virtual void InsertObject(const pair<Rect, OSType> & inItem);
protected:
private:
  list < pair<Rect, OSType>(inItem) > fItems; 
};

Context handlers work similarly to coach handlers. Unlike coach handlers, however, they do not require the insertion of any visual objects. Context handlers receive events and respond to those events. For example, you may want to know if the application is the front process, or if a window is in front, or if a previous step was performed before attempting to coach an item. In this "minimalist" type of framework only front-window checking for both PowerPlant and MacApp is provided. Here are the context-checking classes.

// CContextHandlerPPlant, in CContextHandler.h, abstract superclass
class CContextHandler
{
public:
  // Construction/destruction
  CContextHandler();
  virtual ~CContextHandler();
  //  Must override
   virtual Boolean DoReplyToContext( const AEEventID&   inEventID, 
              const unsigned long& inID,                 CAppleGuide*  inAppleGuide)=0;
  static enum OSType { kIsFrontWindow = 'isft'};
};

// CContextHandlerPPlant, in CContextHandler.h
class CContextHandlerPPlant: public CContextHandler
{
public:
  //
  // Construction/destruction
  //
  CContextHandlerPPlant();
  virtual ~CContextHandlerPPlant();
  // override to expand capabilities beyond front-window checking
  virtual Boolean DoReplyToContext(   const AEEventID&   inEventID, 
                const unsigned long& inID,                 CAppleGuide*  inAppleGuide);
};
// CContextHandlerMacApp, in CContextHandler.h
class CContextHandlerMacApp: public CContextHandler
{
public:
  // Construction/destruction
  CContextHandlerMacApp();
  virtual ~CContextHandlerMacApp();
  // override to expand capabilities beyond front-window checking
  virtual Boolean DoReplyToContext(   const AEEventID&   inEventID, 
                const unsigned long& inID,                 CAppleGuide*  inAppleGuide);
};

CContextHandler is an abstract superclass that supplies the basic interface in DoReplyToContext interface and it is implemented in CContextHandlerMacApp and CContextHandlerPPlant using the MacApp and PowerPlant APIs. You can use the code as an example of handling context checking so that you can create your own code.

Using the Framework

This section shows an example of how to use the framework with MacApp and PowerPlant.

Figure 2 shows the example application. Full source code is available on-line for MacApp and PowerPlant.

Figure 2. Apple Guide Example application.

This example shows four different coaches: a coach for the format box, a coach for the color popup menu, a coach for the quantity field, and a coach for the Beep menu item. The behavior of this application is minimal as it attempts to minimize the amount of code used and make it easier to find the Apple Guide-specific code.

First of all, lets try the application. Launch either example application, and open the guide file by either clicking on the help icon, or selecting Open Guide from the Example menu. In Sample Guide windoid, select the Coaching Examples topic and click the OK button. Follow the directions and you will see each view/pane being coached. Notice that if the AppleGuideExample application is not in front, or its window is not open, you will get a message that reads: "Please make sure that your application's window is the front window before using this guide." This is accomplished by using context checking. You should now be in good shape to see how the Apple Guide code is integrated in a PowerPlant and a MacApp application. MacApp programmers who are not interested in PowerPlant feel free to skip this section and jump directly into the MacApp example.

Powerplant Example

The StartUp method of the application object creates an initialized instance of the CAppleGuide object. For convenience, fAppleGuide is a static variable of the document object. CAppleGuide expects the guide file to be called SampleGuide and to be in the same directory as the application file. If anything goes wrong (can't find the file, Apple Guide is not available, etc), an exception will be thrown, and the program will simply beep.

void
CPPExampleApplication::StartUp()
{
  // create and initialize guide
  CPPExampleDocument::fAppleGuide = new CAppleGuide; 
  try
  {
   if(CPPExampleDocument::fAppleGuide)
CPPExampleDocument::fAppleGuide>Initialize("\pSampleGuide",'AGCT');
  }
  catch(CAppleGuideEx ex)
  {
    ::SysBeep(1);
  }
  catch(CProcessEx ex)
  {
    ::SysBeep(1);
  }
  ObeyCommand(cmd_New, nil); // create a new window
}

At destruction time, CPPExampleDocument::fAppleGuide is deleted, the Apple Guide session is terminated, and the guide is closed.

CPPExampleApplication::~CPPExampleApplication()
{
  if(CPPExampleDocument::fAppleGuide)
    delete CPPExampleDocument::fAppleGuide;
} 

Let's now take a look at the constructor of the document object. Only three parts are Apple Guide specific and they have been commented appropriately. First notice the creation of fCoachHandler and fContextHandler. Secondly, the call to ((CBroadcasterWindow*)mWindow)->AddListener(this ); is used to tell the document when the window becomes active or inactive. That way, when the widow becomes active, we can set their fCoachHandler and fContextHandler data members as the current handlers of the static object CAppleGuide. Finally, a reference to the format, quantity, and color panes is inserted into the coach-handler object. The references are used to return the appropriate coordinates to Apple Guide, when the user selects a specific topic.

CPPExampleDocument::CPPExampleDocument(   LCommander *inSuper, 
                FSSpec *inFileSpec ):                 LSingleDoc( inSuper ),fDirty(0)
{

Try_ {    
  mWindow     = LWindow::CreateWindow( 1000, this );  
  fCoachHandler = nil;
  fContextHandler = nil;
  
  //
  // Create coach and context handlers
  //
  fCoachHandler = new CCoachHandlerPPlant;
  fContextHandler = new CContextHandlerPPlant;  
  ThrowIfNil_(mWindow);
  ThrowIfNil_(fCoachHandler);
  ThrowIfNil_(fContextHandler);
    
  StColorPenState state;
  PenNormal();
  RGBColor color = {0, 0, 0};
  PenState aState;
  GetPenState(&aState);
  LPaintAttachment* blackAttachment = new   LPaintAttachment(&aState,&color, &color, nil);
  LPane* line = mWindow->FindPaneByID('line');
  ThrowIfNil_(blackAttachment);
  ThrowIfNil_(line);  
  line->AddAttachment(blackAttachment);
  LButton* help = (LButton*)mWindow->FindPaneByID('guid');
  ThrowIfNil_(help);
  help->AddListener(this );
  
  //
  // The document needs to know when the window becomes
  // active or inactive.
  //  
  ((CBroadcasterWindow*)mWindow)->AddListener(this );
    
  LPane* format = mWindow->FindPaneByID('FRMT');
  LPane* clr = mWindow->FindPaneByID('COLR');
  LPane* qtty = mWindow->FindPaneByID('QTTY');
  LStdRadioButton * radio1 =
      (LStdRadioButton *)mWindow>FindPaneByID((OSType)1);
  LStdRadioButton * radio2 = 
      (LStdRadioButton *)mWindow->FindPaneByID((OSType)1);
  LStdRadioButton * radio3 =
      (LStdRadioButton *)mWindow->FindPaneByID((OSType)1);
  ThrowIfNil_(format);
  ThrowIfNil_(clr);
  ThrowIfNil_(qtty);
  ThrowIfNil_(radio1);
  ThrowIfNil_(radio2);
  ThrowIfNil_(radio3);
  fRadio1 = radio1;
  fRadio2 = radio2;
  fRadio3 = radio3;
  fQuantity = (LEditField*)qtty;  
  fColor = (LStdPopupMenu*)clr;
  //
  // We need to insert the format, color, and quanty panes 
  // in this document's coach handler. The Beep menu item is
  // handled automatically by AppleGuide.
  //
  if(fCoachHandler)
  {
    fCoachHandler->InsertObject(format);
    fCoachHandler->InsertObject(clr);
    fCoachHandler->InsertObject(qtty);
  }
}Catch_( inErr ) 
{
    SysBeep(1);
    return;
} EndCatch_
  
if ( inFileSpec == nil ) {
    this->NameNewDoc();
    
} else {
  
  this->OpenFile( *inFileSpec );
}
  
mWindow->Show();  
}

Now lets see what happens when the window becomes active.

void       
CPPExampleDocument::ListenToMessage (MessageT inMessage, void *ioParam)
{
  #pragma unused(ioParam)
  
  switch( inMessage )
  {
    case cmd_OpenGuide:
    {
      this->OpenGuide();
      return;
    }
    case cmd_Beep:
    {
      SysBeep(1);
      return;
    }    
    case CBroadcasterWindow::activate_ID :
    {
      if( fAppleGuide )
      {
        fAppleGuide->SetCoachHandler(fCoachHandler);
        fAppleGuide->SetContextHandler(fContextHandler);
      }
      return;
    }
    case CBroadcasterWindow::deactivate_ID:
    {
      if( fAppleGuide )
      {
        fAppleGuide->SetCoachHandler(nil);
        fAppleGuide->SetContextHandler(nil);
      }
      return;
    }
  
  }

}

The code is very simple. If the window becomes inactive, the handlers should be nil. If the window becomes active, the document's handler should be the one replying to a coach or context check message. Finally, the call to OpenGuide is very simple and it is invoked when the user selects a the Open Guide menu item, or clicks on the help icon.

void CPPExampleDocument::OpenGuide()
{  
  try
  {             
    if(fAppleGuide)
      fAppleGuide->OpenGuide();
  }
  catch(CAppleGuideEx ex)
  {
    SysBeep(1);
  }
}

MacApp Example

Hello, MacApp adventurers! The code was developed in MacApp 3.3, and it can be converted to newer and older versions of MacApp with relative ease. If you looked at the PowerPlant example (and PowerPlant is an easy game for MacApp adventurers), you will notice a lot of similarities in the code. In any case, we will go through the MacApp code without assuming you that you read the PowerPlant section.

The IApplicationMAExamplemethod of the application object creates an initialized instance of the CAppleGuide object. For convenience, fAppleGuide is a static variable of the document object. CAppleGuide expects the guide file to be called SampleGuide and to be in the same directory as the application file. If anything goes wrong (can't find the file, Apple Guide is not available, etc), an exception will be thrown, and the program will simply beep.

void TApplicationMAExample::IApplicationMAExample()
{
  
this->IApplication(kFileType,kSignature);

// create and initialize guide 
TDocumentMAExample::fAppleGuide = new CAppleGuide;
  
try
  {
  if(TDocumentMAExample::fAppleGuide)
    TDocumentMAExample::fAppleGuide->Initialize( "\pSampleGuide",'AGCT');
  }
  catch(CAppleGuideEx ex)
  {
    ::SysBeep(1);
    return;
  }
  catch(CProcessEx ex)
  {
    ::SysBeep(1);
    return;
  }
} 

At destruction time, TDocumentMAExample::fAppleGuide is deleted, the Apple Guide session is terminated, and the guide is closed.

TApplicationMAExample::~TApplicationMAExample()
{
  if(TDocumentMAExample::fAppleGuide)
    delete TDocumentMAExample::fAppleGuide;
} 

Let's now take a look at DoMakeViews in the document object. Only three parts are Apple Guide-specific, and they have been commented appropriately. First notice the creation of fCoachHandler and fContextHandler. They are not static because each document has its own pair of handlers. Secondly, the call to aWindow->AddDependent(this); is used to tell the document when the window becomes active or inactive (TBroadcasterWindowMA has this capability). That way, when the widow becomes active, we can set their fCoachHandler and fContextHandler data members as the current handlers of the static object CAppleGuide. Finally, a reference to the format, quantity, and color views is inserted into the coach-handler object. The references are used to return the appropriate coordinates to Apple Guide, when the user selects a specific topic.

void TDocumentMAExample::DoMakeViews(Boolean /*forPrinting*/) //Override 
{
  TWindow* aWindow = nil;
  TStdPrintHandler* aHandler = nil;
  TView* aView   = nil;
  TPicture * aGuidePict = nil;
  aWindow = gViewServer->NewTemplateWindow(kMAExampleWindowID,     this);  
 FailNIL(aWindow );
  aView = aWindow->FindSubView('AGEX');  
  //
  // Become a dependent of TBroadcasterWindowMA so we are notified
  // when the window becomes active or inactive
   //
  aWindow->AddDependent(this); 
  
  //
  // Find objects to be coached
  //
  TView* format   = aWindow->FindSubView('FRMT');
  TView* color     = aWindow->FindSubView('COLR');
  TView* quantity   = aWindow->FindSubView('QTTY');
  FailNIL(format);
  FailNIL(color);
  FailNIL(quantity);
  fColor      = (TPopup*)color;
  fFormat      = (TCluster*)format;
  fQuantity    = (TNumberText*)quantity;  
  fColor->SetCurrentItem(fColorVal, kRedraw);
  fFormat->SetCurrentChoice(fFormatVal);
  fQuantity->SetValue(fQuantityVal, kRedraw);
    
  //
  // Install context handler, coach handler, and objects to be coached
  // ( menus are handled automatically and do not need to be inserted )
  //
  fContextHandler = new CContextHandlerMacApp;
  fCoachHandler = new CCoachHandlerMacApp;
  fCoachHandler->InsertObject(format);
  fCoachHandler->InsertObject(color);
  fCoachHandler->InsertObject(quantity);
    
} 

Now lets see what happens when the window becomes active.

void TDocumentMAExample::DoUpdate(ChangeID theChange,
               TObject* changedObject,
               TObject* changedBy,
               TDependencySpace* dependencySpace )
{
  
  TBroadcasterWindowMA * window =   MA_DYNAMIC_CAST(TBroadcasterWindowMA, changedBy);
  TPicture * picture = MA_DYNAMIC_CAST(TPicture, changedBy);
  if(!window && !picture)
  {
    Inherited::DoUpdate(theChange, 
          changedObject, changedBy, dependencySpace );
    return;
  }
  switch(theChange) 
  {
    case TBroadcasterWindowMA::kActivate:
    {
      fAppleGuide->SetCoachHandler( fCoachHandler );
      fAppleGuide->SetContextHandler(fContextHandler );
      break;
    }
    case TBroadcasterWindowMA::kDeactivate:
    {
      fAppleGuide->SetCoachHandler( nil );
      fAppleGuide->SetContextHandler (nil );
      break;
    }
    
    default:
      Inherited::DoUpdate(theChange, 
        changedObject, changedBy, dependencySpace );
  }
}

The code is very simple. If the window becomes inactive, the handlers should be nil. If the window becomes active, the document's handlers should be the ones replying to a coach or context check message. Finally, the call to OpenGuide is also simple and it is invoked when the user selects a the Open Guide menu item, or clicks on the help icon. If you compare the MacApp and the PowerPlant code, you will see that the MacApp example posts a command that invokes OpenGuide from its DoIt method, whereas the PowerPlant example handles this directly.

void TDocumentMAExample::OpenGuide()
{  
  try
  {             
    if(fAppleGuide)
      fAppleGuide->OpenGuide();
  }
  catch(CAppleGuideEx ex)
  {
    SysBeep(1);
  }
}

Creating A Guide File

As you can see, the framework is simple and very easy to use. The objective of this article is not to teach how to write an AppleGuide script, but to show you how to incorporate AppleGuide into MacApp and PowerPlant applications. This section, therefore, shows how the script "fits" with the code.

First, let's look at the coach marks section. 'AGEX' is the identifier of the application. "FRMT" , "COLR" , and "QTTY" are the identifiers of the panes/views being coached. They are received as a char* 's and the the guide uses the class COSType to convert them into an OSType. Notice that this class uses bit-shifting operators and if you build a 68K project you will need to use 4 bytes integers in your project settings for it to work. Also notice that Apple Guide handles menus automatically, you just need to supply the menu name and the item name.

# --- Coch Marks ------------------------------------------------------

# Define standard coaches for use with .
<Define Menu Coach> "Coach Beep Menu", 'AGEX', REDCIRCLE, "Example", "Beep", RED, UNDERLINE
<Define Object Coach> "Coach Format", 'AGEX', REDCIRCLE, "FRMT"
<Define Object Coach> "Coach Color", 'AGEX', REDCIRCLE, "COLR"
<Define Object Coach> "Coach Quantity", 'AGEX', REDCIRCLE, "QTTY"

Now look at the context checking function IsFrontWindow. 'AGCT' is the context-check identifier that we used to in the call to fAppleGuide->Initialize( "\pSample Guide", 'AGCT'); Also notice that the framework uses OSType identifiers for event id recognition in context-checking. When IsFrontWindow is called in the script, a context check event is sent to the application, which responds accordingly.

<Define Context Check> "IsFrontWindow", 'AGCT', 'AGEX', OSTYPE:'isft'

Additional context-checking can be added by creating your own subclass CContextHandler.

Last Word

This article tries to be as concise as possible. Get the code and see how it can help you in your own development. Play with it, and make your own improvements. The "Apple Guide" classes (see figure 1) contain the most relevant code. It should be fairly straight forward to incorporate Apple Guide help in you PowerPlant and MacApp applications. Have Fun!

Bibliography and References

  • Apple Computer, Inc. "AppleGuide Complete". Addison Wesley Publishing Company, 1996.
  • Apple Computer, Inc. "Programmer's Guide To MacApp". Developer Press, 1996.
  • Metrowerks, Inc. "CodeWarrior® PowerPlant Book". Developer Press, 1996.

Marcelo Lombardi is a developmant consultant at Software Concepts, Inc. Marcelo welcomes coments at his internet address: marcelo@software-concepts.com. You can also check out his WWW home page at http://www.software-concepts.com.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Duplicate Annihilator 5.7.7 - Find and d...
Duplicate Annihilator takes on the time-consuming task of comparing the images in your iPhoto library using effective algorithms to make sure that no duplicate escapes. Duplicate Annihilator... Read more
OS X Server 4.1.3 - For OS X 10.10 Yosem...
Designed for OS X and iOS devices, OS X Server makes it easy to share files, schedule meetings, synchronize contacts, develop software, host your own website, publish wikis, configure Mac, iPhone,... Read more
pwSafe 4.1 - Secure password management...
pwSafe provides simple and secure password management across devices and computers. pwSafe uses iCloud to keep your password databases backed-up and synced between Macs and iOS devices. It is... Read more
Kodi 15.0.rc1 - Powerful media center to...
Kodi (was XBMC) is an award-winning free and open-source (GPL) software media player and entertainment hub that can be installed on Linux, OS X, Windows, iOS, and Android, featuring a 10-foot user... Read more
Coda 2.5.11 - One-window Web development...
Coda is a powerful Web editor that puts everything in one place. An editor. Terminal. CSS. Files. With Coda 2, we went beyond expectations. With loads of new, much-requested features, a few surprises... Read more
Bookends 12.5.7 - Reference management a...
Bookends is a full-featured bibliography/reference and information-management system for students and professionals. Access the power of Bookends directly from Mellel, Nisus Writer Pro, or MS Word (... Read more
Maya 2016 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
RapidWeaver 6.2.3 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
MacFamilyTree 7.5.2 - Create and explore...
MacFamilyTree gives genealogy a facelift: it's modern, interactive, incredibly fast, and easy to use. We're convinced that generations of chroniclers would have loved to trade in their genealogy... Read more
Paragraphs 1.0.1 - Writing tool just for...
Paragraphs is an app just for writers. It was built for one thing and one thing only: writing. It gives you everything you need to create brilliant prose and does away with the rest. Everything in... Read more

Rage of Bahamut is Giving Almost All of...
The App Store isn't what it used to be back in 2012, so it's not unexpected to see some games changing their structures with the times. Now we can add Rage of Bahamut to that list with the recent announcement that the game is severely cutting back... | Read more »
Adventures of Pip (Games)
Adventures of Pip 1.0 Device: iOS iPhone Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: ** ONE WEEK ONLY — 66% OFF! *** “Adventures of Pip is a delightful little platformer full of charm, challenge and impeccable... | Read more »
Divide By Sheep - Tips, Tricks, and Stre...
Who would have thought splitting up sheep could be so involved? Anyone who’s played Divide by Sheep, that’s who! While we’re not about to give you complete solutions to everything (because that’s just cheating), we will happily give you some... | Read more »
NaturalMotion and Zynga Have Started Tea...
An official sequel to 2012's CSR Racing is officially on the way, with Zynga and NaturalMotion releasing a short teaser trailer to get everyone excited. Well, as excited as one can get from a trailer with no gameplay footage, anyway. [Read more] | Read more »
Grab a Friend and Pick up Overkill 3, Be...
Overkill 3 is a pretty enjoyable third-person shooter that was sort of begging for some online multiplayer. Fortunately the begging can stop, because its newest update has added an online co-op mode. [Read more] | Read more »
Scanner Pro's Newest Update Adds Au...
Scanner Pro is one of the most popular document scanning apps on iOS, thanks in no small part to its near-constant updates, I'm sure. Now we're up to update number six, and it adds some pretty handy new features. [Read more] | Read more »
Heroki (Games)
Heroki 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: CLEAR THE SKIES FOR A NEW HERO!The peaceful sky village of Levantia is in danger! The dastardly Dr. N. Forchin and his accomplice,... | Read more »
Wars of the Roses (Games)
Wars of the Roses 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: | Read more »
TapMon Battle (Games)
TapMon Battle 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: It's time to battle!Tap! Tap! Tap! Try tap a egg to hatch a Tapmon!Do a battle with another tapmons using your hatched tapmons! *... | Read more »
Alchemic Dungeons (Games)
Alchemic Dungeons 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: ### Release Event! ### 2.99$->0.99$ for limited time! ### Roguelike Role Playing Game! ### Alchemic Dungeons is roguelike... | Read more »

Price Scanner via MacPrices.net

Seagate Backup Plus Drives Feature 200GB of C...
Seagate Technology plc has announced that its Backup Plus family of external storage offerings will now include 200GB of OneDrive cloud storage, a major added value, and the addition of Lyve’s photo... Read more
Canon PIXMA MG3620 Wireless Inkjet All-in-One...
Canon U.S.A., Inc. has announced the PIXMA MG3620 Wireless (1) Inkjet All-in-One (AIO) printer for high-quality photo and document printing. Built with convenience in mind for the everyday home user... Read more
July 4th Holiday Weekend 13-inch MacBook Pro...
Save up to $150 on the purchase of a new 2015 13″ Retina MacBook Pro at the following resellers this weekend. Shipping is free with each model: 2.7GHz/128GB MSRP $1299 2.7GHz/... Read more
27-inch 3.5GHz 5K iMac on sale for $2149, sav...
Best Buy has the 27″ 3.5GHz 5K iMac on sale for $2149.99. Choose free shipping or free local store pickup (if available). Sale price for online orders only, in-store prices may vary. Their price is $... Read more
Apple now offering refurbished 2015 11-inch...
The Apple Store is now offering Apple Certified Refurbished 2015 11″ MacBook Airs as well as 13″ MacBook Airs (the latest models), available for up to $180 off the cost of new models. An Apple one-... Read more
15-inch 2.5GHz Retina MacBook Pro on sale for...
Amazon.com has the 15″ 2.5GHz Retina MacBook Pro on sale for $2274 including free shipping. Their price is $225 off MSRP, and it’s the lowest price available for this model. Read more
Finally Safe To Upgrade To Yosemite’?
The reason I’ve held back from upgrading my MacBook Air from OS X 10.9 Mavericks to 10.10 Yosemite for nearly a year isn’t just procrastination. Among other bugs reported, there have been persistent... Read more
Logo Pop Free Vector Logo Design App For OS X...
128bit Technologies has released of Logo Pop Free 1.2 for Mac OS X, a vector based, full-fledged, logo design app available exclusively on the Mac App Store for the agreeable price of absolutely free... Read more
21-inch 1.4GHz iMac on sale for $999, save $1...
B&H Photo has new 21″ 1.4GHz iMac on sale for $999 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Best Buy has the 21″ 1.4GHz iMac on sale for $999.99 on their... Read more
16GB iPad mini 3 on sale for $339, save $60
B&H Photo has the 16GB iPad mini 3 WiFi on sale for $339 including free shipping plus NY tax only. Their price is $60 off MSRP. Read more

Jobs Board

Frameworks Engineer, *Apple* Watch - Apple...
**Job Summary** Join the team that is shaping the future of software development for Apple Watch! As a software engineer on the Apple Watch Frameworks team you will Read more
Mobile Payments Counsel, *Apple* Pay (digit...
**Job Summary** Apple is looking for an atto ey to join Apple 's Legal Department to support Apple Pay. **Key Qualifications** 4+ years of relevant experience Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** The ASC is an Apple employee who serves as the Apple business manager and influencer in a hyper-business critical Reseller's store which delivers Read more
Partner Marketing Manager, Merchant- *Apple*...
**Job Summary** The Apple Pay partner marketing team is looking for a marketing manager to develop and drive US marketing programs with our merchant partners. The right Read more
*Apple* Solutions Consultant - Retail Sales...
**Job Summary** As an Apple Solutions Consultant (ASC) you are the link between our customers and our products. Your role is to drive the Apple business in a retail Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.