TweetFollow Us on Twitter

Pin-up Menu
Volume Number:6
Issue Number:6
Column Tag:Pascal Procedures

"PinUpMenu" XCMD

By Steven Fuchs, Coram, NY

Interface the Music

The Problem with the Finder

Excessive Folderfication. How many readers suffer from this graphically oriented computer malady? As our hard drives grow larger we are faced with a delicate balance between maintaining enough folders to satisfy our need for organization, and so many levels of folders that finding a document requires the opening and closing of eight windows. Let’s not even mention a trip to the handy but discouraging “Find File” DA. Don’t get me wrong, I love folders as much as the next guy, but I believe many users would like to have the ability to reach through the folders to ‘grab’ a specific document.

Hypercard “Open Command”

Within the Hypertalk programming environment there exists the “Open ” command . The Open command when used with an application name as its parameter in the form “Open AppName” will launch that application in a manner similar to the Finder. In addition it can be passed a document name as a parameter in the form “Open DocName with AppName” which will cause the application to open to the specified document. This performance parallels the Finder and offers no distinct advantages. The Hypercard advantage lies in its knack for remembering the full pathnames of all documents and applications launched from within it in a “pathname memory”. When launching an application or document from Hypercard only it’s name must be given. Hypercard will search through its “pathname memory” until the correct path is found. If the document is not found Hypercard displays a modal dialog requesting the user’s aid in locating the file. If that search is successful then that pathname is added to the “pathname memory”. This “pathname memory” can be examined by looking at pages 2 through 4 of your Home stack. Here is stored the pathnames of stacks, applications, and documents respectively. If you recognize any folder names that have been changed or deleted, these can be safely removed to save time and disk space.

Introduce Pin-Up Menus

The XCMD to be described this month allows for quick selection from a set of pre-chosen commands, and is accessible from anywhere within Hypercard. The name of the XFCN is “PinUpMenu”, which can be altered by the Hypercard user for his or her own utility. The instance I will use as an example I have dubbed “The Pop-Up Finder”. Which is just what the doctor ordered for quickly launching applications and their documents from within Hypercard.

Figure 1.

Cards-Eye View

Call it Up

Upon invocation, PinUpMenu displays a small window, and waits patiently for a mousedown event (See Figure 1). If this mousedown occurs outside of the window , the window disappears and PinUpMenu has run its course. If this mousedown occurs within the window a pop-up menu (hierarchical if desired) appears and allows for the selection of any desired item. The returned value can then be processed by the script that called it. In the case of “The Pop-Up Finder” the selected application and document will be launched using Hypercards “Open” command.

Necessary Scripts, Options

The PinUpMenu XFCN must be called with at least 2 parameters (See Figure 2). The first parameter is a string which is drawn within the window. Use this parameter to differentiate between your particular implementations of PinUpMenu. Parameters 2 through 16 are used to build the menus, they accomplish this by following a few simple rules. Each parameter should be a Hypercard container which holds one or more items. An Hypercard item being a string delineated by commas. The first item in the list will be the name of that line in the parent menu, while any remaining items will be listed in order as the submenus of that line. If there is only one item in the parameter then that item will be listed alone.

The Returns

PinUpMenu is an XFCN, therefore it must be used within an assignment and will return a value to Hypercard. This value will consist of one or two items. If the original click is made outside of the window or the mouse is released outside of the menu, then “Cancel” is returned. If the mouse is released in the parent menu inside of an item with no submenus then the selection name is returned in a one item string. If the mouse is released in a submenu choice, the answer consists of a two item string, the parent item followed by the submenu item separated by a comma so that your script can process the return with little modification. Be warned, this type of construction will not allow for the use of commas in a menu, as Hypercard will interpret this as two different items.

Figure 2.

Amongst the Gears

Hierarchical Menus

Submenus and Pop-Up Menus themselves are very easy to create and call up. They are created just as are other menus are, with a call to NewMenu. Although GetNewMenu and a resource could have been used, I have decided to create all windows and menus “on the fly”. I believe that XCMD’s should function this way whenever possible, simplifying the resource fork of the users Home stack as well as avoiding numbering conflicts between other external commands. To invoke a parent menu and the associated set of submenus , all you must do is call up the parent menu. The Mac toolbox handles the correct hiliting and displaying of the submenus. In order to alert the toolbox as to what you consider to be the correct hilighting and display two things must be done. First the command key field of the item you wish to give a submenu to should be set to $1B. This is a character which Apple has reserved to represent Hierarchical menus, it consists of the now familiar triangle pointing to the right. Secondly, set the item mark field of that same item to the menu id of the submenu and that’s it. The final step is to call InsertMenu(TheMenu,-1) for each of the submenus, and for the main menu in our case since it is a pop-up menu. By specifying -1 as the second parameter you tell the Mac not to put this menu in the Menubar, but to add it to the menu list anyway. Then call PopUpMenuSelect or MenuSelect and it will take care of the details from there. A very important consideration is that the menu id of a submenu may not be greater than 255, since that value must be a character placed into the item field. Passing a number larger will at the very least not work, and in the worst case cause some major problems.

Stealing Events

While PinUpMenus (or any other external code) is in control, Hypercard is in a semiconscious state so we will have to process events in its stead. This is no problem while running under the Finder, since the Menu Manager refreshes the screen beneath menus. However, if running under MultiFinder update events being generated through application switching will not be handled. This results in white blotches in the Hypercard window. The solution is very simple. By sending Hypercard the message ‘Go to this card’ we can force Hypercard to update itself, without interrupting our goings on (Thanks to Joe Zuffoletto and his article in Feb and March 1989 MacTutor for that handy tip). This however does not update the message box or the tool/pattern windoids. If this causes a problem the windoids can be restored by simply hiding and showing them again once PinUpMenu has run its course. Since the PinUpMenu XFCN serves no real purpose running in the background I plead guilty with explanation to not devising a more graceful alternative.

Saying Goodbye

Cleaning up the stack before returning to Hypercard is very important for any external code. I make sure all menuhandles not used are set to nil. This helps to determine which items have submenus, allowing us to avoid the unpleasant symptoms of deleting a menu which is not there or not deleting a menu that is. When writing external code it is important to dispose of all handles and pointers before returning. The leaving of unneeded blocks of memory lying around the heap for Hypercard to skirt is a very unMac-Like way of programming. In addition the window must be disposed of, and last but certainly not least the GrafPort must be reset to its state before the XFCN ran. If all of these have been done correctly then Hypercard should return without difficulty.

Getting Fancy

Simplicity equals Power

The structure of the XFCN, while remaining simple may be confusing to some developers not familiar with nesting procedures and functions. Under ordinary circumstances this is not necessary, and not often used. When writing a XFCN (or any other code resource) global variables are not allowed. By declaring the important variables in MAIN and then nesting all of the other routines, these variables can be treated as globals by the nested routines.

To sum up the actions of PinUpMenu in a nutshell besides creating a window it merely deciphers Hypercard item lists and calls AppendMenu for each of these. Simplicity yes but where is the power in that? Well, for those of you familiar with AppendMenu’s inherent power the answer is one simple word. Metacharacters. By passing these Metacharacters through Hypercard to PinUpMenus, all of the effects which can be used to make menus more clear can be used.

Staying in Metacharacter

Within the structure of the Mac OS menus may have some different characteristics. Each menu item may be drawn in a different style, may have an icon, may be enabled or disabled, and can have a command key associated with it. These can be added by a developer with little problem, by being specified in a resource file, or added through the AppendMenu call with Metacharacters. A metacharacter is a character which is not part of the actual text. Instead it allows for special distinctions to be made for a menu item. To add an icon to a menu item use the “^” character followed by the icons number less 256. To mark an item with a check mark or some such character, place an exclamation point (!) followed by the character before your item. The less than symbol (<) followed by either B,I,U,O,S sets the style of that item to the corresponding standard style. A slash (/) will associate a command key with that item, and a left parentheses (() will disable the item. If you don’t quite understand this you should get Inside Macintosh Volume 1 (which you should have anyway) and read page 352, where it is all explained very well.

K.I.S.S.

The most important aspect of menus is to add simplicity to your programs, or in this case stacks, menus should serve, not confuse. This means keeping styles, icons, item marks, and command keys to a minimum. By the way any command key equivalents used in PinUpMenus won’t work from Hypercard, since they only exist while the XFCN is running (i.e. while you are holding the mouse button down). If you must use command key equivalents you will have to trap for them yourself from within the scripts.

In Summation

Advantages and Other Uses

The Pop-Up Finder represents a speedy way to launch any desired application and/or document. But this is not the only use for our versatile little XFCN. Since PinUpMenu accepts its parameters as Hypercard item lists, scripts can use it to process and display whatever information they desire. I have written a script which determines the names of all objects in the present card and presents them in menu format. The object which is selected then opens its script for editing. I have also used it as a Pop-Up home stack, presenting the user with a variety of stack categories and names, going to whichever one is selected. For those of you who have taken the time to type this all in, or sent away for the source code, I believe the PinUpMenu represents a very useful XFCN, it makes no great departure from the mandated user interface standard yet allows for a customizable method of processing and choosing your Hypercard data. Hope you like it.

Listing:  XCMDUtil.PUM

unit XCMDUtils;

interface
 uses
 XCMDIntf;
 type
 Str31 = string[31];

 function PasToZero (paramPtr: XCmdPtr;
  str: Str255): Handle;

 procedure ZeroToPas (paramPtr: XCmdPtr;
 zeroStr: Ptr; var pasStr: Str255);

 procedure SendCardMessage (paramPtr: XCmdPtr; 
 msg: Str255);

implementation

 procedure DoJsr (addr: ProcPtr);
 inline
 $205F, $4E90;

 procedure SendCardMessage;
 begin
 with paramPtr^ do
 begin
 inArgs[1] := ORD(@msg);
 request := xreqSendCardMessage;
 DoJsr(entryPoint);
 end;
 end;

 function PasToZero;
 begin
 with paramPtr^ do
 begin
 inArgs[1] := ORD(@str);
 request := xreqPasToZero;
 DoJsr(entryPoint);
 PasToZero := Handle(outArgs[1]);
 end;
 end;

 procedure ZeroToPas;
 begin
 with paramPtr^ do
 begin
 inArgs[1] := ORD(zeroStr);
 inArgs[2] := ORD(@pasStr);
 request := xreqZeroToPas;
 DoJsr(entryPoint);
 end;
 end;

end.
Listing:  PinUpMenu.p

unit PinUpMain;
{--This is the source code of the PinUpMenu XFCN--}
{--Written by Steven Fuchs--}
{--PO Box 129, Coram, NY 11727--}

interface
 uses
 XCMDIntF, XCMDUtils;
 procedure MAIN (ParamPtr: XCMDPtr);
implementation
 type
 MenuArray = array[0..15] of MenuHandle;
 StrArray = array[0..15] of str255;

 procedure MAIN (ParamPtr: XCMDPtr);
 var
 TheMenus: MenuArray;
 TheParams: StrArray;
 PinUpWindow: WindowPtr;
 OldPort: GrafPtr;
 EndRect: rect;
 Name, TheAnswer: str255;
 item: longint;

{--HandleDrawing is a simple routine to draw our windows string--}
 procedure HandleDrawing;
 begin
 MoveTo(PinUpWindow^.portrect.left + 2, PinUpWindow^.portrect.bottom 
- 4);
 DrawString(Name);
 end;

{--HandleThisUpdate determines the correct action to take in  response--}
{--to an Update Event,  if the window is ours it calls HandleDrawing, 
if--}
{--it is the Hypercard main window, it calls SendCardMessage, otherwise--}
{--(most likely one of the tool pallettes) it removes the message--}
 procedure HandleThisUpdate (LilWindow: WindowPtr);
 begin
 BeginUpdate(LilWindow);
 if WindowPtr(LilWindow) = OldPort then
 SendCardMessage(ParamPtr, ‘Go to this card’)
 else if WindowPtr(LilWindow) = PinUpWindow then
 HandleDrawing
 else
 ValidRect(LilWindow^.portrect);
 EndUpdate(LilWindow);
 end;

{--GetParams is responsible for transferring parameters--}
{--sent to MAIN into our variables: Name, and TheParams arrray}
 function GetParams: boolean;
 var
 NumOfMenus, z: integer;
 begin
 NumOfMenus := ParamPtr^.ParamCount - 1;
 GetParams := NumOfMenus >= 1;
 ZeroToPas(ParamPtr, ParamPtr^.params[1]^, Name);
 for z := 1 to 15 do
 if z <= NumOfMenus then
 begin
 ZeroToPas(ParamPtr, ParamPtr^.params[z + 1]^, TheParams[z]);
 TheParams[z] := Include(‘,’, TheParams[z], length(TheParams[z]) + 1);
 end
 else
 TheParams[z] := ‘’;
 end;

{--ReturnWindowRect must determine length of string “Name”--}
{--Size the rectangle so the string fits nicely inside, and locate it 
so that--}
{--it appears in the same spot regardless of screen size--}
 procedure ComputeWindowRect;
 var
 DummyPt: point;
 begin
 SetPt(DummyPt, 150, 100);
 SetRect(EndRect, 0, 0, stringwidth(Name) + 20, 17);
 LocaltoGlobal(DummyPt);
 OffsetRect(EndRect, DummyPt.h, DummyPt.v);
 end;

{--CreateWindow does just that, creating the window for us and setting 
up the default drawing characteristics--}
 procedure CreateWindow;
 var
 LongOne: LongInt;
 begin
 PinUpWindow := NewWindow(nil, EndRect, ‘The Course’, false, 3, nil, 
false, LongOne);
 SetPort(PinUpWindow);
 TextFont(0);
 TextSize(12);
 ShowWindow(PinUpWindow);
 SelectWindow(PinUpWindow);
 end;

{--HitCameInWindow holds our event loop, where it waits for a mousedown--}
{--if this mousedown is within the window we return true, otherwise false.--}
 function HitCameInWindow: boolean;
 var
 Event: EventRecord;
 begin
 HitCameInWindow := false;
 repeat
 SystemTask;
 if GetNextEvent(EveryEvent, Event) then
 case Event.What of
 MouseDown: 
 if PtInRect(Event.Where, EndRect) then
 HitCameInWindow := true;
 UpdateEvt: 
 HandleThisUpdate(WindowPtr(event.message));
 ActivateEvt: 
 HandleDrawing;
 otherwise
 end
 until Event.What = Mousedown;
 end;

{--ReturnAndMaul is our parsing function, it reads the first item from--}
{--the string indicated by Index and returns it. It then deletes that 
item--}
 function ReturnAndMaul (Index: integer): str255;
 var
 ThePlace: integer;
 begin
 ThePlace := Pos(‘,’, TheParams[Index]);
 if ThePlace = 0 then
 ReturnAndMaul := ‘’
 else
 begin
 ReturnAndMaul := str255(copy(TheParams[Index], 1, ThePlace - 1));
 delete(TheParams[Index], 1, ThePlace);
 end;
 end;

{--CreateSubMenu does just that, creating the menu with NewMenu and sets 
the correct fields in the main menu to indicate the submenu exists--}
 procedure CreateSubMenu (Index: integer);
 var
 swf, saf: char;
 begin
 swf := chr($1B);
 saf := chr(240 + Index);
 TheMenus[Index] := NewMenu(240 + Index, ‘ASubMenu’);
{--Tell Mac OS we have a submenu--}
 SetItemCmd(TheMenus[0], Index, swf);
{--Tell Mac OS which Menu it is--}
 SetItemMark(TheMenus[0], Index, saf);
 end;

{--AddAllItems calls ReturnAndMaul repeatedly until there is nothing--}
{--left of string indicated by Index.  Each of items up until--}
{--that point is appended to the end of the submenu.--}
 procedure AddAllItems (TIndex: integer);
 var
 stripe: str255;
 x: integer;
 begin
 repeat
 stripe := ReturnAndMaul(TIndex);
 if stripe <> ‘’ then
 AppendMenu(TheMenus[TIndex], Stripe);
 until stripe = ‘’;
{--Insert our menu into hierarchical portion of MenuList--}
 InsertMenu(TheMenus[TIndex], -1);
 end;

{--BuildThoseMenus is the top layer, it creates the main menu and adds 
the items, decides if that item needs submenus and if so calls the procedures 
to add them--}
 procedure BuildThoseMenus;
 var
 Increment: integer;
 ScaredStr: str255;
 begin
 TheMenus[0] := NewMenu(240, ‘MainMenu’);
 for increment := 1 to 15 do
 begin
 TheMenus[increment] := nil;
 ScaredStr := ReturnAndMaul(increment);
 if ScaredStr <> ‘’ then
 begin
 AppendMenu(TheMenus[0], ScaredStr);
 if Pos(‘,’, TheParams[increment]) <> 0 then
 begin
 CreateSubMenu(increment);
 AddAllItems(increment);
 end;
 end;
 end;
{--Insert main menu into PopUp portion of Menu List--}
{--Same call as for hierarchical menus--}
 InsertMenu(TheMenus[0], -1);
 end;

{--ConvertAnswer takes the longint returned from PopUpMenuSelect and 
Converts it to the proper string for return to Hypercard--}
 function ConvertAnswer (TheL: longInt): str255;
 var
 ThePrimary, TheSecondary: str255;
 begin
 if TheL = 0 then
 ConvertAnswer := ‘Cancel’
 else if HiWord(TheL) = 240 then
 begin
 GetItem(TheMenus[HiWord(TheL) - 240], LoWord(TheL), TheSecondary);
 ConvertAnswer := TheSecondary;
 end
 else
 begin
 GetItem(TheMenus[0], HiWord(TheL) - 240, ThePrimary);
 GetItem(TheMenus[HiWord(TheL) - 240], LoWord(TheL), TheSecondary);
 ConvertAnswer := Str255(concat(ThePrimary, ‘,’, TheSecondary))
 end;
 end;

{--CleanUpMess takes care of the very important work of cleaning up the--}
{--heap before handing the reins back to Hypercard--}
 procedure CleanUpMess;
 var
 x: integer;
 begin
 DisposeWindow(PinUpWindow);
 for x := 0 to 15 do
 if TheMenus[x] <> nil then
 begin
 DeleteMenu(240 + x);
 DisposeMenu(TheMenus[x]);
 end;
 end;

{--Here is the code for the procedure MAIN, it acts at the highest level 
farming out almost all of the tasks to its other procedures and functions--}
 begin
 GetPort(OldPort);
 TheAnswer := ‘Cancel’;
 if GetParams then
 begin
 ComputeWindowRect;
 CreateWindow;
 BuildThoseMenus;
 if HitCameInWindow then
 begin
 Item := PopUpMenuSelect(TheMenus[0], EndRect.bottom + 4, EndRect.left, 
0);
 TheAnswer := ConvertAnswer(Item);
 end;
 SetPort(OldPort);
 CleanUpMess;
 end;
 ParamPtr^.returnvalue := PastoZero(ParamPtr, TheAnswer);
 end;
end.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Adobe Dreamweaver CC 2018 18.0.0.10136 -...
Dreamweaver CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Dreamweaver customer). Adobe Dreamweaver CC 2018 allows you to... Read more
Adobe Lightroom 20170919-1412-ccb76bd] -...
Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more
Adobe Photoshop CC 2018 19.0.0 - Profess...
Photoshop CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Photoshop customer). Adobe Photoshop CC 2018, the industry standard... Read more
Adobe Muse CC 2017 2018.0.0 - Design and...
Muse CC 2018 is available as part of Adobe Creative Cloud for as little as $14.99/month (or $9.99/month if you're a previous Muse customer). Adobe Muse 2018 enables designers to create websites as... Read more
Adobe Animate CC 2017 18.0.0.107 - Anima...
Animate CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Flash Professional customer). Animate CC 2018 (was Flash CC) lets you... Read more
Hopper Disassembler 4.3.0- - Binary disa...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
GraphicConverter 10.5.1 - $39.95
GraphicConverter is an all-purpose image-editing program that can import 200 different graphic-based formats, edit the image, and export it to any of 80 available file formats. The high-end editing... Read more
Delicious Library 3.7 - Import, browse a...
Delicious Library allows you to import, browse, and share all your books, movies, music, and video games with Delicious Library. Run your very own library from your home or office using our... Read more
Duet 1.6.7.0 - Use your iPad as an exter...
Duet is the first app that allows you to use your iDevice as an extra display for your Mac using the Lightning or 30-pin cable. Note: This app requires a $14.99 iOS companion app. Version 1.6.7.0:... Read more
iExplorer 4.1.5 - View and transfer file...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more

Wheels of Aurelia (Games)
Wheels of Aurelia 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: | Read more »
Halcyon 6: Starbase Commander guide - ti...
Halcyon 6 is a well-loved indie RPG with stellar tactical combat and some pretty good writing, too. It's now landed on the App Store, so mobile fans, if you're itching for a good intergalactic adventure, here's your game. Being a strategy RPG, the... | Read more »
Game of Thrones: Conquest guide - how to...
Fans of base building games might be excited to know that yet another entry in the genre has materialized - Game of Thrones: Conquest. Yes, you can now join the many kingdoms of the famed book series, or create your own, as you try to conquer... | Read more »
Halcyon 6: Starbase Commander (Games)
Halcyon 6: Starbase Commander 1.4.2.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.4.2.0 (iTunes) Description: An epic space strategy RPG with base building, deep tactical combat, crew management, alien diplomacy,... | Read more »
Legacy of Discord celebrates its 1 year...
It’s been a thrilling first year for fans of Legacy of Discord, the stunning PvP dungeon-crawling ARPG from YOOZOO Games, and now it’s time to celebrate the game’s first anniversary. The developers are amping up the festivities with some exciting... | Read more »
3 reasons to play Thunder Armada - the n...
The bygone days of the Battleship board game might have past, but naval combat simulators still find an audience on mobile. Thunder Armada is Chinese developer Chyogames latest entry into the genre, drawing inspiration from the explosive exchanges... | Read more »
Experience a full 3D fantasy MMORPG, as...
Those hoping to sink their teeth into a meaty hack and slash RPG that encourages you to fight with others might want to check out EZFun’s new Eternity Guardians. Available to download for iOS and Android, Eternity Guardians is an MMORPG that lets... | Read more »
Warhammer Quest 2 (Games)
Warhammer Quest 2 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Dungeon adventures in the Warhammer World are back! | Read more »
4 of the best Halloween updates for mobi...
Halloween is certainly one of our favorite times for mobile game updates. Many popular titles celebrate this spooky season with fun festivities that can stretch from one week to even the whole month. As we draw closer and closer to Halloween, we'... | Read more »
Fire Rides guide - how to swing to succe...
It's another day, which means another Voodoo game has come to glue our hands to our mobile phones. Yes, it's been an especially prolific month for this particular mobile publisher, but we're certainly not complaining. Fire Rides is yet another... | Read more »

Price Scanner via MacPrices.net

Apple restocks full line of refurbished 13″ M...
Apple has restocked a full line of Apple Certified Refurbished 2017 13″ MacBook Pros for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is free.... Read more
13″ 3.1GHz/256GB MacBook Pro on sale for $167...
Amazon has the 2017 13″ 3.1GHz/256GB Space Gray MacBook Pro on sale today for $121 off MSRP including free shipping: – 13″ 3.1GHz/256GB Space Gray MacBook Pro (MPXV2LL/A): $1678 $121 off MSRP Keep an... Read more
13″ MacBook Pros on sale for up to $120 off M...
B&H Photo has 2017 13″ MacBook Pros in stock today and on sale for up to $120 off MSRP, each including free shipping plus NY & NJ sales tax only: – 13-inch 2.3GHz/128GB Space Gray MacBook... Read more
15″ MacBook Pros on sale for up to $200 off M...
B&H Photo has 15″ MacBook Pros on sale for up to $200 off MSRP. Shipping is free, and B&H charges sales tax in NY & NJ only: – 15″ 2.8GHz MacBook Pro Space Gray (MPTR2LL/A): $2249, $150... Read more
Roundup of Apple Certified Refurbished iMacs,...
Apple has a full line of Certified Refurbished 2017 21″ and 27″ iMacs available starting at $1019 and ranging up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free... Read more
Sale! 27″ 3.8GHz 5K iMac for $2098, save $201...
Amazon has the 27″ 3.8GHz 5K iMac (MNED2LL/A) on sale today for $2098 including free shipping. Their price is $201 off MSRP, and it’s the lowest price available for this model (Apple’s $1949... Read more
Sale! 10″ Apple WiFi iPad Pros for up to $100...
B&H Photo has 10.5″ WiFi iPad Pros in stock today and on sale for $50-$100 off MSRP. Each iPad includes free shipping, and B&H charges sales tax in NY & NJ only: – 10.5″ 64GB iPad Pro: $... Read more
Apple iMacs on sale for up to $130 off MSRP w...
B&H Photo has 21-inch and 27-inch iMacs in stock and on sale for up to $130 off MSRP including free shipping. B&H charges sales tax in NY & NJ only: – 27″ 3.8GHz iMac (MNED2LL/A): $2179 $... Read more
2017 3.5GHz 6-Core Mac Pro on sale for $2799,...
B&H Photo has the 2017 3.5GHz 6-Core Mac Pro (MD878LL/A) on sale today for $2799 including free shipping plus NY & NJ sales tax only . Their price is $200 off MSRP. Read more
12″ 1.2GHz Space Gray MacBook on sale for $11...
Amazon has the 2017 12″ 1.2GHz Space Gray Retina MacBook on sale for $100 off MSRP. Shipping is free: 12″ 1.2GHz Space Gray MacBook: $1199.99 $100 off MSRP Read more

Jobs Board

Commerce Engineer, *Apple* Media Products -...
Commerce Engineer, Apple Media Products (New York City) Job Number: 113028813New York City, New York, United StatesPosted: Sep. 20, 2017Weekly Hours: 40.00 Job Read more
US- *Apple* Store Leader Program - Apple (Un...
US- Apple Store Leader Program Job Number: VariousUnited StatesPosted: Oct. 19, 2017Retail Store Job Summary Learn and grow as you explore the art of leadership at Read more
Product Manager - *Apple* Pay on the *Appl...
Job Summary Apple is looking for a talented product manager to drive the expansion of Apple Pay on the Apple Online Store. This position includes a unique Read more
*Apple* Retail - Multiple Positions - Farmin...
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
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
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.