TweetFollow Us on Twitter

Mouse in MacApp
Volume Number:6
Issue Number:12
Column Tag:Jörg's Folder

Related Info: Event Manager

MacApp-Tracking the Mouse

By Jörg Langowski, MacTutor Editorial Board

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

As promised, I will show you this month how to add code that handles mouse tracking to our last example. In the code as it was given in V6#11, we had no explicit mouse tracking routine defined; in that case MacApp uses the default routine, which simply draws the rectangle defined by the mouse starting point and the current mouse position. For dragging an object, this default behavior is quite inconvenient, because you don’t see the exact outline of the object being dragged and can’t position it exactly where you want it.

We would like dragged objects to behave like they do in MacDraw, where an outline of the object follows the mouse. How can one implement this?

All the changes we have do to are to the TDragger class. Specifically, we need to define a TrackFeedback method in this class. This method is called by MacApp’s TApplication.TrackMouse routine while it tracks the mouse. You may draw some shape here, which is then ‘dragged around’ with the mouse: TrackMouse will set the pen to patXOR mode before any calls to the feedback routine. When you move the mouse, the shape is first redrawn at the old position (erasing it that way), then drawn at the new position. All this is handled automatically by TrackMouse; you only need to provide the drawing routine.

So all we would have to do is write a TrackFeedback method that draws the shape at the current mouse position, maybe like this:

/* 1 */

pascal void TDragger::TrackFeedback(VPoint *anchorPoint,
 VPoint *nextPoint, Boolean turnItOn, Boolean mouseDidMove)
{
 Point  delta;

 if (mouseDidMove) {
 delta = fTextView->ViewToQDPt(nextPoint);
 SubPt(fTextView->ViewToQDPt(previousPoint), &delta);
 OffsetRect(&fBox->fLocation,delta.h,delta.v);
 fBox->DrawShape();
 }
}

In the call to the routine, anchorPoint and nextPoint are the starting point of the mouse drag and the current mouse position. mouseDidMove is true when the mouse actually did move since the last call to this routine; and turnItOn is a variable that controls whether feedback should be turned on or off; we don’t use it. To draw the shape at the new mouse position, we calculate the difference between the two coordinates (SubPt) and offset the shape rectangle accordingly; then we draw the shape.

This method should work without problems when you add it to last month’s example (try it, and don’t forget to include the method in the class definition in the header file). Since we change the location rectangle of fBox as we go, we may even simplify the code that changes oldLocation and newLocation at the end of the TDragger.TrackMouse routine; fBox->fLocation is already at its final value when the mouse is released.

However, I would like to show you a different way to do the feedback which can later be used in a much more general way, for instance if we want to drag an outline of a group of different shapes, change the aspect of the shape being dragged around, etc. The principle is taken from an example in the excellent book Programming with MacApp by David Wilson, Larry Rosenstein, and Dan Shafer (Addison-Wesley). We call the routines that we want to use for drawing the shape(s) to be dragged only once, when the mouse is first clicked or at its first movement. At that point, we create a picture, calling all the drawing routines, and store its handle in an instance variable. The TrackFeedback routine will then take this picture handle and call DrawPicture with it.

Creation of the picture, and destruction when we’re done with the dragging, is handled by the TrackMouse routine. When this routine is called, one parameter indicated what track phase we are in: whether the mouse button was just pressed (trackPress), is being held down (trackMove), or has just been released (trackRelease).

The track phase tells us what to do (see listing): when we are in trackPress, we create the picture and save its handle; when we are in trackMove, we offset the picture’s bounds rectangle by the distance the mouse has traveled; finally, in trackRelease, we change the shape’s coordinates to the mouse position and dispose of the picture. If we find out that the shape has not been moved at all out of its old position, we return gNoChanges.

Note that the mouse tracking routine does not do any drawing at all; drawing the dragged shape is done by the TrackFeedback routine, and the final draw of the shape at its new position is of course done when the window is updated automatically. Another point to remember is that you have to set the pen state to PenNormal and patXor when you create the picture (see listing). The current pen state is part of the picture information, so when the picture is created, that pen state will be remembered. The pen state in the TrackMouse routine in the trackPress phase is not the one we want; if you don’t set it to patXor yourself, it will be patCopy (I guess) when the picture is drawn by the feedback routine. That means you will create copies of your shape all over the screen when you drag it. Try it out.

Final words

This was a short Christmas column; next time will be longer, because we’ll add code for different shapes and for dragging a selection of shapes. Also, it might be that my test copy of MacFortran II comes in until then, so that we can finally see those comprehensive benchmarks. Absoft, I want my M F Two...

Listing 1: Changes to the V6#9 example to support track feedback

// Dragging support with custom mouse track feedback
// © JL/MT 10/90
pascal void 
 TDragger::IDragger(TBox *itsBox, 
 TTEDocument *itsDocument, TTextView *itsView)
{
 TScroller *aScroller;

 aScroller = itsView->GetScroller(true);
 ICommand(cDragBox, itsDocument, itsView, aScroller);
 fTEDocument = itsDocument;
 fTextView = itsView;
 fBox = itsBox;
 oldLocation = fBox->fLocation;
 newLocation = fBox->fLocation;
}

pascal struct TCommand 
 *TDragger::TrackMouse(TrackPhase aTrackPhase,
 VPoint *anchorPoint, VPoint *previousPoint, 
 VPoint *nextPoint, Boolean mouseDidMove)
{
 Point  delta;
 Rect   r;
 RgnHandleoldClip;
 PenState oldState;
 
 if (aTrackPhase == trackPress) {
 r = fBox->fLocation;
 oldClip = MakeNewRgn();  // MacApp routine
 
// get the old environment for later restore
 GetClip(oldClip);
 GetPenState(&oldState);
// and open a new picture
 fFeedbackPicture = OpenPicture(&r);
 FailNIL(fFeedbackPicture); // be safe
 ClipRect(&r);
// the following lines ARE necessary since the picture 
// remembers the pen state that was in effect when this 
// routine was called.
// Since we are in trackPress, the pen has NOT yet been 
// set to patXOR. Comment out the next two lines, 
// you’ll see interesting effects -- JL
 PenNormal();
 PenMode(patXor);
// draw the shape
 fBox->DrawShape();
 ClosePicture();
 fPictureBounds = r;

// restore old environment
 SetClip(oldClip);
 DisposeRgn(oldClip);
 SetPenState(&oldState);
 
 if (EmptyRect(&(*fFeedbackPicture)->picFrame)) {
 KillPicture(fFeedbackPicture);
 fFeedbackPicture = nil;
 FailNIL(fFeedbackPicture);
 }
 }

 if ((aTrackPhase == trackMove) && mouseDidMove) {
 delta = fTextView->ViewToQDPt(nextPoint);
 SubPt(fTextView->ViewToQDPt(previousPoint), &delta);
// we don’t actually move the shape here, only its picture.
// the move is done in the last phase
 OffsetRect(&fPictureBounds,delta.h,delta.v);
 }

 if ((aTrackPhase == trackRelease) && mouseDidMove) {
 if (fFeedbackPicture != nil)  {
// being paranoid: normally we should never get here if the 
// picture couldn’t be created, but who knows
 KillPicture(fFeedbackPicture);
 fFeedbackPicture = nil; }

 delta = fTextView->ViewToQDPt(nextPoint);
 SubPt(fTextView->ViewToQDPt(anchorPoint), &delta);
 newLocation = oldLocation;
 if ((delta.h == 0) && (delta.v == 0))
 { return gNoChanges;}
// if we get here, something has been changed. 
// move the shape to its new location
 OffsetRect(&newLocation,delta.h,delta.v);
 fBox->fLocation = newLocation;    
 }
 return this;
}

pascal void 
 TDragger::TrackFeedback(VPoint *anchorPoint, 
 VPoint *nextPoint,
 Boolean turnItOn, Boolean mouseDidMove)
{
 Rect r;
 
 if (mouseDidMove && (fFeedbackPicture != nil)) {
 r = fPictureBounds;
 DrawPicture(fFeedbackPicture,&r); // that’s all!! 
 }
}

pascal void TDragger::DoIt()
{
 fTextView->InvalidRect(&newLocation);
 fTextView->InvalidRect(&oldLocation);
}

pascal void TDragger::RedoIt()  
{  
 fBox->fLocation = newLocation;
 DoIt(); 
}

pascal void TDragger::UndoIt()
{
 fBox->fLocation = oldLocation;
 DoIt(); 
}

#ifdef qDebug
pascal void TDragger::Fields(pascal void (*DoToField) 
 (StringPtr fieldName, Ptr fieldAddr, short fieldType, 
 void *link), void *link)
{
 DoToField(“\pTDragger”, nil, bClass, link);
 DoToField(“\pfTEDocument”, 
 (Ptr) &fTEDocument, bObject, link);
 DoToField(“\pfTextView”, 
 (Ptr) &fTextView, bObject, link);
 DoToField(“\pfBox”, (Ptr) &fBox, bObject, link);
 DoToField(“\poldLocation”, 
 (Ptr) &oldLocation, bRect, link);
 DoToField(“\pnewLocation”, 
 (Ptr) &newLocation, bRect, link);
 DoToField(“\pfFeedbackPicture”, 
 (Ptr) &fFeedbackPicture, bHandle, link);
 DoToField(“\pfPictureBounds”, 
 (Ptr) &fPictureBounds, bRect, link);
 inherited::Fields(DoToField, link);
}
#endif

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

FoldersSynchronizer 4.2.1 - Synchronize...
FoldersSynchronizer is a popular and useful utility that synchronizes and backs-up files, folders, disks and boot disks. On each session you can apply special options like Timers, Multiple Folders,... Read more
Simon 4.0.2 - 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
Cocktail 8.1.2 - General maintenance and...
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
Cyberduck 4.6.4 - FTP and SFTP browser....
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Herald 5.0.2 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
DEVONthink Pro 2.8.3 - Knowledge base, i...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
Boom 2 1.0.1 - System-wide pro audio app...
Boom 2 is a system-wide volume booster and equalizer app that is designed especially for OS X 10.10 Yosemite. It comes with a smart interface, self-calibrates itself according to your Mac, offers... Read more
Apple Security Update 2015-001 - For OS...
Apple Security Update 2015-001 is recommended for all users and improves the security of OS X. For detailed information about the security content of this update, please visit: http://support.apple.... Read more
Drive Genius 4.0.1 - Powerful system uti...
Drive Genius 4 gives you faster performance from your Mac while also protecting it. The award-winning and improved DrivePulse feature alerts you to hard drive issues before they become major problems... Read more
Yosemite Cache Cleaner 9.0.3 - Clear cac...
Yosemite Cache Cleaner is an award-winning general purpose tool for OS X. YCC makes system maintenance simple with an easy point-and-click interface to many OS X functions. Novice and expert users... Read more

Unlock Sunshine Girl in Ironkill with th...
Unlock Sunshine Girl in Ironkill with this special 148Apps code Posted by Rob Rich on January 29th, 2015 [ permalink ] Robo-fighter Ironkill has been out on iOS a | Read more »
Crossroad Zombies Review
Crossroad Zombies Review By Jordan Minor on January 29th, 2015 Our Rating: :: CROSSWALKING DEADiPad Only App - Designed for the iPad Crossroad Zombies is a rough draft of a cool genre mash-up.   | Read more »
Blood Brothers 2 – Tips, Cheats, and Str...
War is hell: Is it the kind of hell you want to check out? Read our Blood Brothers 2 review to find out! Blood Brothers 2, DeNA’s follow-up to the original Blood Brothers, is an intriguing card collecting / role-playing / strategy hybrid. There’s... | Read more »
Blood Brothers 2 Review
Blood Brothers 2 Review By Nadia Oxford on January 29th, 2015 Our Rating: :: AN AGGRAVATING RELATIVEUniversal App - Designed for iPhone and iPad Blood Brothers 2 is built on a simple, solid foundation, but its free-to-play system... | Read more »
I AM BREAD, the Toast of the Town, is Ro...
Have you ever dreamt of being deliciously gluten-y? Do you feel passionate about Rye and Wheat? The guys at Bossa Studios do and that is why they are bringing I AM BREAD to iOS soon. The loafy app will feature all the new content that is being... | Read more »
Fahrenheit: Indigo Prophecy Remastered R...
Fahrenheit: Indigo Prophecy Remastered Review By Jennifer Allen on January 29th, 2015 Our Rating: Universal App - Designed for iPhone and iPad 10 years after its initial release and Fahrenheit: Indigo Prophecy still feels like a... | Read more »
Evolve: Hunters Quest is a Match-3 That...
Evolve: Hunters Quest is a Match-3 That Has You Hunting Up Some Big Game. Posted by Jessica Fisher on January 29th, 2015 [ permalink ] | Read more »
Destructamundo Review
Destructamundo Review By Jordan Minor on January 29th, 2015 Our Rating: :: WRECKING CREWUniversal App - Designed for iPhone and iPad Destructamundo blows up real good.   | Read more »
The Sandbox Gets Exclusive Update, Adds...
The Sandbox Gets Exclusive Update, Adds Invincible Characters Campagin Posted by Tre Lawrence on January 29th, 2015 [ permalink ] | Read more »
Mean Girls: The Game Review
Mean Girls: The Game Review By Jordan Minor on January 29th, 2015 Our Rating: :: FETCHUniversal App - Designed for iPhone and iPad A Mean Girls tower defense game makes way more sense than you’d think.   | Read more »

Price Scanner via MacPrices.net

Back in stock: Refurbished iPod nanos for $99...
The Apple Store has Apple Certified Refurbished 16GB iPod nanos available for $99 including free shipping and Apple’s standard one-year warranty. That’s $50 off the cost of new nanos. Most colors are... Read more
New Good Management Suite Simplifies Enterpri...
Good Technology has announced the availability of the Good Management Suite, a comprehensive cross-platform solution for organizations getting started with mobile business initiatives. Built on the... Read more
15-inch 2.0GHz Retina MacBook Pro (refurbishe...
The Apple Store has Apple Certified Refurbished previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1489 including free shipping plus Apple’s standard one-year warranty. Their price is... Read more
15-inch 2.5GHz Retina MacBook Pro on sale for...
Amazon has the 15″ 2.5GHz Retina MacBook Pro on sale for $2319.99 including free shipping. Their price is $180 off MSRP, and it’s the lowest price available for this model from any reseller. Read more
iPad Turns Five – The ”Book Mystique
Five years ago this week, the late Steve Jobs took the stage at an Apple special press event to unveil the first Apple iPad — a slab-shaped, hand-holdable device that was to shake the personal... 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 $150 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1889.99... Read more
Apple refurbished Mac minis for up to $150 of...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
Apple Releases New Tranche Of OS Updates For...
Apple has released incremental bugfix and security updates for its most recent Mac and iOS versions. OS X Yosemite 10.10.2 Update Apple says this update includes the following improvements: Resolves... Read more
Samsung To Be Main Supplier Of A9 Chips For i...
Korea’s Maeil Business Newspaper reports that Samsung has beat out its chipmaking rivals, Taiwan’s Qualcomm and TSMC, as supplier of chipsets for the next generations of both its own Galaxy S6 and... Read more
Save up to $340 on iMacs with Apple Certified...
The Apple Store has Apple Certified Refurbished iMacs available for up to $340 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. These are the best prices on... Read more

Jobs Board

SW QA Engineer - *Apple* TV - Apple (United...
**Job Summary** The Apple TV team is looking for experienced Quality Assurance Engineers with a passion for delivering first in class home entertainment solutions. **Key Read more
*Apple* Retail - Multiple Positions(US) - Ap...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you re also the Read more
*Apple* Systems Engineer - Pre Sales, Educat...
…is responsible for proactively providing technical expertise to drive sales of Apple solutions into assigned accounts. The SE architects, validates, and assists in Read more
*Apple* Solutions Consultant - Retail Sales...
As an ambassador of the Apple brand, the ASC is accountable for driving sales performance by: Connecting with customers. Discovering customers' needs and values. Showing Read more
*Apple* Solutions Consultant - Retail Sales...
As an ambassador of the Apple brand, the ASC is accountable for driving sales performance by: Connecting with customers. Discovering customers' needs and values. Showing Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.