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

Vivaldi 1.7.735.46 - An advanced browser...
Vivaldi is a browser for our friends. In 1994, two programmers started working on a web browser. Our idea was to make a really fast browser, capable of running on limited hardware, keeping in mind... Read more
HandBrake 1.0.3 - Versatile video encode...
HandBrake is a tool for converting video from nearly any format to a selection of modern, widely supported codecs. Features Supported Sources VIDEO_TS folder, DVD image or real DVD (unencrypted... Read more
Slack 2.5.1 - Collaborative communicatio...
Slack is a collaborative communication app that simplifies real-time messaging, archiving, and search for modern working teams. Version 2.5.1: New The way we load teams you don't view often has been... Read more
BBEdit 11.6.4 - Powerful text and HTML e...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
BBEdit 11.6.4 - Powerful text and HTML e...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
beaTunes 4.6.12 - Organize your music co...
beaTunes is a full-featured music player and organizational tool for music collections. How well organized is your music Library? Are your artists always spelled the same way? Any R.E.M. vs REM?... Read more
Tinderbox 7.0.1 - Store and organize you...
Tinderbox is a personal content management assistant. It stores your notes, ideas, and plans. It can help you organize and understand them. And Tinderbox helps you share ideas through Web journals... Read more
FotoMagico 5.4 - Powerful slideshow crea...
FotoMagico lets you create professional slideshows from your photos and music with just a few, simple mouse clicks. It sports a very clean and intuitive yet powerful user interface. High image... Read more
Direct Mail 4.3.9 - 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
Tinderbox 7.0.1 - Store and organize you...
Tinderbox is a personal content management assistant. It stores your notes, ideas, and plans. It can help you organize and understand them. And Tinderbox helps you share ideas through Web journals... Read more

The best sales on the App Store this wee...
The App Store has quite an exciting lineup of discount games this week that range across a variety of genres. It's a great opportunity to catch up on some of the premium games you may have been holding off on -- and some you can even grab for free... | Read more »
The best new games we played this week
Ah, here we are again at the close of another busy week. Don't rest too easy, though. We had a lot of great new releases in mobile games this week, and now you're going to have to spend all weekend playing them. That shouldn't be too much of a... | Read more »
Rollercoaster Tycoon Touch Guide: How to...
| Read more »
Rabbids Crazy Rush Guide: How to unlock...
The Rabbids are back in a new endless running adventure, Rabbids Crazy Rush. It's more ridiculous cartoon craziness as you help the little furballs gather enough fuel (soda) to get to the moon. Sure, it's a silly idea, but everyone has dreams --... | Read more »
Tavern Guardians (Games)
Tavern Guardians 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Tavern Guardians is a Hack-and-Slash action game played in the style of a match-three. You can experience high pace action... | Read more »
Slay your way to glory in idle RPG Endle...
It’s a golden age for idle games on the mobile market, and those addictive little clickers have a new best friend. South Korean developer Ekkorr released Endless Frontier last year, and players have been idling away the hours in the company of its... | Read more »
Tiny Striker: World Football Guide - How...
| Read more »
Good news everyone! Futurama: Worlds of...
Futurama is finding a new home on mobile in TinyCo and Fox Interactive's new game, Futurama: Worlds of Tomorrow. They're really doing it up, bringing on board Futurama creator Matt Groening along with the original cast and writers. TinyCo wants... | Read more »
MUL.MASH.TAB.BA.GAL.GAL (Games)
MUL.MASH.TAB.BA.GAL.GAL 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: ENDLESS UPGRADES. CONSTANT DANGER. ANCIENT WISDOM. BOUNCY BALLS. Launch Sale, 40% OFF for a very limited time!!! MUL.... | Read more »
Dungeon Rushers (Games)
Dungeon Rushers 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Dungeon Rushers is a 2D tactical RPG combining dungeon crawler’s gameplay and turn based fights. Manage your team, loot dusty... | Read more »

Price Scanner via MacPrices.net

12-inch 1.2GHz Retina MacBooks on sale for $2...
Newegg has the 12″ 1.2GHz Space Gray Retina MacBook (sku MLH82LL/A) on sale for $1349.99 including free shipping. Their price is $250 off MSRP, and it’s the lowest price available for this model.... Read more
13-inch MacBook Airs on sale for $100 off MSR...
B&H Photo has 13″ MacBook Airs on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 1.6GHz/128GB MacBook Air (MMGF2LL/A): $899 $100 off MSRP - 13″ 1.6GHz/... Read more
9-inch 32GB Silver iPad Pro on sale for $549,...
B&H Photo has the 9.7″ 32GB Silver Apple iPad Pro on sale for $549 for a limited time. Shipping is free, and B&H charges NY sales tax only. Their price is $50 off standard MSRP for this model... Read more
13-inch 2.0GHz Apple MacBook Pros on sale for...
B&H has the non-Touch Bar 13″ 2.0GHz MacBook Pros in stock today and on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 2.0GHz MacBook Pro Space Gray (... Read more
15-inch Touch Bar MacBook Pros on sale for up...
B&H Photo has the new 2016 15″ Apple Touch Bar MacBook Pros in stock today and on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.7GHz Touch Bar... Read more
12-inch Retina MacBooks on sale for $1150, $1...
B&H has 12″ 1.1GHz Retina MacBooks on sale for $150 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 12″ 1.1GHz Space Gray Retina MacBook: $1149 $150 off MSRP - 12″ 1.1GHz... Read more
Apple restocks refurbished 11-inch MacBook Ai...
Apple has Certified Refurbished 11″ MacBook Airs (the latest models recently discontinued by Apple), available for up to $170 off original MSRP. An Apple one-year warranty is included with each... Read more
Apple Park Opens to Employees in April With T...
Apple has announced that Apple Park, the company’s new 175-acre campus, will be ready for employees to begin occupying in April. The process of moving more than 12,000 people will take over six... Read more
Manhattan Neighbors for Safer Telecommunicati...
A new education and advocacy group focused on cell phone and wireless risks, Manhattan Neighbors for Safer Telecommunications, launched today at http://www.ManhattanNeighbors.org. Manhattan... Read more
Portable Dual DisplayPort Monitor Dock Enable...
IOGEAR has announced the launch of its USB-C Dual DisplayPort Monitor Portable Dock (GUC3CMST). The dock enables users to easily connect two DisplayPort monitors to a USB-C or Thunderbolt 3 laptop to... Read more

Jobs Board

*Apple* Wireless Lead - T-ROC - The Retail O...
…of knowledge in wireless sales and activations to the Beautiful and NEW APPLE Experiencestore within MACYS. THIS role, APPLE Wireless Lead, isbrandnewas MACYS Read more
Manager *Apple* Systems Administration - Pu...
Req ID 3315BR Position Title Manager, Apple Systems Administration Job Description The Manager of Apple Systems Administration oversees the administration and 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
*Apple* Retail - Multiple Positions- Chicago...
SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Manager *Apple* Systems Administration - Pu...
Req ID 3315BR Position Title Manager, Apple Systems Administration Job Description The Manager of Apple Systems Administration oversees the administration and Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.