a drag box for selecting an area

What sort of trouble? I note that you’re parenting your new MW’s to base.mouseWatcher, which is already filtered a little bit. It might work fine, though. I had in mind parenting it to base.mouseWatcher.getParent(), to get the raw data directly from the MouseAndKeyboard object. I’m not sure if there will be a difference, but it’s probably worth trying it that way just to be sure.

Right, you’ll have to listen for window-event, similar to the way ShowBase does. You can either set the film size or directly set the aspect ratio. Setting the film size gives you more explicit control.

David

Actually, I’m not having it anymore and I don’t remember when it stopped. Knowing me, that part of my message might have been out of date. However I am using a routing method to look-up the ‘up’ methods from a dictionary, to get them to the View objects that got the corresponding ‘down’ methods. Maybe it’s not necessary.

class Diagram(DirectObject):
	def __init__(self):
		# snip
		self.accept("mouse1", self.route, ['mouse1','mouse1','down'] )
		self.accept("mouse1-up", self.route, ['mouse1up','mouse1','up'] )
		self.accept("mouse3", self.route, ['mouse3','mouse3','down'] )
		self.accept("mouse3-up", self.route, ['mouse3up','mouse3','up'] )

	def route( self, methName, *args ):
		if not base.mouseWatcherNode.hasMouse( ):
			return
		if args and args[1]== 'up':
			reg= self.prevreg.pop( args[0], None )
			if reg is None:
				return
			args= args[2:]
		else:
			x=base.mouseWatcherNode.getMouseX()
			y=base.mouseWatcherNode.getMouseY()
			reg= base.mouseWatcherNode.getOverRegion( x, y )
		if reg is None:
			return
		if args and args[1]== 'down':
			self.prevreg[ args[0] ]= reg
			args= args[2:]
		if not reg.getName( ).startswith( 'region-' ):
			return
		view= int( reg.getName( )[ 7 ] )
		view= self.views[ view ]
		getattr( view, methName )( *args )

I tried reparenting my MWs to base.mouseWatcher.getParent() . It didn’t seem to change the behavior, but the behavior doesn’t seem to be what I reported.

Alright, well, is it just the default camera that does it by default? I assume thwww.panda3d.orged, which is what I want. This actually gives me the opportunity to change the resize behavior anyway-- I was wanting to keep the same zoom/pixel ratio, instead of zoom/window ratio, if that does any kind of job of explaining it.

By the way, you suggested using set-from-frustum earlier. I don’t think that would be awful once I have the world coordinates. My picture of what I want is that the narrower side of the rectangle we select fills the screen, so the frustum would have to be the largest that doesn’t exceed the given rectangle, not the smallest that encapsulates it, but I’m not getting that behavior right now anyway. At some point you start to wonder what the reason is for your picture, if there’s something similar that’s a lot more convenient.

I got lucky on this one. The ‘rezoom’ method on views has a relative zoom parameter. Just calling it with that equal to one results in requerying the pixel width and pixel height. These attributes are already adjusted by the time window-event gets called. Then the film size is set from the pixel sizes times the zoom factor.

On the window-event event:

	def windowEvent( self, win ):
		for v in self.views:
			v.rezoom( relzoom= 1 )

The rezoom method:

	def rezoom( self, zoom= None, relzoom= None ):
		if zoom is not None:
			self.zoom= zoom
		else:
			self.zoom= zoom= self.zoom* relzoom
		x= self.dispreg.getPixelWidth( )/ float( zoom )
		y= self.dispreg.getPixelHeight( )/ float( zoom )
		self.lens.setFilmSize( x, y )

It could be that View instances could sink window-event themselves, assuming that events can be one-to-many.

A further update on my mouse-up trouble-- the mouse position that the MWN knows of doesn’t seem to change once the mouse leaves its region. But it doesn’t register an up event properly until the button does come up.

I noticed this by, when the user drags from in-bounds to out-of-bounds, the during-drag task seems to stop. However, it must still be running because the mouse-up event comes at the right time.

Unfortunately, the

self.mouse1x2=self.mousewatN.getMouseX()
		self.mouse1y2=self.mousewatN.getMouseY()

query during the dragging task won’t return coordinates if the MWN doesn’t have the mouse.

Assertion failed: _has_mouse at line 65 of c:\panda3d-1.7.0\panda\src\tform\mouseWatcher.I

Traceback (most recent call last):
  File "C:\Documents and Settings\usr\My Documents\working\diagram.py", line 270, in dragg
ing3
    x2=self.mousewatN.getMouseX()
AssertionError: _has_mouse at line 65 of c:\panda3d-1.7.0\panda\src\tform\mouseWatcher.I
:task(error)www.panda3d.orgd in PythonTask dragging3

Otherwise, maybe I could keep the drag going.

Hmm, good point. The MWN should remember, and continue to report, the mouse position as long as the button is held down, even if the mouse wanders out of the DisplayRegion. I’ll put in a fix for that.

In the meantime, to avoid the assertion error at least, you should check the result of hasMouse() before you query getMouseX() or getMouseY().

David

I got this into decent shape and put it in Code Snippets.

discourse.panda3d.org/viewtopic … highlight=

There is some support for capturing the mouse even if it wanders out of the window!-- so long as a button is being held. Do your plans include that as well?

How come we never see

x, y= getMouse( )

in the docs?

Also, I am obtaining a MouseWatcherRegion from:

	reg= base.mouseWatcherNode.getOverRegion( )

Now I need the MouseWatcher and the Camera I’m using in it. I could iterate over all my MouseWatchers, but it seems like I could get them directly, but the MouseWatcherRegion class doesn’t include anything like that.

Yes.

Because these pages of the manual were written by someone who didn’t use that construct? You’re welcome to rewrite them if you think they could be made more clear.

Well, the MouseWatcherRegion doesn’t have a pointer to its containing MouseWatcher. But you do–you just called getOverRegion() on the containing MouseWatcher. Why not save that pointer?

David

I don’t get that.

Here’s what I’m doing now. I think the for loop is superfluous.

    if not base.mouseWatcherNode.hasMouse( ):
        return task.cont
    for view in views:
        if view.mousewatN.hasMouse( ):
            break
    else:
        return task.cont

    mpos = view.mousewatN.getMouse()
    pickerRay.setFromLens(view.cam, mpos.getX(), mpos.getY())