mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
Merge pull request #18 from eswartz/support-mouse-confinement
Support mouse confinement
This commit is contained in:
commit
5f20afd5ea
@ -736,24 +736,10 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
// Fullscreen property specified, but unchanged.
|
// Fullscreen property specified, but unchanged.
|
||||||
properties.clear_fullscreen();
|
properties.clear_fullscreen();
|
||||||
}
|
}
|
||||||
if (properties.has_mouse_mode() ) {
|
if (properties.has_mouse_mode() &&
|
||||||
|
properties.get_mouse_mode() == _properties.get_mouse_mode()) {
|
||||||
if (properties.get_mouse_mode() == _properties.get_mouse_mode()) {
|
// Mouse mode specified, but unchanged.
|
||||||
properties.clear_mouse_mode();
|
properties.clear_mouse_mode();
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(properties.get_mouse_mode() == WindowProperties::M_absolute) {
|
|
||||||
_properties.set_mouse_mode(WindowProperties::M_absolute);
|
|
||||||
mouse_mode_absolute();
|
|
||||||
properties.clear_mouse_mode();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_properties.set_mouse_mode(WindowProperties::M_relative);
|
|
||||||
mouse_mode_relative();
|
|
||||||
properties.clear_mouse_mode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,19 +798,30 @@ clear_z_order() {
|
|||||||
// Function: WindowProperties::set_mouse_mode
|
// Function: WindowProperties::set_mouse_mode
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Specifies the mode in which the window is to operate
|
// Description: Specifies the mode in which the window is to operate
|
||||||
// its mouse pointer. The default is M_absolute, which
|
// its mouse pointer.
|
||||||
// is the normal mode in which a mouse pointer operates;
|
//
|
||||||
// but you can also set M_relative, which is
|
// M_absolute: the normal mode in which a mouse pointer
|
||||||
// particularly useful for FPS-style mouse movements
|
// operates, where the mouse can move outside the window
|
||||||
// where you have hidden the mouse pointer and are are
|
// and the mouse coordinates are relative to its
|
||||||
// more interested in how fast the mouse is moving,
|
// position in the window.
|
||||||
// rather than precisely where the pointer is hovering.
|
//
|
||||||
|
// M_relative (OSX or Unix/X11 only): a mode where only
|
||||||
|
// relative movements are reported; particularly useful
|
||||||
|
// for FPS-style mouse movements where you have hidden
|
||||||
|
// the mouse pointer and are are more interested in how
|
||||||
|
// fast the mouse is moving, rather than precisely where
|
||||||
|
// the pointer is hovering.
|
||||||
|
//
|
||||||
|
// This has no effect on Windows. On Unix/X11, this
|
||||||
|
// requires the Xxf86dga extension to be available.
|
||||||
|
//
|
||||||
|
// M_confined: this mode reports absolute mouse
|
||||||
|
// positions, but confines the mouse pointer to
|
||||||
|
// the window boundary. It can portably replace
|
||||||
|
// M_relative for an FPS, but you need to periodically
|
||||||
|
// move the pointer to the center of the window
|
||||||
|
// and track movement deltas.
|
||||||
//
|
//
|
||||||
// This has no effect on Windows, which does not
|
|
||||||
// have this concept; but is important to do on OSX
|
|
||||||
// and Unix/X11 to properly enable a smooth FPS-style
|
|
||||||
// mouselook mode. On Unix/X11, this requires the
|
|
||||||
// Xxf86dga extension to be available.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void WindowProperties::
|
INLINE void WindowProperties::
|
||||||
set_mouse_mode(MouseMode mode) {
|
set_mouse_mode(MouseMode mode) {
|
||||||
|
@ -400,6 +400,8 @@ operator << (ostream &out, WindowProperties::MouseMode mode) {
|
|||||||
return out << "absolute";
|
return out << "absolute";
|
||||||
case WindowProperties::M_relative:
|
case WindowProperties::M_relative:
|
||||||
return out << "relative";
|
return out << "relative";
|
||||||
|
case WindowProperties::M_confined:
|
||||||
|
return out << "confined";
|
||||||
}
|
}
|
||||||
return out << "**invalid WindowProperties::MouseMode(" << (int)mode << ")**";
|
return out << "**invalid WindowProperties::MouseMode(" << (int)mode << ")**";
|
||||||
}
|
}
|
||||||
@ -413,6 +415,8 @@ operator >> (istream &in, WindowProperties::MouseMode &mode) {
|
|||||||
mode = WindowProperties::M_absolute;
|
mode = WindowProperties::M_absolute;
|
||||||
} else if (word == "relative") {
|
} else if (word == "relative") {
|
||||||
mode = WindowProperties::M_relative;
|
mode = WindowProperties::M_relative;
|
||||||
|
} else if (word == "confined") {
|
||||||
|
mode = WindowProperties::M_confined;
|
||||||
} else {
|
} else {
|
||||||
display_cat.warning()
|
display_cat.warning()
|
||||||
<< "Unknown mouse mode: " << word << "\n";
|
<< "Unknown mouse mode: " << word << "\n";
|
||||||
|
@ -40,6 +40,7 @@ PUBLISHED:
|
|||||||
enum MouseMode {
|
enum MouseMode {
|
||||||
M_absolute,
|
M_absolute,
|
||||||
M_relative,
|
M_relative,
|
||||||
|
M_confined,
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowProperties();
|
WindowProperties();
|
||||||
|
@ -35,6 +35,8 @@ WinGraphicsWindow *WinGraphicsWindow::_creating_window = NULL;
|
|||||||
WinGraphicsWindow *WinGraphicsWindow::_cursor_window = NULL;
|
WinGraphicsWindow *WinGraphicsWindow::_cursor_window = NULL;
|
||||||
bool WinGraphicsWindow::_cursor_hidden = false;
|
bool WinGraphicsWindow::_cursor_hidden = false;
|
||||||
|
|
||||||
|
RECT WinGraphicsWindow::_mouse_unconfined_cliprect;
|
||||||
|
|
||||||
// These are used to save the previous state of the fancy Win2000
|
// These are used to save the previous state of the fancy Win2000
|
||||||
// effects that interfere with rendering when the mouse wanders into a
|
// effects that interfere with rendering when the mouse wanders into a
|
||||||
// window's client area.
|
// window's client area.
|
||||||
@ -359,6 +361,48 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.has_mouse_mode()) {
|
||||||
|
if (properties.get_mouse_mode() != _properties.get_mouse_mode()) {
|
||||||
|
switch (properties.get_mouse_mode()) {
|
||||||
|
case WindowProperties::M_absolute:
|
||||||
|
case WindowProperties::M_relative: // not implemented, treat as absolute
|
||||||
|
|
||||||
|
if (_properties.get_mouse_mode() == WindowProperties::M_confined) {
|
||||||
|
ClipCursor(NULL);
|
||||||
|
windisplay_cat.info() << "Unconfining cursor from window\n";
|
||||||
|
}
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_absolute);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_confined:
|
||||||
|
{
|
||||||
|
RECT clip;
|
||||||
|
|
||||||
|
if (!GetWindowRect(_hWnd, &clip)) {
|
||||||
|
windisplay_cat.warning()
|
||||||
|
<< "GetWindowRect() failed in set_properties_now. Cannot confine cursor.\n";
|
||||||
|
} else {
|
||||||
|
windisplay_cat.info()
|
||||||
|
<< "ClipCursor() to " << clip.left << "," << clip.top << " to "
|
||||||
|
<< clip.right << "," << clip.bottom << endl;
|
||||||
|
|
||||||
|
GetClipCursor(&_mouse_unconfined_cliprect);
|
||||||
|
if (!ClipCursor(&clip)) {
|
||||||
|
windisplay_cat.warning()
|
||||||
|
<< "ClipCursor() failed in set_properties_now. Ignoring.\n";
|
||||||
|
} else {
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_confined);
|
||||||
|
windisplay_cat.info() << "Confining cursor to window\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -214,6 +214,9 @@ private:
|
|||||||
static BOOL _saved_cursor_shadow;
|
static BOOL _saved_cursor_shadow;
|
||||||
static BOOL _saved_mouse_vanish;
|
static BOOL _saved_mouse_vanish;
|
||||||
|
|
||||||
|
// The mouse constraints before applying mouse mode M_confined.
|
||||||
|
static RECT _mouse_unconfined_cliprect;
|
||||||
|
|
||||||
// Since the Panda API requests icons and cursors by filename, we
|
// Since the Panda API requests icons and cursors by filename, we
|
||||||
// need a table mapping filenames to handles, so we can avoid
|
// need a table mapping filenames to handles, so we can avoid
|
||||||
// re-reading the file each time we change icons.
|
// re-reading the file each time we change icons.
|
||||||
|
@ -711,6 +711,88 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
properties.clear_foreground();
|
properties.clear_foreground();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.has_mouse_mode()) {
|
||||||
|
switch (properties.get_mouse_mode()) {
|
||||||
|
case WindowProperties::M_absolute:
|
||||||
|
XUngrabPointer(_display, CurrentTime);
|
||||||
|
#ifdef HAVE_XF86DGA
|
||||||
|
if (_dga_mouse_enabled) {
|
||||||
|
x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
||||||
|
XF86DGADirectVideo(_display, _screen, 0);
|
||||||
|
_dga_mouse_enabled = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_absolute);
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_relative:
|
||||||
|
#ifdef HAVE_XF86DGA
|
||||||
|
if (!_dga_mouse_enabled) {
|
||||||
|
int major_ver, minor_ver;
|
||||||
|
if (XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
||||||
|
|
||||||
|
X11_Cursor cursor = None;
|
||||||
|
if (_properties.get_cursor_hidden()) {
|
||||||
|
x11GraphicsPipe *x11_pipe;
|
||||||
|
DCAST_INTO_V(x11_pipe, _pipe);
|
||||||
|
cursor = x11_pipe->get_hidden_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
||||||
|
GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
||||||
|
x11display_cat.error() << "Failed to grab pointer!\n";
|
||||||
|
} else {
|
||||||
|
x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
||||||
|
XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
||||||
|
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_relative);
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
_dga_mouse_enabled = true;
|
||||||
|
|
||||||
|
// Get the real mouse position, so we can add/subtract
|
||||||
|
// our relative coordinates later.
|
||||||
|
XEvent event;
|
||||||
|
XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
||||||
|
&event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
||||||
|
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
||||||
|
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x11display_cat.info() << "XF86DGA extension not available\n";
|
||||||
|
_dga_mouse_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_confined:
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XF86DGA
|
||||||
|
if (_dga_mouse_enabled) {
|
||||||
|
XF86DGADirectVideo(_display, _screen, 0);
|
||||||
|
_dga_mouse_enabled = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
X11_Cursor cursor = None;
|
||||||
|
if (_properties.get_cursor_hidden()) {
|
||||||
|
x11GraphicsPipe *x11_pipe;
|
||||||
|
DCAST_INTO_V(x11_pipe, _pipe);
|
||||||
|
cursor = x11_pipe->get_hidden_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
||||||
|
GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
||||||
|
x11display_cat.error() << "Failed to grab pointer!\n";
|
||||||
|
} else {
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_confined);
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set_wm_properties(wm_properties, true);
|
set_wm_properties(wm_properties, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,14 +803,7 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void x11GraphicsWindow::
|
void x11GraphicsWindow::
|
||||||
mouse_mode_absolute() {
|
mouse_mode_absolute() {
|
||||||
#ifdef HAVE_XF86DGA
|
// unused: remove in 1.10!
|
||||||
if (!_dga_mouse_enabled) return;
|
|
||||||
|
|
||||||
XUngrabPointer(_display, CurrentTime);
|
|
||||||
x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
|
|
||||||
XF86DGADirectVideo(_display, _screen, 0);
|
|
||||||
_dga_mouse_enabled = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -738,42 +813,7 @@ mouse_mode_absolute() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void x11GraphicsWindow::
|
void x11GraphicsWindow::
|
||||||
mouse_mode_relative() {
|
mouse_mode_relative() {
|
||||||
#ifdef HAVE_XF86DGA
|
// unused: remove in 1.10!
|
||||||
if (_dga_mouse_enabled) return;
|
|
||||||
|
|
||||||
int major_ver, minor_ver;
|
|
||||||
if (XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
|
|
||||||
|
|
||||||
X11_Cursor cursor = None;
|
|
||||||
if (_properties.get_cursor_hidden()) {
|
|
||||||
x11GraphicsPipe *x11_pipe;
|
|
||||||
DCAST_INTO_V(x11_pipe, _pipe);
|
|
||||||
cursor = x11_pipe->get_hidden_cursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync,
|
|
||||||
GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
|
|
||||||
x11display_cat.error() << "Failed to grab pointer!\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
|
|
||||||
XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
|
|
||||||
|
|
||||||
_dga_mouse_enabled = true;
|
|
||||||
} else {
|
|
||||||
x11display_cat.info() << "XF86DGA extension not available\n";
|
|
||||||
_dga_mouse_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the real mouse position, so we can add/subtract
|
|
||||||
// our relative coordinates later.
|
|
||||||
XEvent event;
|
|
||||||
XQueryPointer(_display, _xwindow, &event.xbutton.root,
|
|
||||||
&event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root,
|
|
||||||
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
|
||||||
_input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
172
samples/mouse-modes/main.py
Normal file
172
samples/mouse-modes/main.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
'''
|
||||||
|
Demonstrate different mouse modes
|
||||||
|
'''
|
||||||
|
|
||||||
|
# from panda3d.core import loadPrcFileData
|
||||||
|
#
|
||||||
|
# loadPrcFileData("", "notify-level-x11display debug")
|
||||||
|
# loadPrcFileData("", "notify-level-windisplay debug")
|
||||||
|
#
|
||||||
|
# loadPrcFileData("", "load-display p3tinydisplay")
|
||||||
|
|
||||||
|
from panda3d.core import WindowProperties, TextNode
|
||||||
|
from direct.task.TaskManagerGlobal import taskMgr
|
||||||
|
from direct.gui.OnscreenText import OnscreenText
|
||||||
|
from direct.task import Task
|
||||||
|
from direct.showbase.ShowBase import ShowBase
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class App(ShowBase):
|
||||||
|
def __init__(self):
|
||||||
|
ShowBase.__init__(self)
|
||||||
|
self.base = self
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def genLabelText(self, text, i):
|
||||||
|
text = OnscreenText(text = text, pos = (-1.3, .5-.05*i), fg=(0,1,0,1),
|
||||||
|
align = TextNode.ALeft, scale = .05)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
# Disable the camera trackball controls.
|
||||||
|
self.disableMouse()
|
||||||
|
|
||||||
|
self.mouseMagnitude = 144
|
||||||
|
|
||||||
|
self.rotateX, self.rotateY = 0, 0
|
||||||
|
|
||||||
|
self.genLabelText("[0] Absolute mode, [1] Relative mode, [2] Confined mode", 0)
|
||||||
|
|
||||||
|
self.base.accept('0', lambda: self.setMouseMode(WindowProperties.M_absolute))
|
||||||
|
self.base.accept('1', lambda: self.setMouseMode(WindowProperties.M_relative))
|
||||||
|
self.base.accept('2', lambda: self.setMouseMode(WindowProperties.M_confined))
|
||||||
|
|
||||||
|
self.genLabelText("[C] Manually re-center mouse on each tick", 1)
|
||||||
|
self.base.accept('C', lambda: self.toggleRecenter())
|
||||||
|
self.base.accept('c', lambda: self.toggleRecenter())
|
||||||
|
|
||||||
|
self.genLabelText("[S] Show mouse", 2)
|
||||||
|
self.base.accept('S', lambda: self.toggleMouse())
|
||||||
|
self.base.accept('s', lambda: self.toggleMouse())
|
||||||
|
|
||||||
|
self.base.accept('escape', sys.exit, [0])
|
||||||
|
|
||||||
|
self.mouseText = self.genLabelText("", 5)
|
||||||
|
self.deltaText = self.genLabelText("", 6)
|
||||||
|
self.positionText = self.genLabelText("", 8)
|
||||||
|
|
||||||
|
self.lastMouseX, self.lastMouseY = None, None
|
||||||
|
|
||||||
|
self.hideMouse = False
|
||||||
|
|
||||||
|
self.setMouseMode(WindowProperties.M_absolute)
|
||||||
|
self.manualRecenterMouse = True
|
||||||
|
|
||||||
|
# make a box to move with the mouse
|
||||||
|
self.model = self.loader.loadModel("box.egg")
|
||||||
|
self.model.reparentTo(self.render)
|
||||||
|
|
||||||
|
self.cam.setPos(0, -5, 0)
|
||||||
|
self.cam.lookAt(0, 0, 0)
|
||||||
|
|
||||||
|
self.mouseTask = taskMgr.add(self.mouseTask, "Mouse Task")
|
||||||
|
|
||||||
|
def setMouseMode(self, mode):
|
||||||
|
print "Changing mode to",mode
|
||||||
|
|
||||||
|
self.mouseMode = mode
|
||||||
|
|
||||||
|
wp = WindowProperties()
|
||||||
|
wp.setMouseMode(mode)
|
||||||
|
self.base.win.requestProperties(wp)
|
||||||
|
|
||||||
|
# these changes may require a tick to apply
|
||||||
|
self.base.taskMgr.doMethodLater(0, self.resolveMouse, "Resolve mouse setting")
|
||||||
|
|
||||||
|
def resolveMouse(self, t):
|
||||||
|
wp = self.base.win.getProperties()
|
||||||
|
|
||||||
|
actualMode = wp.getMouseMode()
|
||||||
|
if self.mouseMode != actualMode:
|
||||||
|
print "ACTUAL MOUSE MODE:", actualMode
|
||||||
|
|
||||||
|
self.mouseMode = actualMode
|
||||||
|
|
||||||
|
self.rotateX, self.rotateY = -.5, -.5
|
||||||
|
self.lastMouseX, self.lastMouseY = None, None
|
||||||
|
self.recenterMouse()
|
||||||
|
|
||||||
|
def recenterMouse(self):
|
||||||
|
self.base.win.movePointer(0,
|
||||||
|
int(self.base.win.getProperties().getXSize() / 2),
|
||||||
|
int(self.base.win.getProperties().getYSize() / 2))
|
||||||
|
|
||||||
|
|
||||||
|
def toggleRecenter(self):
|
||||||
|
print "Toggling re-center behavior"
|
||||||
|
self.manualRecenterMouse = not self.manualRecenterMouse
|
||||||
|
|
||||||
|
def toggleMouse(self):
|
||||||
|
print "Toggling mouse visibility"
|
||||||
|
|
||||||
|
self.hideMouse = not self.hideMouse
|
||||||
|
|
||||||
|
wp = WindowProperties()
|
||||||
|
wp.setCursorHidden(self.hideMouse)
|
||||||
|
self.base.win.requestProperties(wp)
|
||||||
|
|
||||||
|
def mouseTask(self, task):
|
||||||
|
mw = self.base.mouseWatcherNode
|
||||||
|
|
||||||
|
hasMouse = mw.hasMouse()
|
||||||
|
if hasMouse:
|
||||||
|
# get the window manager's idea of the mouse position
|
||||||
|
x, y = mw.getMouseX(), mw.getMouseY()
|
||||||
|
|
||||||
|
if self.lastMouseX is not None:
|
||||||
|
# get the delta
|
||||||
|
if self.manualRecenterMouse:
|
||||||
|
# when recentering, the position IS the delta
|
||||||
|
# since the center is reported as 0, 0
|
||||||
|
dx, dy = x, y
|
||||||
|
else:
|
||||||
|
dx, dy = x - self.lastMouseX, y - self.lastMouseY
|
||||||
|
else:
|
||||||
|
# no data to compare with yet
|
||||||
|
dx, dy = 0, 0
|
||||||
|
|
||||||
|
self.lastMouseX, self.lastMouseY = x, y
|
||||||
|
|
||||||
|
else:
|
||||||
|
x, y, dx, dy = 0, 0, 0, 0
|
||||||
|
|
||||||
|
if self.manualRecenterMouse:
|
||||||
|
# move mouse back to center
|
||||||
|
self.recenterMouse()
|
||||||
|
|
||||||
|
# scale position and delta to pixels for user
|
||||||
|
w, h = self.win.getSize()
|
||||||
|
|
||||||
|
self.mouseText.setText("Mode: {0}, Recenter: {1} | Mouse: {2}, {3} | hasMouse: {4}".format(
|
||||||
|
self.mouseMode, self.manualRecenterMouse,
|
||||||
|
int(x*w), int(y*h),
|
||||||
|
hasMouse))
|
||||||
|
self.deltaText.setText("Delta: {0}, {1}".format(
|
||||||
|
int(dx*w), int(dy*h)))
|
||||||
|
|
||||||
|
# rotate box by delta
|
||||||
|
self.rotateX += dx * 10
|
||||||
|
self.rotateY += dy * 10
|
||||||
|
|
||||||
|
self.positionText.setText("Model rotation: {0}, {1}".format(
|
||||||
|
int(self.rotateX*1000)/1000., int(self.rotateY*1000)/1000.))
|
||||||
|
|
||||||
|
self.model.setH(self.rotateX)
|
||||||
|
self.model.setP(self.rotateY)
|
||||||
|
return Task.cont
|
||||||
|
|
||||||
|
app = App()
|
||||||
|
app.run()
|
Loading…
x
Reference in New Issue
Block a user