Popup that always sends message
|
|
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
|
|
|