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

OmniGraffle Pro 7.4.3 - Create diagrams,...
OmniGraffle Pro helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use... Read more
OmniGraffle 7.4.3 - Create diagrams, flo...
OmniGraffle helps you draw beautiful diagrams, family trees, flow charts, org charts, layouts, and (mathematically speaking) any other directed or non-directed graphs. We've had people use Graffle to... Read more
VueScan 9.5.86 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
ExpanDrive 6.1.0 - Access cloud storage...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more
Yojimbo 4.1 - Data information organizer...
Yojimbo empowers Mac users to manage, effortlessly and securely, the onslaught of information encountered every day at work and at home, even across multiple computers. Yojimbo stores different data... Read more
Airmail 3.5 - Powerful, minimal email cl...
Airmail is an mail client with fast performance and intuitive interaction. Support for iCloud, MS Exchange, Gmail, Google Apps, IMAP, POP3, Yahoo!, AOL, Outlook.com, Live.com. Airmail was designed... Read more
Cocktail 11.0 - General maintenance and...
Cocktail is a general purpose utility for macOS 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
Numi 3.17.2 - Menu-bar calculator suppor...
Numi is a calculator that magically combines calculations with text, and allows you to freely share your computations. Numi combines text editor and calculator Support plain English. For example, '5... Read more
ScreenFlow 7.1 - Create screen recording...
ScreenFlow is powerful, easy-to-use screencasting software for the Mac. With ScreenFlow you can record the contents of your entire monitor while also capturing your video camera, microphone and your... Read more
Little Snitch 4.0.3 - 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

The best visual novels on mobile
Narrative games have been around for ages, but only now have they been creeping into the mainstream spotlight. These games tell some of the industry's finest stories, and they break new ground in terms of gameplay and mechanics regularly. Here are... | Read more »
The best new games we played this week -...
It's pretty much been one big release after another. We were privy to a bunch of surprises this week, with a lot of games we'd been waiting for quite some time dropping unexpectedly. We hope you're free this weekend, because there is a lot for... | Read more »
Stormbound: Kingdom Wars guide - how to...
Stormbound: Kingdom Wars is an excellent new RTS turned card battler out now on iOS and Android. Lovers of strategy will get a lot of enjoyment out of Stormbound's chess-like mechanics, and it's cardbased units are perfect for anyone who loves the... | Read more »
The best AR apps and games on iOS right...
iOS 11 has officially launched, and with it comes Apple's ARKit, a helpful framework that makes it easier than ever for developers to create mobile AR experiences. To celebrate the occassion, we're featuring some of the best AR apps and games on... | Read more »
Phoenix Wright: Ace Attorney - Spirit of...
Phoenix Wright: Ace Attorney - Spirit of Justice 1.00.00 Device: iOS Universal Category: Games Price: $.99, Version: 1.00.00 (iTunes) Description: ************************************************※IMPORTANT※・Please read the “When... | Read more »
Kpressor (Utilities)
Kpressor 1.0.0 Device: iOS Universal Category: Utilities Price: $4.99, Version: 1.0.0 (iTunes) Description: The ultimate ZIP compression application for iPhone and iPad. - Full integration of iOS 11 with support for multitasking.-... | Read more »
Find out how you can save £35 and win a...
Nothing raises excitement like a good competition, and we’re thrilled to announce our latest contest. We’ll be sending one lucky reader and a friend to the Summoners War World Arena Championship at Le Comedia in Paris on October 7th. It’s the... | Read more »
Another Lost Phone: Laura's Story...
Another Lost Phone: Laura's Story 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Another Lost Phone is a game about exploring the social life of a young woman whose phone you have just... | Read more »
The Witness (Games)
The Witness 1.0 Device: iOS Universal Category: Games Price: $9.99, Version: 1.0 (iTunes) Description: You wake up, alone, on a strange island full of puzzles that will challenge and surprise you. You don't remember who you are, and... | Read more »
Egg, Inc. guide - how to build your gold...
Egg, Inc.'s been around for some time now, but don't you believe for one second that this quirky clicker game has gone out of style. The game keeps popping up on Reddit and other community forums thanks to the outlandish gameplay (plus, the... | Read more »

Price Scanner via MacPrices.net

Apple Certified Refurbished iPad minis availa...
Apple has Certified Refurbished 128GB iPad minis available today for $339 including free shipping. Apple’s standard one-year warranty is included. Their price is $60 off MSRP. Read more
12-inch 1.2GHz Retina MacBook Pros on sale fo...
B&H Photo has 2017 12″ 1.2GHz Retina MacBooks on sale for $100 off MSRP. Shipping is free, and B&H charges sales tax in NY & NJ only: 12″ 1.2GHz Space Gray MacBook: $1199 $100 off MSRP 12... Read more
Sunday sale: 13-inch 3.1GHz MacBook Pros for...
Amazon has 2017 13″ 3.1GHz MacBook Pros on sale today for up to $150 off MSRP, each including free shipping: – 13″ 3.1GHz/256GB Space Gray MacBook Pro (MPXV2LL/A): $1649.99 $150 off MSRP – 13″ 3.1GHz... Read more
Looking for a 2017 12″ Retina MacBook? Save $...
Apple has Certified Refurbished 2017 12″ Retina MacBooks available for $200-$240 off the cost of new models. Apple will include a standard one-year warranty with each MacBook, and shipping is free.... Read more
Apple Offering Up To $455 Credit Toward iPhon...
iPhone 8 and 8 Plus are now available at the Apple Store, and you can receive up to $375 credit toward a new iPhone purchase when you trade in your eligible smartphone. Photo Courtesy Apple Just... Read more
AnyTrans Offers iOS Users Three Ways For Movi...
iMobie Inc. today announceed AnyTrans v6.0.1, which now can help iOS users move all data to iPhone 8/8 Plus seamlessly. The software is available both on Mac and Windows and fully able to move all... Read more
Snag a 13-inch 2.3GHz MacBook Pro for $100 of...
B&H Photo has 2017 13″ 2.3GHz MacBook Pros in stock today and on sale for $100 off MSRP, each including free shipping plus NY & NJ sales tax only: – 13-inch 2.3GHz/128GB Space Gray MacBook... Read more
Verizon offers new iPhone 8 for $100-$300 off...
Verizon is offering the new iPhone 8 for up to $300 off MSRP with an eligible trade-in: • $300 off: iPhone 6S/6S Plus/7/7 Plus, Google Pixel XL, LG G6, Moto Z2 Force, Samsung Galaxy S7/S7 edge/S8/S8... Read more
Apple Refurbished 2017 13-inch MacBook Pros a...
Apple has Certified Refurbished 2017 13″ Touch Bar MacBook Pros in stock today and available for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is... Read more
OWC USB-C Travel Dock with 5 Ports Connectivi...
OWC have announced the new OWC USB-C Travel Dock, the latest addition to their line of connectivity solutions. The USB-C Travel Dock lets you connect its integrated USB-C cable to a Mac or PC laptop... Read more

Jobs Board

Development Operations and Site Reliability E...
Development Operations and Site Reliability Engineer, Apple Payment Gateway Job Number: 57572631 Santa Clara Valley, California, United States Posted: Jul. 27, 2017 Read more
Development Operations and Site Reliability E...
Development Operations and Site Reliability Engineer, Apple Payment Gateway Job Number: 57572631 Santa Clara Valley, California, United States Posted: Jul. 27, 2017 Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Instructional Designer, *Apple* Product Doc...
Job Summary The Apple Product Documentation team is looking for an instructional designer or a video editor to write user documentation for its professional video Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.