Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Mac Programming / November 2004



Tip: Looking for answers? Try searching our database.

Popup that always sends message

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David Dunham - 14 Nov 2004 06:38 GMT
I've got a popup menu which I always want to hear from (via
ListenToMessage) when it's chosen. Even if the user chooses the
currently-checked item. It looks to me like there's lots of code which
is preventing this from happening.

My first thought was to avoid subclassing by creating an LAttachment,
but there's no way for the attachment to send ClickSelf to make the
tracking happen.

I can subclass (and always send BroadcastValueMessage), but I'm
wondering if there's some way not to.

Signature

David Dunham    A Sharp, LLC
http://www.a-sharp.com/
   "I say we should listen to the customers and give them what they want."
   "What they want is better products for free." --Scott Adams

David Phillip Oster - 15 Nov 2004 04:42 GMT
> I've got a popup menu which I always want to hear from (via
> ListenToMessage) when it's chosen. Even if the user chooses the
[quoted text clipped - 4 lines]
> but there's no way for the attachment to send ClickSelf to make the
> tracking happen.

Sure there is. Read LPane::Click() in LPane.cp. The attachment gets
called with an msg_Click message. If the attachment returns false, the
LPane's ClickSelf() is not called.

ClickSelf is public, so the attachment can call it, THEN broadcast.
Phoenix - 16 Nov 2004 03:32 GMT
Okay, So I am an experienced PowerPlant programmer.  Recently I have
been moving a decent sized gui project over to PPx.  Many of the gui
elements that I am working with (custom panes and views and such)
require mouse tracking in the form of the old LMouseTracker
class/LPane::MouseWithin.  I was going to try to use an PPx::IdleTimer,
essentially copying the behaviour of the LMouseTracker periodical, but
the PPx::IdleTimer does not send a mouse event that I can work with.  I
then discovered PPx::MouseMovedDoer, but I never see the event get
posted (my DoMouseMoved method never gets called).  Other things I have
tried have also proven fruitless. So how do I implement a non-blocking
mouse tracker with PPx?

Thanks,

---Phoenix...
David Phillip Oster - 17 Nov 2004 17:36 GMT
> Okay, So I am an experienced PowerPlant programmer.  Recently I have
> been moving a decent sized gui project over to PPx.  Many of the gui
[quoted text clipped - 7 lines]
> tried have also proven fruitless. So how do I implement a non-blocking
> mouse tracker with PPx?

Mouse down or mouse up? Mouse down tracking loops generally bottom out
on either the system call TrackMouseLocation(),
TrackMouseLocationWithOptions(), or, more rarely, TrackMouseRegion()

for mouse up tracking loops, be sure to read the "Mouse Events" section
of CarbonEvents.h. Note that CarbonEvents.h has changed since the old
"Universal Headers" days, so be sure you are looking at the copy of
CarbonEvents.h inside Carbon.framework (CarbonEvents.h is in
HIToolbox.framework, inside Carbon.framework).

Once you understand what system calls are being called, then you search
the PPx source code and examples to see how connect through the PPx
layer to your code.

Make sure you understand the difference between a

kMouseTrackingMouseDragged and a kMouseTrackingMouseMoved, return values
from the TrackMouseXXX() system calls.

and between a {kEventClassMouse, kEventMouseMoved} and
{kEventClassMouse, kEventMouseDragged} Carbon Event.

Note that some of this changed between OS X 10.1 and OS X 10.2.
Phoenix - 18 Nov 2004 01:51 GMT
Hi there,

Thanks for the response.  I am specifically looking for a way to capture
strictly mouse movement events, with no buttons being pressed.  I have
other things going on in the window (occasionally animation,
occasionally mouse clicks, and other things going on), so I can't call
any routines that block.  From my reading of the TrackMouseXXX() calls,
it appears that these would block until a mouse event occurs.  I will
have to try them to be sure my reading is correct.
So I came across the PPx::MouseMovedDoer mixin class, that should
capture the carbon mouse event(s) {kEventClassMouse, kEventMouseMoved}.
 I wrote a sample window that just displays view that should change
colors when the mouse moves, if the event is captured.  When I set a
breakpoint in my ::DoMouseMoved routine, the routine is never called.
Is there some sort of other setup that I need to do that will let my
view or window capture these events?

I will also mention that I have already successfully moved over much of
the window code to PPx, so I am at least familiar with the paradigm, if
not yet completely up to speed on some of the specifics.

Oh, I also have not been able to find any example code that captures
carbon mouse events (specifically kEventMouseMoved, kEventMouseEntered,
kEventMouseExited).  Do you know of any?

Thanks,

---Phoenix...

>>Okay, So I am an experienced PowerPlant programmer.  Recently I have
>>been moving a decent sized gui project over to PPx.  Many of the gui
[quoted text clipped - 31 lines]
>
> Note that some of this changed between OS X 10.1 and OS X 10.2.
Isaac Wankerl - 18 Nov 2004 03:35 GMT
> Hi there,
>
[quoted text clipped - 20 lines]
> carbon mouse events (specifically kEventMouseMoved, kEventMouseEntered,
> kEventMouseExited).  Do you know of any?

I can send you or post some code for a view that responds to the
MouseEntered and MouseExited events tomorrow.  I'm still looking at an
issue where resizing the view doesn't update the mouse tracking region
correctly in certain situations.  I will also look into the MouseMoved
events.

Signature

Isaac Wankerl
Metrowerks

Isaac Wankerl - 18 Nov 2004 21:50 GMT
> > Hi there,
> >
[quoted text clipped - 26 lines]
> correctly in certain situations.  I will also look into the MouseMoved
> events.

Ok, you can download the code from here:

http://www.iwankerl.com/Software/MouseTrackingView.dmg

Signature

Isaac Wankerl
Metrowerks

David Phillip Oster - 19 Nov 2004 03:59 GMT
> Ok, you can download the code from here:
>
> http://www.iwankerl.com/Software/MouseTrackingView.dmg

Thank you. Great work. It would be nice if Apple documented that it
doesn't send MouseMoved events to an HIView, only to a Window.
Thomas Engelmeier - 21 Nov 2004 13:38 GMT
> Thank you. Great work. It would be nice if Apple documented that  [...]

bugreport.apple.com ?

Regards,
  Tom_E

Signature

This address is valid in its unmodified form but expires soon.

David Phillip Oster - 24 Nov 2004 17:36 GMT
> > Thank you. Great work. It would be nice if Apple documented that  [...]
>
> bugreport.apple.com ?

Sigh.

Dear Apple,

* Please make it easier to file bug reports. After all, you are taking
my valuable time to do your Q/A for you. At least move a template of
your preferred form out where I can see it, instead of inside a login
session with a 30 minute time out, so I'm not continually getting a bug
report filed out only to have your system throw it away because the
session timed out.

* And, since you have my account information already, please use it to
fill out all the machine specific info from my previous reports. I'll
tell you if I change machines.

* Did you read the current AskTog?
<http://www.asktog.com/columns/068priceOfNotListening.html>

* The headers are full of routines like DMSetMainDisplay() which are
documented as "Implemented in OS X", when in fact the implementation
does nothing. You have the source code, you know which routines are
mis-documented. Fix them. Document what the calls actually do in each
version of the O.S. For calls that you are never going to implement,
like DMSetMainDisplay() document that the modern way of doing this is to
use CoreGraphics to move a display to position {0,0}.

* Carbon Events is fill of strange interdepencies and limitations. Mouse
Moved events can only be attached to windows, not HIViews. Installing
some event handlers like ControlClick, cause other event handlers like
MouseDrag to not be called. You've got the source code. Document what is
actually going on, and in which versions of the system the behavior
changed.

* Your own example source code has numerous occurrences of comments that
explain that some bizarre thing is a workaround for an O.S. bug. Search
your own code base and fix the problem, then modify the example code to
only do the bizarre workaround on older systems.

* Too many of the Core Foundation system calls return NULL on error.
Give us a status code so we have some clue about what the call really
wants.

* TXNGetIndexedRunInfoFromRange() DOES return RGBColor text color
information in the ATSUStyle (I know, I looked.), but FontPanel ignores
it (I think this is a bug in 10.3's FontPanel.)

* There is a pause of about a second the first time a FontPanel routine
is called. I tried to workaround this by moving a call to  
CFontPanel::IsFontPanelVisible() early in the program, but then I got
error messages on the console saying that there was no AutoReleasePool.

* As mentioned in the code comments, MLTE grabs keystrokes directly,
without going through the PowerPlant LCommander system, so
SetFontInfoForSelection() is only being called when you click.

* TXNGetChangeCount() and TXNClearChangeCount() do not appear to work
correctly. Use TXNGetActionChangeCount() and TXNClearActionChangeCount()

My complaint is

1.) the strangeness exists

2.) that not only does the strangeness exist, but it isn't documented in
the comments in the header files, Comments provided by Apple as a plcae
to put that strangeness.

3.) Not only does the strangeness exist and isn't documented in the
header file, but it isn't documented in the documentation section of
developer.apple.com instead the developer website is polluted with web
pages that just list the system calls with no links to useful
information. Useless for anything.

4.) Not only is it not documented at developer.apple.com, but now that
Apple's mailing lists are indexed by google, I can tell you that many of
these issues haven't been discussed on Apple's mailing lists

5.) Not only that, but many of these issues haven't been discussed on
ANY source indexed by google, not as web pages nor as newsgroup postings.

Now to spend more than an hour getting Apple's Bug Reporter to accept
the above points.
Phoenix - 19 Nov 2004 04:19 GMT
Thank you, this looks like it is exactly what I needed.  I very much
appreciate your time and help.

---Phoenix...

>>I can send you or post some code for a view that responds to the
>>MouseEntered and MouseExited events tomorrow.  I'm still looking at an
[quoted text clipped - 5 lines]
>
> http://www.iwankerl.com/Software/MouseTrackingView.dmg
David Phillip Oster - 19 Nov 2004 07:45 GMT
> Ok, you can download the code from here:
>
> http://www.iwankerl.com/Software/MouseTrackingView.dmg

I installed your code in my sample app, and while it appears to
work great for MouseMoved events, there was a problem with
MouseDragged events.

It only sees MouseDragged events if I hold the right button of
my 4 button mouse down. The left and center and thumb buttons
are all ignored, and chords of buttons are all ignored.

. . . . . . . .

Ah, I just fixed it while I was writing this: I had a
ControlHitTestDoer mixed in to my view. Once I removed it,
everything worked as expected.

## What this does: is use a multibutton mouse as a multicolored pen.
This is working code.

Depending what chord of the multiple buttons you hold down, this draws
in a different color. Mouse motion over the pane with all buttons up
will also draw.

At least in 10.3, you can resize the window without any problem.

Here is the interesting part of the source code:

struct PointColor {
  HIPoint pt;
  UInt32  color;
  PointColor(const HIPoint& inPt, UInt32 inColor) :
     pt(inPt), color(inColor) {}
};

typedef std::vector<PointColor>  VectorPoint;

namespace {

bool operator == (const HIPoint& a, const HIPoint& b){
  return  a.x == b.x and a.y == b.y;
}

bool ShouldAppend(const VectorPoint& v, const HIPoint& p, UInt32 inColor){
  if(0 == v.size()){
     return true;
  }
  return not (p == v[v.size() - 1].pt and inColor == v[v.size() - 1].color);
}

} // end anonymous namespace

// ---------------------------------------------------------------------------
// DoControlDraw                    Event Handler        [protected]
OSStatus MouseMovedView::DoControlDraw(
  PPx::SysCarbonEvent& /* ioEvent */,
  ControlRef           /* inControl */,
  ControlPartCode         /* inPartCode */,
  RgnHandle            /* inClipRgn */,
  CGContextRef         inContext){

  HIRect   frame;            // Get bounding box in local coordinates
  GetLocalFrame(frame);  
  CGContextStrokeRectWithWidth(inContext, frame, mLineWidth);

  if(2 <= mPoints.size()){
     int iCount = mPoints.size();
     int lastColor = -1;
     for(VectorPoint::const_iterator i = mPoints.begin();i != mPoints.end(); ++i){
        if(lastColor != i->color){
           CGContextDrawPath(inContext, kCGPathStroke);
           CGContextBeginPath(inContext);
           CGContextMoveToPoint(inContext, i->pt.x, i->pt.y);
           CGContextSetLineWidth(inContext, 1);
           CGContextSetRGBStrokeColor(inContext,
              (1 & i->color) ? .9 : 0,
              (2 & i->color) ? .9 : 0,
              (4 & i->color) ? .9 : 0,
              (8 & i->color) ? .9 : .4);
           lastColor = i->color;
        }
        CGContextAddLineToPoint(inContext, i->pt.x, i->pt.y);
     }
     CGContextDrawPath(inContext, kCGPathStroke);
  }
  return noErr;
}

// ---------------------------------------------------------------------------
OSStatus MouseMovedView::MouseMotion(const HIPoint& inMouseLoc, UInt32 inColor){
  HIPoint localMouseLoc;
  OSStatus err;
  if(noErr == (err = GlobalToLocal(inMouseLoc, localMouseLoc)) and ShouldAppend(mPoints, localMouseLoc, inColor)){
     mPoints.push_back(PointColor(localMouseLoc, inColor));
     HIViewSetNeedsDisplay(GetSysView(), true);
     return noErr;
  }else{
     return err;
  }
}

// ---------------------------------------------------------------------------
// DoMouseMoved   Event Handler        [protected]
OSStatus MouseMovedView::DoMouseMoved(PPx::SysCarbonEvent& /*ioEvent*/, const HIPoint& inMouseLoc){
  return MouseMotion(inMouseLoc, 0);
}

namespace PPx {
namespace SysEventParam {

PPx_Declare_SysEventParam_Traits( TabletPointRec, typeTabletPointRec );
PPx_Declare_SysEventParam_Traits( TabletProximityRec, typeTabletProximityRec );

}  // SysEventParam
}  // PPx

// ---------------------------------------------------------------------------
// DoMouseDragged Event Handler        [protected]
/// just for fun, we handle digitizing tablets too.
OSStatus MouseMovedView::DoMouseDragged(PPx::SysCarbonEvent& ioEvent, const HIPoint& inMouseLoc){
  UInt32 modifiers = 0;
  UInt32 tabletType = 0;
  UInt32   mouseChord = 0;
  TabletPointRec pointRec;
  TabletProximityRec proximityRec;
  PPx::SysEventParam::Get(ioEvent, kEventParamMouseChord, mouseChord);
  // chord is | of:
  // 0x1 if left button down
  // 0x2 if right button down
  // 0x4 if middle button down
  // 0x8 if thumb button down
  // if you don't have a multibutton mouse, you can use these modifier bits instead. (appropriately shifted)
  PPx::SysEventParam::Get(ioEvent, kEventParamKeyModifiers, modifiers);
  if(noErr == PPx::SysEventParam::GetOptional(ioEvent, kEventParamTabletEventType, tabletType)){
     switch(tabletType){
     case kEventTabletPoint:    PPx::SysEventParam::Get(ioEvent, kEventParamTabletPointRec, pointRec);        break;
     case kEventTabletProximity:   PPx::SysEventParam::Get(ioEvent, kEventParamTabletProximityRec, proximityRec);   break;
     }
  }
  return MouseMotion(inMouseLoc, mouseChord);
}

// ---------------------------------------------------------------------------
// GlobalToLocal  conversion        [private]
OSStatus MouseMovedView::GlobalToLocal(const HIPoint& inMouseLoc, HIPoint& outPoint)const{
  OSStatus status = noErr;
  HIViewRef   sysView = GetSysView();
  PPx::Window* window = PPx::Window::GetWindowObject(GetControlOwner(sysView));
  if(NULL == window){ return paramErr; }
  Rect contentBounds;
  status = GetWindowBounds(window->GetSysWindow(), kWindowGlobalPortRgn, &contentBounds);
  outPoint = CGPointMake(inMouseLoc.x - contentBounds.left, inMouseLoc.y - contentBounds.top);
  if(noErr == status){ status = HIViewConvertPoint(&outPoint, window->GetContentView()->GetSysView(),   sysView); }
  return status;
}
David Dunham - 27 Nov 2004 21:39 GMT
In article
<oster-A78318.20424214112004@newssvr14-ext.news.prodigy.com>,

> > My first thought was to avoid subclassing by creating an LAttachment,
> > but there's no way for the attachment to send ClickSelf to make the
[quoted text clipped - 5 lines]
>
> ClickSelf is public, so the attachment can call it, THEN broadcast.

Hmm, I ended up subclassing so I don't have my attachment, but I could
have sworn I ran into problems with it not being public.

Signature

David Dunham    A Sharp, LLC
http://www.a-sharp.com/
   "I say we should listen to the customers and give them what they want."
   "What they want is better products for free." --Scott Adams

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.