Mousewheel binding works, cutaway view shows view controls

This commit is contained in:
David Vierra 2015-02-08 09:24:05 -10:00
parent 97d4cb0e6a
commit 57f69916eb
4 changed files with 115 additions and 67 deletions

View File

@ -10,6 +10,7 @@ from PySide import QtGui
from mcedit2.rendering import worldscene, scenegraph
from mcedit2.util import profiler
from mcedit2.widgets.layout import Column, Row
from mcedit2.worldview.viewcontrols import ViewControls
from mcedit2.worldview.worldruler import WorldViewRulerGrid
from mcedit2.worldview.worldview import WorldView
from mcedit2.worldview.viewaction import ViewAction, MoveViewMouseAction
@ -34,6 +35,7 @@ def RecenterButton(view):
def CutawayWorldViewFrame(dimension, textureAtlas, geometryCache, sharedGLWidget):
viewFrame = QtGui.QWidget()
view = CutawayWorldView(dimension, textureAtlas, geometryCache, sharedGLWidget)
grid = WorldViewRulerGrid(view)
@ -65,13 +67,15 @@ def CutawayWorldViewFrame(dimension, textureAtlas, geometryCache, sharedGLWidget
view.viewportMoved.connect(updateDepthLabel)
view.__updateDepthLabel = updateDepthLabel
buttonBar = Row(None, depthLabel, x, y, z, RecenterButton(view))
widget = QtGui.QWidget()
widget.setLayout(Column(buttonBar, (grid, 1)))
widget.worldView = view
viewFrame.viewControls = ViewControls(view)
return widget
buttonBar = Row(None, depthLabel, x, y, z, RecenterButton(view), viewFrame.viewControls.getShowHideButton())
viewFrame.setLayout(Column(buttonBar, (grid, 1)))
viewFrame.worldView = view
return viewFrame
class SlicedWorldScene(scenegraph.Node):
@ -164,7 +168,8 @@ class CutawayWorldView(WorldView):
self.viewportMoved.connect(self.updateMeshPos)
self.viewActions.extend((
MoveViewMouseAction(),
CutawaySliceWheelAction()
CutawaySliceUpAction(),
CutawaySliceDownAction(),
))
def createWorldScene(self):
@ -277,15 +282,26 @@ class CutawayWorldView(WorldView):
event.view = self
class CutawaySliceWheelAction(ViewAction):
settingsKey = "worldview.cutaway.xxx_make_mousewheel_bindable"
def wheelEvent(self, event):
delta = event.delta()
if delta == 0:
return
class CutawaySliceUpAction(ViewAction):
settingsKey = "worldview.cutaway.slice_up"
button = ViewAction.WHEEL_UP
labelText = "Slice Up"
acceptsMouseWheel = True
def buttonPressEvent(self, event):
p = list(event.view.centerPoint)
p[event.view.dim] += delta / abs(delta)
p[event.view.dim] += 1
event.view.centerPoint = p
class CutawaySliceDownAction(ViewAction):
settingsKey = "worldview.cutaway.slice_down"
button = ViewAction.WHEEL_DOWN
labelText = "Slice Down"
acceptsMouseWheel = True
def buttonPressEvent(self, event):
p = list(event.view.centerPoint)
p[event.view.dim] -= 1
event.view.centerPoint = p

View File

@ -3,12 +3,13 @@
"""
from __future__ import absolute_import, division, print_function
import logging
from PySide import QtGui, QtCore
from PySide.QtCore import Qt
from mcedit2.util.settings import Settings
log = logging.getLogger(__name__)
class ViewAction(object):
class ViewAction(QtCore.QObject):
button = Qt.NoButton
modifiers = Qt.NoModifier
key = 0
@ -17,17 +18,30 @@ class ViewAction(object):
settingsKey = NotImplemented
acceptsMouseWheel = False
WHEEL_UP = 0x100
WHEEL_DOWN = 0x200
_buttonNames = None
def __init__(self):
"""
An action that can be bound to a keypress or mouse button click, drag, or movement with the bound key or button held.
"""
super(ViewAction, self).__init__()
if self.settingsKey is not None:
settings = Settings()
prefix = "keybindings/"
self.modifiers = int(settings.value(prefix + self.settingsKey + "/modifiers", self.modifiers))
self.button = int(settings.value(prefix + self.settingsKey + "/button", self.button))
self.key = int(settings.value(prefix + self.settingsKey + "/key", self.key))
try:
modifiers = int(settings.value(prefix + self.settingsKey + "/modifiers", self.modifiers))
button = int(settings.value(prefix + self.settingsKey + "/button", self.button))
key = int(settings.value(prefix + self.settingsKey + "/key", self.key))
except Exception as e:
log.error("Error while reading key binding:")
else:
self.modifiers = modifiers
self.button = button
self.key = key
def __repr__(self):
return "%s(button=%s, key=%s, modifiers=%s)" % (self.__class__.__name__, self.button, self.key, self.modifiers)
@ -111,6 +125,42 @@ class ViewAction(object):
"""
def buttonName(self, buttons):
if ViewAction._buttonNames is None:
ViewAction._buttonNames = [
(Qt.LeftButton, self.tr("Left Button")),
(Qt.RightButton, self.tr("Right Button")),
(Qt.MiddleButton, self.tr("Middle Button")),
(ViewAction.WHEEL_UP, self.tr("Mousewheel Up")),
(ViewAction.WHEEL_DOWN, self.tr("Mousewheel Down")),
]
parts = [name for mask, name in self._buttonNames if buttons & mask]
return "+".join(parts)
def describeKeys(self):
modifierKeyNames = {
Qt.Key_Shift: self.tr("Shift"),
Qt.Key_Control: self.tr("Control"),
Qt.Key_Alt: self.tr("Alt"),
Qt.Key_Meta: self.tr("Meta"),
}
s = modifierKeyNames.get(self.key) # QKeySequence returns weird strings when only a modifier is pressed
if s is None:
try:
s = QtGui.QKeySequence(self.key | self.modifiers).toString()
except TypeError:
log.error("KEY: %r MOD: %r", self.key, self.modifiers)
raise
if self.key == 0:
s = s[:-2]
if self.button != Qt.NoButton:
if len(s):
s += "+"
s += self.buttonName(self.button)
return s
class UseToolMouseAction(ViewAction):
button = Qt.LeftButton
labelText = "Use Tool (Don't change!)"

View File

@ -7,46 +7,10 @@ from PySide import QtGui
from PySide.QtCore import Qt
import time
from mcedit2.widgets.layout import Column
from mcedit2.worldview.viewaction import ViewAction
log = logging.getLogger(__name__)
_buttonNames = [
(Qt.LeftButton, "Left Button"),
(Qt.RightButton, "Right Button"),
(Qt.MiddleButton, "Middle Button"),
]
def buttonName(buttons):
parts = [name for mask, name in _buttonNames if buttons & mask]
return "+".join(parts)
def describeKeys(viewAction):
modifierKeyNames = {
Qt.Key_Shift: QtGui.qApp.tr("Shift"),
Qt.Key_Control: QtGui.qApp.tr("Control"),
Qt.Key_Alt: QtGui.qApp.tr("Alt"),
Qt.Key_Meta: QtGui.qApp.tr("Meta"),
"WHEEL_UP": QtGui.qApp.tr("Mousewheel Up"),
"WHEEL_DOWN": QtGui.qApp.tr("Mousewheel Down"),
}
s = modifierKeyNames.get(viewAction.key) # QKeySequence returns weird strings when only a modifier is pressed
if s is None:
try:
s = QtGui.QKeySequence(viewAction.key | viewAction.modifiers).toString()
except TypeError:
log.error("KEY: %r MOD: %r", viewAction.key, viewAction.modifiers)
raise
if viewAction.key == 0:
s = s[:-2]
if viewAction.button != Qt.NoButton:
if len(s):
s += "+"
s += buttonName(viewAction.button)
return s
class ModifierInputWidget(QtGui.QWidget):
@ -62,7 +26,7 @@ class ModifierInputWidget(QtGui.QWidget):
frame = QtGui.QFrame()
frame.setFrameStyle(QtGui.QFrame.Box)
self.inputLabel = QtGui.QLabel(describeKeys(inputButton))
self.inputLabel = QtGui.QLabel(inputButton.viewAction.describeKeys())
self.inputLabel.setAlignment(Qt.AlignCenter)
font = self.inputLabel.font()
font.setPointSize(font.pointSize() * 1.5)
@ -92,7 +56,7 @@ class ModifierInputWidget(QtGui.QWidget):
return # Forbid binding left button
self.inputButton.setBinding(mouseEvent.button(), 0, mouseEvent.modifiers())
self.inputLabel.setText(describeKeys(self.inputButton.viewAction))
self.inputLabel.setText(self.inputButton.viewAction.describeKeys())
def keyPressEvent(self, keyEvent):
"""
@ -112,7 +76,7 @@ class ModifierInputWidget(QtGui.QWidget):
log.info("Control change: key %s(%s) modifiers %s(%s)", key, hex(key), modifiers, hex(int(modifiers)))
self.inputButton.setBinding(Qt.NoButton, key, modifiers)
self.inputLabel.setText(describeKeys(self.inputButton.viewAction))
self.inputLabel.setText(self.inputButton.viewAction.describeKeys())
def wheelEvent(self, wheelEvent):
if not self.inputButton.viewAction.acceptsMouseWheel:
@ -122,16 +86,16 @@ class ModifierInputWidget(QtGui.QWidget):
if delta == 0:
return
if delta > 0:
key = "WHEEL_UP"
button = ViewAction.WHEEL_UP
else:
key = "WHEEL_DOWN"
button = ViewAction.WHEEL_DOWN
modifiers = wheelEvent.modifiers()
log.info("Control change: key %s modifiers %s", key, hex(int(modifiers)))
log.info("Control change: button %s modifiers %s", button, hex(int(modifiers)))
self.inputButton.setBinding(Qt.NoButton, key, modifiers)
self.inputLabel.setText(describeKeys(self.inputButton))
self.inputButton.setBinding(button, 0, modifiers)
self.inputLabel.setText(self.inputButton.viewAction.describeKeys())
class ButtonModifierInput(QtGui.QPushButton):
@ -141,7 +105,7 @@ class ButtonModifierInput(QtGui.QPushButton):
:type viewAction: mcedit2.worldview.viewaction.ViewAction
"""
super(ButtonModifierInput, self).__init__(text=describeKeys(viewAction), *a, **kw)
super(ButtonModifierInput, self).__init__(text=viewAction.describeKeys(), *a, **kw)
self.setStyleSheet("""
:disabled {
color: #000000;
@ -165,7 +129,7 @@ class ButtonModifierInput(QtGui.QPushButton):
inputWidget.setGeometry(rect)
def updateText(self):
self.setText(describeKeys(self.viewAction))
self.setText(self.viewAction.describeKeys())
@property
def key(self):

View File

@ -358,12 +358,30 @@ class WorldView(QGLWidget):
if not action.key or action.key in self.pressedKeys:
action.mouseReleaseEvent(event)
wheelPos = 0
def wheelEvent(self, event):
self.augmentMouseEvent(event)
for action in self.viewActions:
if action.acceptsMouseWheel and ((action.modifiers & event.modifiers()) or action.modifiers == event.modifiers()):
if action.key in("WHEEL_UP", "WHEEL_DOWN"):
for i in range((abs(event.delta()) + 14) / 15): # xxx 15 = wheel sensitivity?
self.wheelPos += event.delta()
# event.delta reports eighths of a degree. a standard wheel tick is 15 degrees, or 120 eighths.
# keep count of wheel position and emit an event for each 15 degrees turned.
# xxx will we ever need sub-click precision for wheel events?
clicks = 0
while self.wheelPos >= 120:
self.wheelPos -= 120
clicks += 1
while self.wheelPos <= -120:
self.wheelPos += 120
clicks -= 1
if action.button == action.WHEEL_UP and clicks < 0:
for i in range(abs(clicks)):
action.keyPressEvent(event)
if action.button == action.WHEEL_DOWN and clicks > 0:
for i in range(clicks):
action.keyPressEvent(event)