TweetFollow Us on Twitter

Horse Feathers

Volume Number: 20 (2004)
Issue Number: 7
Column Tag: Programming

QuickTime Toolkit

by Tim Monroe

Horse Feathers


In the previous article ("Tickle Me" in MacTech, June 2004), we took a look at using the Tcl scripting language and the Tk graphical user interface toolkit to build a QuickTime application. We saw how to use the QuickTimeTcl extension to add to a basic Tcl/Tk application the ability to open and display QuickTime movies. Figure 1 shows a movie displayed by our sample application, called TickLeez.

Figure 1: A movie window displayed by TickLeez (Macintosh)

In this article, I want to continue investigating QuickTimeTcl. In particular, we'll see how to configure our application to react to keyboard and operating system events. We'll also see how to implement movie editing. By the end of this article, TickLeez will incorporate all the standard movie playback and editing behaviors.

Event Bindings

Last time, we saw how to create the menu bar and menus for the TickLeez application. Later in this article, we'll learn how to adjust the state of menu items according to the current edited state of the frontmost movie window. Right now, we need to create some Tk bindings for a handful of events.

An event binding attaches a Tcl command to a specific event related to a movie window or to some other event, such as a keyboard event. The -accelerator options we specified when creating the menu items affect only the appearance of the menu items. To enable the keyboard shortcuts, we need to call the bind command, for instance like this:

bind .$winName <$appData(modKey)-n> {newDoc}

Tk also allows us to create bindings for activate and deactivate events for a window and for mouse-enter and mouse-exit events. Our complete set of event bindings is established in the setupBindings procedure, shown in Listing 1.

Listing 1: Setting up key bindings

proc setupBindings {winName} {
   global appData
   bind .$winName <$appData(modKey)-n> {newDoc}
   bind .$winName <$appData(modKey)-o> {openDoc}
   bind .$winName <$appData(modKey)-q> {exit}
   if {[isMovieWindow $winName]} {
      # window state-change bindings
      bind .$winName <Activate> {adjustMenus}
      bind .$winName <Deactivate> {adjustMenus}
      # accelerator key bindings
      bind .$winName <$appData(modKey)-w> {closeDoc}
      bind .$winName <$appData(modKey)-s> {saveDoc}
      bind .$winName <$appData(modKey)-S> {saveAsDoc}
      bind .$winName <$appData(modKey)-z> {undoDoc}
      bind .$winName <$appData(modKey)-x> {editDoc cut}
      bind .$winName <$appData(modKey)-c> {editDoc copy}
      bind .$winName <$appData(modKey)-v> {editDoc paste}
      bind .$winName <$appData(modKey)-a> {selectDoc all}
      bind .$winName <$appData(modKey)-b> {selectDoc none}
      bind .$winName <$appData(modKey)-KeyPress-1> \
                                                {puts "TO BE PROVIDED"}
      # miscellaneous bindings
      bind .$winName <Delete> {editDoc cut}
      bind .$winName <KeyPress> "handleKey $winName %K"
      bind .$winName <Leave> ".$winName configure \
                                                -cursor arrow"

Note the Leave binding: it's mainly intended for QuickTime VR movies, where the cursor is not automatically changed to the normal arrow cursor when it moves outside of the movie rectangle. (Other media types that alter the cursor, such as Flash, do not have this problem, so one could reasonably consider the VR behavior to be a bug.) Keep in mind that this workaround is not perfect: the cursor does not change to an arrow until the cursor hotspot has completely exited the movie window. This means that it will remain as the current VR cursor if moved into the window's title bar. Addressing that issue is left as an exercise for the reader.

Movie Playback

Once we've loaded a movie into a movie window (using the configure command), QuickTimeTcl takes care of all the nitty-gritty details of passing user or system events to the movie and making sure it reacts appropriately to those events. Mouse events on the movie controller bar work fine. Moreover, QuickTimeTcl takes care of tasking the movie often enough to ensure uninterrupted playback of linear movies or smooth user interaction with nonlinear movies like QuickTime VR movies or wired sprite movies.

Handling Keyboard Events

QuickTimeTcl, however, does not appear to provide built-in support for the standard methods of controlling movie playback using the keyboard. With a linear movie, for instance, pressing the space bar should toggle the current play state of the movie. And with a QuickTime VR movie, pressing the left arrow key should pan the movie to the left.

As you've probably guessed, we can support these behaviors by creating the appropriate event bindings. The setupBindings function considered just above binds key presses to the handleKey function, like so:

bind .$winName <KeyPress> "handleKey $winName %K"

The "%K" keyword is replaced with the keysym, which is a special Tk designator for a key on the keyboard. For instance, the keysym for the space bar is "space", and the keysym for the Shift key is "Shift_L".

Our implementation of handleKey, shown in Listing 2, first determines whether the specified movie window is a QuickTime VR movie or not. (The command ispanoramic is slightly misnamed, as it also returns 1 for a QuickTime VR object movie.) For a QuickTime VR movie, we use the movie widget commands pan, tilt, and fieldofview to adjust the view parameters. For linear movies, we use the commands step, play, and stop to adjust the movie time and play rate. We also adjust the movie's volume when we receive an up arrow or down arrow key.

Listing 2: Handling key presses

proc handleKey {winName key} {
   global appData
   set movie $appData($winName,movie)
   if {[$movie ispanoramic]} {
      # handle QTVR movie controller key bindings 
      # (and, yes, "ispanoramic" is true for object movies too)
      switch $key {
         "Right" {$movie pan [expr [$movie pan] - 10]}
         "Left" {$movie pan [expr [$movie pan] + 10]}
         "Up" {$movie tilt [expr [$movie tilt] + 10]}
         "Down" {$movie tilt [expr [$movie tilt] - 10]}
         "Shift_L" {$movie fieldofview [expr [$movie \
                              fieldofview] - 5]}
         "Control_L" {$movie fieldofview [expr [$movie \
                              fieldofview] + 5]}
   } else {
      # handle standard movie controller key bindings
      switch $key {
         "Right" {$movie step 1}
         "Left" {$movie step -1}
         "Up" {$movie configure -volume [min 255 \
                  [expr 64 + [$movie cget -volume]]]}
         "Down" {$movie configure -volume [max 0 \
                  [expr -64 + [$movie cget -volume]]]}
         "space" {if {[$movie rate] == 0} {$movie play} 
                                                else {$movie stop}}

Installing a Movie Controller Callback Function

At this point, TickLeez can open and display QuickTime movies, and it can handle all the standard means of user interaction with the movie. Before we move on to consider how to support movie editing, I should mention that QuickTimeTcl provides a way to observe and possibly override actions associated with the movie; that is to say, it provides a wrapper for QuickTime's movie controller action filter function.

We installed this movie controller callback function when we configured our movie widget, by passing a procedure name to the -mccommand argument:

.$ configure -mccommand controllerProc \
               -mcedit 1 -resizable 1

The specified procedure is passed the name of the movie widget, a string representing the action, and a possibly empty list of parameters associated with that action. For linear movies, these actions include activate, customButtonClick, deactivate, key, goToTime, mouseDown, play, setSelectionBegin, setSelectionDuration, and setVolume. For QuickTime VR movies, these actions also include pan, tilt, fieldofview, and triggerhotspot. Listing 3 shows the basic form of a movie controller callback function.

Listing 3: Handling movie controller actions

proc controllerProc {w what {par {}}} {
   if {![isMovieWindow [string range $w 1 end]]} {
   if {$what == "key"} {
      puts "got key event in controller action proc"

Normally the action is processed by the movie controller after our callback procedure returns. To suppress an action, we can execute this line of code:

return -code 3

Movie Editing

QuickTimeTcl provides a number of movie widget commands for performing the standard movie editing operations (cut, copy, paste, and so forth). It also provides support for multilevel undo, that is, the ability to undo more than one previous editing operation. None of the QuickTime-savvy applications that we've built hitherto supports this very nice feature, except for the MooVeez application we built in an earlier article, where the multilevel undo is provided by the Cocoa application framework. (See "The Cocoanuts" in MacTech, December 2002.) In this section, we'll see how to implement editing in TickLeez and how to adjust the File and Edit menus in accordance with the edited state of the frontmost movie window.

Handling Editing Operations

We've already seen how to invoke an edit command when the appropriate menu item is selected. For instance, in the setupMenus procedure (Listing 4 in the previous article), we saw this line of code for setting up the Clear menu item:

$m add command -label "Clear" -command {editDoc clear}

So, when the user selects the Clear menu item, the editDoc procedure is called with the "clear" parameter. Listing 4 shows our implementation of the editDoc procedure.

Listing 4: Editing a movie

proc editDoc {op} {
   global appData
   set winName [topMovieWindow]
   $appData($winName,movie) $op
   if {$op != "copy"} {
      set n [incr appData($winName,undoLevel)]
      set appData($winName,undoOp,$n) $op
      setWindowDirty $winName 1 
   adjustSize $winName

The key step here is the line of code that sends the specified operation string $op to the frontmost movie widget as a command. The movie widget supports these editing commands: cut, copy, paste, clear, add, and undo. Notice that we also increment the widget's undo level and store the operation string itself in the movie window's global data array. In a moment, we'll see how these items are used to support multilevel undo.

The editDoc function also calls the setWindowDirty function (shown in Listing 5) to mark the movie window as having been changed. (Note that QuickTimeTcl provides a built-in procedure haschanged that we could use instead of reading this stored value; however, I prefer to keep track of changes to the movie myself.)

Listing 5: Marking a movie window as changed

proc setWindowDirty {winName state} {
   global appData
   set appData($winName,dirty) $state
   if {[string match "mac*" $appData(os)]} {
      wm attributes .$winName -modified $state

Notice that, on Macintosh computers, we also set the modified attribute of the movie window; on Mac OS X, this has the effect of drawing a dot inside the window's close button, as shown in Figure 2.

Figure 2: A modified movie window

Undoing Editing Operations

Whenever an editing operation is performed, QuickTimeTcl adds information about the state of the movie just prior to the edit to an edit stack. The number of the topmost item on the stack is called the undo level. When a movie is first opened, its undo level is 0. Subsequent editing operations increment the undo level.

QuickTimeTcl allows us to undo one or more edits by executing the undo command. This command requires one parameter, which specifies the undo level we want to revert to. In TickLeez, we shall always revert to the previous edit, so we'll decrement the undo level by one and pass that number to undo. This is how we implement multilevel undo. Listing 6 shows our definition of the undoDoc function.

Listing 6: Undoing an edit

proc undoDoc {} {
   global appData
   set winName [topMovieWindow]
   if {$appData($winName,undoLevel) > 0} {
      incr appData($winName,undoLevel) -1
      $appData($winName,movie) undo \
   if {$appData($winName,undoLevel) == 0} {
      setWindowDirty $winName 0 

As you can see, if the user undoes all edits (so that the undo level reaches 0 once again), we call setWindowDirty with the parameter 0 to mark the window as not dirty.

Selecting All or None of a Movie

The Edit menu in TickLeez contains the Select All and Select None menu items. In previous articles, we've seen how to handle those items quite easily. For instance, we can handle the Select All item by setting the beginning of the movie selection to movie time 0 and the duration of the movie selection to the duration of the entire movie.

QuickTimeTcl provides the select command that we can use to set the movie selection to a specified range, but it does not provide a command that returns the duration of a movie directly. Instead, QuickTimeTcl provides the gettime command, which returns an array of four movie-related times: the current time, the length of the movie, the movie time scale, and the movie poster time. For a specific movie window, we can retrieve that array like this:

array set timeArr [$appData($winName,movie) gettime]

Once we've successfully done that, we can read the movie duration by looking at the $timeArr(-movieduration) element in the array; and we can read the current movie time by looking at the $timeArr(-movietime) element. Then we can handle the two selection menu items using the selectDoc function, defined in Listing 7.

Listing 7: Selecting all or none of a movie

proc selectDoc {op} {
   global appData
   set winName [topMovieWindow]
   array set timeArr [$appData($winName,movie) gettime]
   switch -- ${op} {
       all {$appData($winName,movie) select \
               0 $timeArr(-movieduration)}
       none {$appData($winName,movie) select \
               $timeArr(-movietime) 0}

Enabling and Disabling Menu Items

As you know, we need to adjust some of the items in the File and Edit menus based on the current state of the frontmost movie window (if one exists). For instance, if a movie has been edited, we need to enable the Save menu item in the File menu so that the user can save those changes, if desired. Listing 8 shows our implementation of the adjustMenus function, which is called by many of the editing functions we've encountered recently. We handle the Save menu item by looking at the dirty field of the stored movie window data, like this:

if {$appData($winName,dirty) == 1} {
   $bar.file entryconfigure "Save" -state active}

Here, we use Tk's entryconfigure command to set the state of a menu item.

We can determine whether other menu items should be enabled or disabled by executing the controllerinfo command. Like the gettime command we just considered, controllerinfo fills an array with a set of entries, in this case with entries that indicate the current state of the movie controller.

array set infoArr [$appData($winName,movie) controllerinfo]

For instance, if the $infoArr(-cutavailable) item is 1, then we want to enable the Cut menu item.

Listing 8: Adjusting the menus and menu items

proc adjustMenus {} {
   global appData
   set winName [topMovieWindow]
   set bar .${winName}mbar
   if {[string equal $appData(os) "windows"]} {
      if {[string equal $winName ""]} {
   # set the default state
   $bar.file entryconfigure "New" -state active
   $bar.file entryconfigure "Open..." -state active
   $bar.file entryconfigure "Close" -state disabled
   $bar.file entryconfigure "Save" -state disabled
   $bar.file entryconfigure "Save As..." -state disabled
   $bar.edit entryconfigure "Undo" -state disabled
   $bar.edit entryconfigure "Cut" -state disabled
   $bar.edit entryconfigure "Copy" -state disabled
   $bar.edit entryconfigure "Paste" -state disabled
   $bar.edit entryconfigure "Clear" -state disabled
   $bar.edit entryconfigure "Select All" -state disabled
   $bar.edit entryconfigure "Select None" -state disabled
   $ entryconfigure "Hide Controller Bar" \
            -state disabled
   if {[string equal $appData(os) "windows"]} {
      $ entryconfigure "About TickLeez" -state active
   } else {
      $ entryconfigure "About TickLeez" \
            -state active
   if {[isMovieWindow $winName]} {
      $bar.file entryconfigure "Close" -state active
      $bar.file entryconfigure "Save As..." -state active
      $bar.edit entryconfigure "Select All" -state active
      $bar.edit entryconfigure "Select None" -state active
      if {$appData($winName,dirty) == 1} {
         $bar.file entryconfigure "Save" -state active}
      array set infoArr [$appData($winName,movie) \
      if {$appData($winName,undoLevel) > 0} {
         $bar.edit entryconfigure "Undo" -state active}
      if {$infoArr(-cutavailable) == 1} {
         $bar.edit entryconfigure "Cut" -state active}
      if {$infoArr(-copyavailable) == 1} {
         $bar.edit entryconfigure "Copy" -state active}
      if {$infoArr(-pasteavailable) == 1} {
         $bar.edit entryconfigure "Paste" -state active}
      if {$infoArr(-clearavailable) == 1} {
         $bar.edit entryconfigure "Clear" -state active}
      if {$appData($winName,undoLevel) > 0} {
         set op \ $appData($winName,undoOp,$appData($winName,undoLevel))
         $bar.edit entryconfigure "Undo*" -label \
                                    "Undo [string totitle $op]"
      $ entryconfigure "Hide Controller Bar" \
            -state active

File Manipulation

Our final task before wrapping up TickLeez for delivery to end users is to handle the document-related operations -- that is saving an edited movie, saving a movie into a new file, closing a movie window, and ultimately quitting the application itself. As we've seen in previous articles, we need to track the state of a movie and prompt the user to save or discard changes to it when the movie window is to be closed or the application is to be quit.

Closing a Movie Window

When the user selects the Close menu item in the File menu (or types the appropriate keyboard shortcut), TickLeez executes the closeDoc procedure, which is defined in Listing 9.

Listing 9: Handling the Close menu item

proc closeDoc {} {
   attemptClose [topMovieWindow] closing

As you can see, closeDoc finds the name of the frontmost movie window and passes that name as an argument to the attemptClose function, along with the action name "closing". The attemptClose function needs to look at the dirty state of the window and, if necessary, display a dialog box asking the user to save or discard the changes to the movie. Listing 10 shows our definition of attemptClose.

Listing 10: Prompting the user to save a changed movie

proc attemptClose {winName action} {
   global appData
   set closeWindow 1
   if {$appData($winName,dirty) == 1} {
      set movieName [file tail $appData($winName,fileName)]
      set answer [tk_messageBox \
         -parent .$winName \
         -title "Save changes before $action" \
         -message "Do you want to save the changes you made \
                     to the document \u201C$movieName\u201D \
                     before $action?" \
         -type yesnocancel \
         -icon warning]
      switch $answer {
         yes         {set closeWindow [saveDoc]}
         cancel   {set closeWindow 0}
         no          {set closeWindow 1}
   if {$closeWindow == 1} {disposeDoc $winName}
   return $closeWindow

We display the Save Changes dialog box by calling the tk_messageBox function, this time with the yesnocancel type. Figure 3 shows the Macintosh dialog box, and Figure 4 shows the Windows dialog box.

Figure 3: The Save Changes dialog box of TickLeez (Macintosh)

Figure 4: The Save Changes dialog box of TickLeez (Windows)

Notice in Listing 10 that if the user selects Yes, we call the saveDoc procedure (defined later) and then set the closeWindow variable to the value it returns. We set the closeWindow variable to 1 if the user selects No and to 0 if the user selects Cancel. If closeWindow is 1, we call the disposeDoc function, defined in Listing 11.

Listing 11: Disposing a movie window and its associated data

proc disposeDoc {winName} {
   global appData
   if {![isMovieWindow $winName]} {return}
   destroy .$winName
   array unset appData $winName,*

The key step in disposeDoc is to call the Tk function destroy, which removes the specified window from the screen and dispose of any memory it occupies. We also call the array unset command to remove from the appData associative array any elements associated with the movie window.

Saving a Changed Movie

As we've seen, TickLeez calls the saveDoc function when the user selects the Save menu item (or types the appropriate keyboard equivalent). In addition, the attemptClose method (Listing 10) calls the saveDoc function if the user elects to save the changes to a window that is about to close. It's easy to implement saveDoc, using the save command provided by QuickTimeTcl, as shown in Listing 12.

Listing 12: Saving a movie

proc saveDoc {} {
   global appData
   set winName [topMovieWindow]
   # if the movie file is in our temporary directory, alert the user
   if {[string compare \
      -length [string length $appData(tempDir)] \
      $appData($winName,fileName) $appData(tempDir)] == 0} {
      tk_messageBox \
         -parent .$winName \
         -title "Warning" \
         -message "Cannot save this movie into the current \
            folder.\nPlease choose \u201CSave As...\u201D to \
            select a different folder." \
         -type ok \
         -icon warning
      return    0
   $appData($winName,movie) save
   setWindowDirty $winName 0 
   return 1

Recall that QuickTimeTcl requires a filename for each open movie and that we create a temporary file when the user selects the New command in the File menu. If the file we are saving is located in the designated temporary directory, we want to display the alert sheet shown in Figure 5 to force the user to save the file elsewhere.

Figure 5: The bad directory alert sheet

Saving a Movie into a New File

When the user selects the Save As menu item in the File menu, we need to elicit a location for the new movie file and then save the movie into that file. In TickLeez, we'll execute this line of code:

set newFile [tk_getSaveFile]

The tk_getSaveFile function displays a dialog box like the one shown in Figure 6. It returns as its result the full pathname of the specified file, or an empty string if the user did not specify a file.

Figure 6: The file-saving dialog box displayed by Tk

If the user does specify a file, we can write the movie into that file by calling the QuickTimeTcl command flatten, as shown in Listing 13

Listing 13: Saving a movie into a new file

proc saveAsDoc {} {
   global appData
   set winName [topMovieWindow]
   set newFile [tk_getSaveFile]
   if {$newFile != ""} {
      $appData($winName,movie) flatten $newFile
      $appData($winName,movie) configure -file $newFile
      wm title .$winName [file tail $newFile]
      set appData($winName,dirty) 0   
      set appData($winName,fileName) $newFile   
      set appData($winName,undoLevel) 0
      setWindowDirty $winName 0 

As you know, the standard behavior of a Save As operation is for the new movie to replace the existing movie in the existing movie window. Accordingly, saveAsDoc calls the QuickTimeTcl command configure with the full pathname of the new movie file. Then it resets the window title and several fields of the global data array associated with the movie.

Quitting the Application

When the user decides to quit TickLeez, we need to perform the standard quitting-time operations (such as making sure the user saves or discards any unsaved changes to the movie windows). When the user selects the Quit menu item, Tcl calls its own exit function, which performs any Tcl-specific cleanup tasks. We can make sure that our own cleanup tasks are performed prior to that by renaming the exit function to some other name, like this:

rename exit __exit

Then we can define our own exit function, as shown in Listing 14.

Listing 14: Quitting the application

proc exit {} {

The TickLeez function quitApp is shown in Listing 15. After we've inspected all movie windows and made sure that all changes have been saved, we remove the temporary directory we created earlier. Then we call __exit to let Tcl perform its cleanup tasks.

Listing 15: Handling the Quit menu item

proc quitApp {} {
   global appData
   set cancelled 0
   while {([topMovieWindow] != "") && ($cancelled == 0)} {
      set cancelled [expr ![attemptClose [topMovieWindow] \
   if {$cancelled == 0} {
      # remove the temp directory if it exists
      if {[file exists $appData(tempDir)]} {
         file delete -force $appData(tempDir)


This brings us to the end of our investigation of Tcl/Tk and QuickTimeTcl as a delivery vehicle for QuickTime applications. In just under four hundred lines of script (not counting the blank lines and comments in the file TickLeez.tcl), we've managed to construct a multi-window QuickTime playback and editing application that runs on both Macintosh and Windows computers. TickLeez exhibits all the standard user-interaction and document-related behaviors that we've come to expect of a QuickTime application, and it does so with a minimum of platform-specific code. I think that QuickTimeTcl provides a very nice wrapper for the underlying QuickTime APIs. Better still, its source code is freely available and can be easily modified to add capabilities that it does not currently provide. Neither Tcl/Tk nor QuickTimeTcl is perfect, but all three packages are under active development and promise to get even better as time goes by.


Thanks are due once again to Jim Ingham and to Mats Bengtsson for reviewing a draft of this article and for providing invaluable feedback.

Tim Monroe is a member of the QuickTime engineering team at Apple. You can contact him at The views expressed here are not necessarily shared by his employer.


Community Search:
MacTech Search:

Software Updates via MacUpdate

Artlantis Studio - 3D rendering...
Artlantis Studio is a unique and ideal tool for performing very high resolution rendering easily and in real time. The new FastRadiosity engine now lets you compute images in radiosity-even in... Read more
MacUpdate Desktop 6.0.5 - Search and ins...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
BitTorrent Sync 2.0.82 - Sync files secu...
BitTorrent Sync allows you to sync unlimited files between your own devices, or share a folder with friends and family to automatically sync anything. File transfers are encrypted. Your information... Read more
Google Drive 1.20 - File backup and shar...
Google Drive is a place where you can create, share, collaborate, and keep all of your stuff. Whether you're working with a friend on a joint research project, planning a wedding with your fiancé, or... Read more
Simon 4.0.3 - Monitor changes and crashe...
Simon monitors websites and alerts you of crashes and changes. Select pages to monitor, choose your alert options, and customize your settings. Simon does the rest. Keep a watchful eye on your... Read more
Vitamin-R 2.23 - Personal productivity t...
Vitamin-R creates the optimal conditions for your brain to work at its best by structuring your work into short bursts of distraction-free, highly focused activity alternating with opportunities for... Read more
iDefrag 5.0.0 - Disk defragmentation and...
iDefrag helps defragment and optimize your disk for improved performance. Features include: Supports HFS and HFS+ (Mac OS Extended). Supports case sensitive and journaled filesystems. Supports... Read more
PCalc 4.2 - Full-featured scientific cal...
PCalc is a full-featured, scriptable scientific calculator with support for hexadecimal, octal, and binary calculations, as well as an RPN mode, programmable functions, and an extensive set of unit... Read more
FileZilla 3.10.2 - Fast and reliable FTP...
FileZilla (ported from Windows) is a fast and reliable FTP client and server with lots of useful features and an intuitive interface. Version 3.10.2: Note: Now requires a 64-bit Intel processor.... Read more
The Hit List 1.1.11 - Advanced reminder...
The Hit List manages the daily chaos of your modern life. It's easy to learn - it's as easy as making lists. And it's powerful enough to let you plan, then forget, then act when the time is right.... Read more

Warner Bros. Interactive Entertainment A...
Warner Bros. has some exciting games coming down the pipe! | Read more »
GDC 2015 – Star Trek Timelines will Prob...
GDC 2015 – Star Trek Timelines will Probably Make Your Inner Trekkie Squeal With Glee Posted by Rob Rich on March 4th, 2015 [ permalink ] Any popular fictional universe has its fair share of fan fiction – where belo | Read more »
Protect Yourself from an Onslaught of Ca...
Surprise Attack Games has announced a Cat-astrophic new physics puzzler called Fort Meow! In the game, a young girl named Nia finds her grandfather’s journal which triggers an all mighty feline attack! Why do the cats want the journal? Who knows,... | Read more »
GDC 2015 – Jelly Reef will be Game Oven’...
GDC 2015 – Jelly Reef will be Game Oven’s Last Hurrah, and it Seems like a Good Note to Go Out on Posted by Rob Rich on March 4th, 2015 [ permalink ] It’s sad knowing that Game Oven ( | Read more »
daWindci Deluxe Review
daWindci Deluxe Review By Campbell Bird on March 4th, 2015 Our Rating: :: BLUSTERY PUZZLESUniversal App - Designed for iPhone and iPad This updated puzzle game offers some creative gameplay and new mechanics, but still suffers from... | Read more »
Dungeon Hunter 5 Coming on March 12
Gameloft has excitedly announced that Dungeon Hunter 5 is on its way! Once again, you will adventure across the land of Valenthia exploring dungeons and fighting monsters. The game will have a new asynchronous multiplayer mode called Strongholds... | Read more »
GDC 2015 – The Sandbox 2 is Coming, and...
GDC 2015 – The Sandbox 2 is Coming, and Now it has Textures! | Read more »
Warner Bros. Interactive Announces Mort...
Mortal Kombat X, by Warner Bros. and NetherRealm Studios, will be a a free-to-play fighting/card-battle Mortal Kombat game. The game promises card collecting, multiplayer team combat, classic characters such as Scorpion, Sub-Zero and Raiden, and the... | Read more »
GDC 2015 – Piloteer is Whitaker Trebella...
GDC 2015 – Piloteer is Whitaker Trebella’s Latest Project, and it’s Definitely Something DIfferent Posted by Rob Rich on March 3rd, 2015 [ permalink ] You know | Read more »
PangoLand Review
PangoLand Review By Amy Solomon on March 3rd, 2015 Our Rating: :: COME VISIT PANGO AND FRIENDSUniversal App - Designed for iPhone and iPad PangoLand is an open-ended world full of familiar characters, bright colors and interactive... | Read more »

Price Scanner via

iPad: A More Positive Outlook – The ‘Book Mys...
It’s good to hear someone saying positive things about the iPad. I’ve been trying to bend my mind around how Apple’s tablet could have gone from zero to bestselling personal computing device on the... Read more
Mac Pros on sale for up to $279 off MSRP
Amazon has Mac Pros in stock and on sale for up to $279 off MSRP. Shipping is free: - 4-Core Mac Pro: $2725.87, $273 off MSRP (9%) - 6-Core Mac Pro: $3719.99, $279 off MSRP (7%) Read more
Sale! 13-inch Retina MacBook Pros for up to $...
B&H Photo has 13″ Retina MacBook Pros on sale for up to $205 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.6GHz/128GB Retina MacBook Pro: $1219.99 save $80 - 13″ 2.... Read more
Another Tranche Of IBM MobileFirst For iOS Ap...
IBM has announced the next expansion phase for  its IBM MobileFirst for iOS portfolio, with a troika of new apps to address key priorities for the Banking and Financial Services, Airline and Retail... Read more
Sale! 15-inch Retina MacBook Pros for up to $...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for up to $250 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $... Read more
WaterField Designs Introduces the Minimalist...
With Apple Pay gaining popularity, Android Pay coming in May 2015, and loyalty cards and receipts that can be accessed from smartphones, San Francisco’s WaterField Designs observes that it may be... Read more
Sale! 15-inch 2.2GHz Retina MacBook Pro for $...
 Best Buy has the 15″ 2.2GHz Retina MacBook Pro on sale for $1774.99 $1799.99, or $225 off MSRP. Choose free home shipping or free local store pickup (if available). Price valid for online orders... Read more
13-inch 2.5GHz MacBook Pro (refurbished) avai...
The Apple Store has Apple Certified Refurbished 13″ 2.5GHz MacBook Pros available for $170 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz... Read more
13-inch 2.5GHz MacBook Pro on sale for $100 o...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999.99 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more
27-inch 3.5GHz 5K iMac in stock today and on...
 B&H Photo has the 27″ 3.5GHz 5K iMac in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP, and it’s the lowest price available for... Read more

Jobs Board

*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
Position Opening at *Apple* - Apple (United...
…Summary** As a Specialist, you help create the energy and excitement around Apple products, providing the right solutions and getting products into customers' hands. You Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** The Apple Store is a retail environment like no other - uniquely focused on delivering amazing customer experiences. As an Expert, you introduce people 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
*Apple* Pay Automation Engineer - iOS System...
**Job Summary** At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring passion and dedication to your job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.