TweetFollow Us on Twitter

Try Pop-Up
Volume Number:1
Issue Number:13
Column Tag:C Workshop

Try Pop-Up Menus!

By Mike Schuster, Consulair Corp.

What's a Pop-Up Menu?

The Macintosh™ user interface provides a repertoire of graphic objects that perform functions when pressed with the mouse. Pressing a scroll bar's arrow moves the document under the window. Selecting a tool from a palette determines the type of object to be drawn. Pressing on a menu title presents a list of choosable actions and attributes. A feature missing from this repertoire is the ability to associate a menu with an arbitrary graphic object on the screen. A pop-up menu provides just this capability.

Here's how it works: When you press on a object with an associated pop-up menu (the little menu icon above), the menu instantly "pops-up" right on top of the object and under the pointer. While holding down the mouse button, you move the pointer down the menu. As pointer moves to each item, the item is highlighted. The item that's highlighted when you release the mouse button is choosen. As soon as the button is released, the command blinks briefly, the menu disappears, and the command is executed, just like a pull-down menu.

A pop-up menu shares many of the advantages of a pull-down menu: It's invisible until you want to see it, yet at the same time it's easy to see and choose items from. Until you choose an item, nothing happens, so you can look at a pop-up without making a commitment to do anything.

The advantage of a pop-up is that it directly associates actions and attributes with an object on the screen. Its biggest disadvantage is that there may be no indication that a given object has an associated menu, until you happen to press on it. This disadvantage could lead to less transparent and less consistent applications, especially if the application's standard menus were replaced with pop-ups. Don't do that! I find them most useful in dialog boxes and desk accessories.

One final issue. When the user presses on an object with a pop-up menu, it might be desirable to highlight the object and have the menu pop-up just below the object, in a manner similar to pull-down menus. I'd call such a scheme a "pop-down" menu, and leave its implementation as an exercise.

Designing a Pop-Up

To make pop-up menus easy to use, I wanted to minimize the number of additional routines an application or desk accessory must call. Also, I wanted to apply all of the existing resource editing and compiling tools to construction and modification of the resource file description of a pop-up. Finally, to minimize my programming effort, I wanted to use as much of the Menu Manager's built in machinery as possible. With these goals in mind, I decided to use the standard menu record and the standard menu definition procedure without modification.

My efforts resulted in the single routine PopUpSelect. Its interface is almost identical to the Menu Manager routine MenuSelect:

 typedef short int16;
 typedef long int32;
 int32 PopUpSelect(theMenu, hitPt)
 MenuHandle theMenu;
 Point * hitPt;

Here's how you use it: When your application receives a mouse-down event in an object that has an associated pop-up, your application should call the PopUpSelect, supplying it with a handle to the pop-up menu and the point where the mouse button was pressed. PopUpSelect will pop-up the menu, track the mouse and highlight menu items until the user releases the mouse button. PopUpSelect returns a 32 bit integer in a manner identical to MenuSelect. The high-order 16 bits contains the menu ID of the pop-up menu, the low-order 16 bits contains the menu item number of the item that was choosen. If no item was choosen, the value returned is 0. (I use int16 and int32 to avoid the ambiguity inherent in the sizes of C's short, int, and long types. Also, I pass points by address rather than by value, in deference to Inside Mac.)

Before PopUpSelect can be called, the pop-up menu itself must be set up. Since a pop-up has the same structure as a pull-down menu, you do this by reading the menu from a resource file using GetMenu, or allocate it with NewMenu and filling it with items using AppendMenu, AddResMenu or InsertResMenu. The only difference in usage between pull-down and pop-up menus is that pull-downs are added to the menu bar using InsertMenu, and pop-ups are passed to PopUpSelect whenever the appropriate mouse-down events occur.

One thing to note: Don't bother defining a command key equivalent to an item in a pop-up. Since the pop-up is not in the menu bar, the Menu Manager routine MenuKey won't be able to find it. You could add all of your pop-ups to the menu bar just before the MenuKey call, and remove them just after, but don't do this! There's no need for these items to have command equivalents.

Making It Work

PopUpSelect is built up from the following sequence of operations:

- determine where to draw the pop-up

- save the part of the screen under the pop-up

- draw the pop-up

- track the mouse until the mouse button is released

- blink the selected item, if any

- erase the pop-up and restore the screen

- return the appropriate result

The first task, that of determining where to draw the pop-up, is based on the size of the menu and the location where the mouse was pressed. The size of the menu is defined by the fields menuWidth and menuHeight in the menu record (whose definition is shown below), which specify the horizontal and vertical dimensions of the menu, in pixels. The Menu Manager determines these values when the menu is allocated and filled with items.

 typedef struct
 {
 int16 menuID;
 int16 menuWidth;
 int16 menuHeight;
 Handle menuProc;
 int32 enableFlags;
 Str255 menuData;
 } MenuInfo, *MenuPtr, **MenuHandle;

The standard menu definition procedure draws the menu's items inside a rectangle of these dimensions. The black border and shadow of the standard pull-down menu appear immediately outside that rectangle.

I decided that the rectangle should be positioned so that the location where the mouse was pressed is just inside of the top-right corner of the menu. The pop-up hangs generally downward and to the left of the pointer. The only constraint on this positioning is that the menu must be completely visible in the desktop portion of the screen. Thus, the rectangle must be shifted in the appropriate direction if the mouse location is near the menu bar or an edge of the screen.

The technique I used to determine the coordinates of the menu rectangle can best be explained with the aid of a diagram. The point labeled S is the top-left corner of the screen. The point labeled M is the location where the mouse was pressed (defined by the hitPt argument). The rounded corner rectangle represents the screen. The thick bordered rectangle containing M represents the boundary of the pop-up.

Notice that top-left corner of the menu rectangle is displaced POINTERH pixels horizontally and POINTERV pixels vertically from M. These values incorporate my decision to have the menu appear generally to the left and downward from the pointer. They are constants in the implementation, and hence are easy to change.

The top of the menu rectangle is displaced 20 pixels downward from the local origin, labeled 0,0 in the diagram. By defining a local origin in this manner, the standard menu definition procedure is tricked into thinking that it is drawing the menu just below the menu bar. That is, the top coordinate of the menu rectangle in the local system is 20, the height of the standard menu bar. Given these values, you should be able to find that the horizontal coordinate of S is -(hitPt.h - POINTERH) and its vertical coordinate is -(hitPt.v - POINTERV - 20).

The final constraint on the local location of S is that the menu must be completely visible in the desktop portion of the screen. This constrains the horizontal coordinate of S to be less than or equal to 0 (otherwise the left side of the menu would be off-screen) and greater than or equal to the width of the menu minus the width of the screen (otherwise the right side would be off-screen). A similar situation holds vertically. All of these computations (plus an allowance for the menu's frame and shadow) are incorporated in the arguments of a Quickdraw SetOrigin call, which sets up the desired local origin.

One final item to note: SetOrigin translates the coordinates of the current port's portBits.bounds, portRect, and visRgn to the new coordinate system, but not its clipRgn. Hence, a call to ClipRect with the translated portRect as an argument is appropriate after the SetOrigin call.

PopUpSelect accomplishes the task of saving the part of the screen under the pop-up by copying that part to an off-screen bitmap using the Quickdraw routine CopyBits. The off-screen bitmap is allocated with a NewHandle call. The width of the menu rectangle (plus the width of the frame and shadow) determines the value of its rowBytes field (appropriate rounded up to a multiple of 2 bytes, since rowBytes must be even). The height of the menu rectangle (plus the height of the frame and shadow) determines the number of rows in the bitmap. These two values multiplied together, plus the size of a bitmap structure, determine the number of bytes to allocate. The bitmap structure itself is build in the first few bytes of the allocated area. The baseAddr field of the bitmap points to the byte immediately following the end of the bitmap structure.

The next task, that of drawing the menu, is performed by calling the standard menu definition procedure whose handle is contained in the menuProc field of the menu record. A menu definition procedure has the following interface:

 #define mDrawMsg 0
 #define mChooseMsg 1
 #define mSizeMsg 2

 MenuDefProc(message, theMenu, menuRect,
 hitPt, whichItem)
 int16 message;
 MenuHandle theMenu;
 Rect *menuRect;
 Point *hitPt;
 int16 *whichItem;

Passing the message mDrawMsg to the menu definition procedure causes it to draw the menu inside the rectangle menuRect. The Window Manager port should be the current port when this message is sent. I set the port's clipRgn equal to menuRect, just to be safe.

The task of tracking the mouse is accomplished by passing the message mChooseMsg to the menu definition procedure. When the procedure receives mChooseMsg, its hitPt parameter is the current mouse location, and its whichItem parameter is the item number of the last item that was choosen from the menu. If the location is in an enabled menu item, the procedure unhighlights whichItem and highlights the newly choosen item (unless the new item is the same as the whichItem), and returns the item number of the new item in whichItem. If the location isn't in an enabled item (or isn't inside menuRect), the procedure unhighlights whichItem and returns 0. The following fragment of code shows how this works:

 whichItem = 0;
 SetPt(hitPt, 0, 0);
 do
 {
 MenuDefProc(mChooseMsg, theMenu, 
 &menuRect, hitPt, &whichItem);
 GetMouse(hitPt);
 }
 while (WaitMouseUp());

WhichItem and hitPt are both initialized to 0 since the local coordinate system has changed, invalidating the original value of hitPt. This initialization is consistent since the local origin is outside menuRect. GetMouse returns the mouse location in the local coordinate system of the current port, which is just what we want. Finally, WaitMouseUp is called rather than StillDown so that the pending mouse-up event is removed, to avoid confusing the application (MenuSelect does this too).

If the final value of whichItem is not zero, then PopUpSelect interrogates the menu blink value in the system parameter ram area and sends the menu definition procedure the mChooseMsg message an appropriate number of times to blink the selected item. The hitPt argument is alternately modified so that the item blinks.

The task of restoring the screen after the mouse-up occurs is easily accomplished with CopyBits. The off-screen bitmap is deallocated after CopyBits completes. The original coordinate system is also restored with a second SetOrigin call.

Finally, PopUpSelect returns the appropriate result based on the menu's menuID field and the final value of whichItem.

An Implementation

The remainder of the article contains the implementation of PopUpSelect and a sample program showing how to use it. The sample draws the caution alert icon on the screen and pops-up a short menu whenever the icon is pressed. The sources are set up to use the Consulair C compiler and header files, version 4.01. [Note that a complete Megamax version is supplied along with this Consulair version on the source code disk, courtesy of the author. -Ed.]


/*
 * Pop-Up Menu Selection
 * by Mike Schuster
 *
 * function PopUpSelect(theMenu: MenuHandle, hitPt: Point): Longint
 *
 * with hitPt equal to the point (in global coordinates) where the mouse
 * button was pressed, PopUpSelect will pop up theMenu and retain control
 * by tracking the mouse and highlighting menu items until the mouse 
button
 * is released.  PopUpSelect returns a 32-bit integer in a manner identical
 * to the Menu Manager routine MenuSelect.
 *
 * October 16, 1985: Version 1.0
 */

#include "memory.h"
#include "resource.h"
#include "quickdraw.h"
#include "menu.h"
#include "osmisc.h"

#define GETSYSPPTR ((SysPPtr) 0x1F8)

typedef short int16;
typedef long int32;

#define mDrawMsg 0
#define mChooseMsg 1
#define mSizeMsg 2

#define POINTERH (*theMenu)->menuWidth - 4   /* width offset from hitPt 
*/
#define POINTERV 8 /* height offset from hitPt */

#define MENUV 20 /* height of menu bar */

#define FRAMEH 2 /* width of menu frame */
#define FRAMEV 2 /* height of menu frame */

#define DELAY 2L /* blink delay */

/* pin integer i between lower and upper bounds l and u */
static pin(i, l, u)
 int16 i;
 int16 l;
 int16 u;
 {
 if (i < l)
 return l;
 else if (i > u)
 return u;
 else
 return i;
 }

/* invoke the standard menu definition procedure */
static MenuDefProc(message, theMenu, menuRect, hitPt, whichItem)
 int16 message;
 MenuHandle theMenu;
 Rect *menuRect;
 Point *hitPt;
 int16 *whichItem;
 {
 #asm
 move.w message,-(A7); push first parameter
 move.l theMenu,-(A7)
 move.l menuRect,-(A7)
 move.l hitPt,A0
 move.l (A0),-(A7)
 move.l whichItem,-(A7)   ; push last parameter
 move.l theMenu,A0 ; get menu handle
 move.l (A0),A0  ; get menu pointer
 move.l 6(A0),A0 ; get menu proc handle
 move.l (A0),A0  ; get menu proc pointer
 jsr    (A0); dive in
 #endasm
 }

/* popup menu selection routine */
int32 PopUpSelect (theMenu, hitPt)
 MenuHandle theMenu;
 Point *hitPt;
 {
 GrafPtr port;   /* current graf port */
 GrafPtr wMgrPort; /* window manager port */
 BitMap **theMenuBits;    /* handle to BitMap to save screen in */
 BitMap *menuBits; /* pointer to "" */
 int16 rowBytes; /* rowBytes of "" */
 int16 rows;/* rows of "" */
 Rect menuRect;  /* menu rectangle, in local coordinates*/

 int16 whichItem;/* selected item */
 int16 blink;    /* blink count */
 int32 nilPt;    /* nil point for blink */

 /* return if mouse is not down */
 if (!WaitMouseUp())
 return 0L;

 /* determine the menu rectangle, in local coordinates */
 SetRect(&menuRect, 
 0, MENUV, (*theMenu)->menuWidth, MENUV + (*theMenu)->menuHeight);

 /* inset the menu rectangle to include the frame and shadow */
 InsetRect(&menuRect, -FRAMEH, -FRAMEV);

 /* allocate the bitmap to save screen in */
 rowBytes = ((menuRect.right - menuRect.left + 15) >> 4) << 1;
 rows = menuRect.bottom - menuRect.top;
 theMenuBits = (BitMap **) 
 NewHandle(rowBytes * rows + (int32) sizeof(BitMap));

 /* return if no space */
 if (!theMenuBits)
 return 0L;

 /* lock down the bitmap */
 HLock(theMenuBits);
 menuBits = *theMenuBits;

 /* initialize the BitMap */
 menuBits->baseAddr = (char *) (menuBits + 1);
 menuBits->rowBytes = rowBytes;
 menuBits->bounds = menuRect;

 /* save the current graf port, use the window manager port */
 GetPort(&port);
 GetWMgrPort(&wMgrPort);
 SetPort(wMgrPort);

 /* set origin so that menu definition procedure draws menu under hitPt 
*/
 /* pin so that whole menu is visible */
 SetOrigin
 (pin(POINTERH - hitPt->h, 
 (*theMenu)->menuWidth - wMgrPort->portRect.right + 
 FRAMEH, 1 - FRAMEH), 
  pin(MENUV + POINTERV - hitPt->v, 
   MENUV + (*theMenu)->menuHeight - wMgrPort->portRect.bottom + 
 FRAMEV, 1 - FRAMEV));

 /* clip to save the screen */
 ClipRect(&wMgrPort->portRect);

 /* save the screen */
 CopyBits(&wMgrPort->portBits, menuBits, 
 &menuBits->bounds, &menuBits->bounds, 0, 0L);

 /* erase and frame the menu rectangle */
 InsetRect(&menuRect, FRAMEH, FRAMEV);
 EraseRect(&menuRect);
 InsetRect(&menuRect, -1, -1);
 FrameRect(&menuRect);
 InsetRect(&menuRect, 1, 1);

 /* add shadow */
 PenNormal();
 MoveTo(menuRect.left + 1, menuRect.bottom + 1);
 Line((*theMenu)->menuWidth, 0);
 Line(0, - (*theMenu)->menuHeight);

 /* clip for the standard menu definition procedure */
 ClipRect(&menuRect);

 /* prepare to call the standard menu definition procedure */
 LoadResource((*theMenu)->menuProc);
 HLock((*theMenu)->menuProc);

 /* draw the menu */
 whichItem = 0;
 SetPt(hitPt, 0, 0);
 MenuDefProc(mDrawMsg, theMenu, &menuRect, hitPt, &whichItem);

 /* track the mouse until the button is released */
 do
 {
 MenuDefProc(mChooseMsg, theMenu, &menuRect, hitPt, &whichItem);
 GetMouse(hitPt);
 }
 while (WaitMouseUp());

 /* blink the item */
 if (whichItem)
 {
 for (blink = GETSYSPPTR->Misc >> 2 & 0x3; blink; blink--)
 {
 nilPt = 0L;
 MenuDefProc(mChooseMsg, theMenu, &menuRect, &nilPt,&whichItem);
 nilPt = Delay(DELAY);    /* Inside Mac and Consulair C differ here */
 menudefproc(mChooseMsg, theMenu, &menuRect, hitPt, &whichItem);
 nilPt = Delay(DELAY);    /* Inside Mac and Consulair C differ here */
 }
 }

 /* done calling the standard menu definition procedure */
 HUnlock((*theMenu)->menuProc);

 /* clip to restore screen */
 ClipRect(&wMgrPort->portRect);

 /* restore the screen and clean up */
 CopyBits(menuBits, &wMgrPort->portBits, 
 &menuBits->bounds, &menuBits->bounds, 0, 0L);
 HUnlock(theMenuBits);
 DisposHandle(theMenuBits);

 /* restore the window manager port origin and the current graf port 
*/
 SetOrigin(0, 0);
 ClipRect(&wMgrPort->portRect);
 SetPort(port);

 /* return the standard result */
 return whichItem ? ((int32) (*theMenu)->menuID << 16) + whichItem : 
0L;
 }

/*
 * Pop-up Menu Example
 */

#include "quickdraw.h"
#include "menu.h"
#include "events.h"

extern long PopUpSelect();

main()
 {
 MenuHandle menu;
 EventRecord event;
 GrafPtr port;
 Rect box;

 /* initialize the managers */
 /* InitGraf(&thePort); *//* Consulair does this for us */
 /* InitFonts(); */
 /* InitWindows(); */
 InitMenus();
 TEInit();
 InitDialogs(0L);
 InitCursor();

 /* draw the icon */
 GetWMgrPort(&port);
 SetPort(port);
 ClipRect(&port->portRect);
 SetRect(&box, 32, 32, 64, 64);
 PlotIcon(&box, GetIcon(0));

 /* initialize the popup menu */
 menu = NewMenu(1, "");
 AppendMenu(menu, "\pBeep;(-;Quit"); /* \p for pascal string */

 /* handle mouse down events */
 while (1)
 {
 GetNextEvent(everyEvent, &event);
 if (event.what == mouseDown)
 if (PtInRect(&event.where, &box))
 switch (LoWord(PopUpSelect(menu, &event.where)))
 {
 case 1:
 SysBeep(4);
 break;
 case 3:
 ExitToShell();
 break;
 }
 }
 }

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Duplicate Annihilator 5.7.5 - 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
BusyContacts 1.0.2 - Fast, efficient con...
BusyContacts is a contact manager for OS X that makes creating, finding, and managing contacts faster and more efficient. It brings to contact management the same power, flexibility, and sharing... Read more
Capture One Pro 8.2.0.82 - RAW workflow...
Capture One Pro 8 is a professional RAW converter offering you ultimate image quality with accurate colors and incredible detail from more than 300 high-end cameras -- straight out of the box. It... Read more
Backblaze 4.0.0.872 - Online backup serv...
Backblaze is an online backup service designed from the ground-up for the Mac.With unlimited storage available for $5 per month, as well as a free 15-day trial, peace of mind is within reach with... Read more
Little Snitch 3.5.2 - Alerts you about o...
Little Snitch gives you control over your private outgoing data. Track background activity As soon as your computer connects to the Internet, applications often have permission to send any... Read more
Monolingual 1.6.4 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. If you use your computer in only one (human) language, you... Read more
CleanApp 5.0 - Application deinstaller a...
CleanApp is an application deinstaller and archiver.... Your hard drive gets fuller day by day, but do you know why? CleanApp 5 provides you with insights how to reclaim disk space. There are... Read more
Fantastical 2.0 - Create calendar events...
Fantastical is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event details... Read more
Cocktail 8.2 - General maintenance and o...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
Direct Mail 4.0.4 - Create and send grea...
Direct Mail is an easy-to-use, fully-featured email marketing app purpose-built for OS X. It lets you create and send great looking email campaigns. Start your newsletter by selecting from a gallery... Read more

Appy to Have Known You - Lee Hamlet Look...
Being at 148Apps these past 2 years has been an awesome experience that has taught me a great deal, and working with such a great team has been a privilege. Thank you to Rob Rich, and to both Rob LeFebvre and Jeff Scott before him, for helping me... | Read more »
MLB Manager 2015 (Games)
MLB Manager 2015 5.0.14 Device: iOS Universal Category: Games Price: $4.99, Version: 5.0.14 (iTunes) Description: Guide your favorite MLB franchise to glory! MLB Manager 2015, officially licensed by MLB.com and based on the award-... | Read more »
Breath of Light (Games)
Breath of Light 1.0.1421 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.1421 (iTunes) Description: Hold a quiet moment. Breath of Light is a meditative and beautiful puzzle game with a hypnotic soundtrack by... | Read more »
WWE WrestleMania Tags into the App Store
Are You ready to rumble? The official WWE WrestleMania app, by World Wrestling Entertainment, is now available. Now you can get all your WrestleMania info in one place before anyone else. The app offers details on superstar signings, interactive... | Read more »
Bio Inc's New Expansion is Infectin...
Bio Inc., by DryGin Studios, is the real time strategy game where you infect a human body with the worst virus your evil brain can design. Recently, the game was updated to add a whole lot of new features. Now you can play the new “Lethal”... | Read more »
The Monocular Minion is Here! Despicable...
Despicable Me: Minion Rush, by Gameloft, is introducing a new runner to the mix in their latest update. Now you can play as Carl, the prankster minion. Carl has a few new abilities to play with, including running at a higher speed from the start.... | Read more »
Dungeon of Madness (Games)
Dungeon of Madness 1.0.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0.0 (iTunes) Description: Dungeon of Madness is an action game where you rotate tiles to create our own route. Help the hero by connecting the... | Read more »
Filters for iPhone (Photography)
Filters for iPhone 1.0 Device: iOS iPhone Category: Photography Price: $.99, Version: 1.0 (iTunes) Description: | Read more »
Jump'N'Shoot Attack (Games)
Jump'N'Shoot Attack 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: A mobile game for gamers! Join Louise Lightfoot, the legendary "Master of Jumping and Shooting", on her mission to save... | Read more »
Space Bounties Inc. (Games)
Space Bounties Inc. 1.4 Device: iOS Universal Category: Games Price: $1.99, Version: 1.4 (iTunes) Description: SuperGameDroid: 4/5 "Satisfying futuristic RPG combat, high replay value, and a heavy dose of nostalgia make Space... | Read more »

Price Scanner via MacPrices.net

13-inch 2.5GHz MacBook Pro (refurbished) avai...
The Apple Store has Apple Certified Refurbished 13″ 2.5GHz MacBook Pros available for $829, or $270 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.... Read more
Save up to $80 on iPad Air 2s, NY tax only, f...
 B&H Photo has iPad Air 2s on sale for $80 off MSRP including free shipping plus NY sales tax only: - 16GB iPad Air 2 WiFi: $469.99 $30 off - 64GB iPad Air 2 WiFi: $549.99 $50 off - 128GB iPad... Read more
iMacs on sale for up to $205 off MSRP
B&H Photo has 21″ and 27″ iMacs on sale for up to $205 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $1019 $80 off - 21″ 2.7GHz iMac: $1189 $110 off - 21″ 2.9GHz... Read more
Färbe Technik Offers iPhone Battery Charge LI...
Färbe Technik, which manufactures and markets of mobile accessories for Apple, Blackberry and Samsung mobile devices, is offering tips on how to keep your iPhone charged while in the field: •... Read more
Electronic Recyclers International CEO Urges...
Citing a recent story on CNBC about concerns some security professionals have about the forthcoming Apple Watch, John Shegerian, Chairman and CEO of Electronic Recyclers International (ERI), the... Read more
Save up to $380 with Apple refurbished iMacs
The Apple Store has Apple Certified Refurbished iMacs available for up to $380 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 27″ 3.5GHz 5K iMac – $2119 $... Read more
Mac minis on sale for up to $75 off, starting...
MacMall has Mac minis on sale for up to $75 off MSRP including free shipping. Their prices are the lowest available for these models from any reseller: - 1.4GHz Mac mini: $459.99 $40 off - 2.6GHz Mac... Read more
College Student Deals: Additional $50 off Mac...
Take an additional $50 off all MacBooks and iMacs at Best Buy Online with their College Students Deals Savings, valid through April 11, 2015. Anyone with a valid .EDU email address can take advantage... Read more
Mac Pros on sale for up to $260 off MSRP
B&H Photo has Mac Pros on sale for up to $260 off MSRP. Shipping is free, and B&H charges sales tax in NY only: - 3.7GHz 4-core Mac Pro: $2799, $200 off MSRP - 3.5GHz 6-core Mac Pro: $3719.99... 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 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
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
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
Lead *Apple* Solutions Consultant - Retail...
**Job Summary** Job Summary The Lead ASC is an Apple employee who serves as the Apple business manager and influencer in a hyper-business critical Reseller's store Read more
*Apple* Pay - Site Reliability Engineer - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring 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.