4 from __future__ import division
9 from PyQt4 import QtGui
10 from PyQt4 import QtCore
15 class PieKeyboard(object):
17 SLICE_CENTER = qtpie.EIGHT_SLICE_PIE.SLICE_CENTER
18 SLICE_NORTH = qtpie.EIGHT_SLICE_PIE.SLICE_NORTH
19 SLICE_NORTH_WEST = qtpie.EIGHT_SLICE_PIE.SLICE_NORTH_WEST
20 SLICE_WEST = qtpie.EIGHT_SLICE_PIE.SLICE_WEST
21 SLICE_SOUTH_WEST = qtpie.EIGHT_SLICE_PIE.SLICE_SOUTH_WEST
22 SLICE_SOUTH = qtpie.EIGHT_SLICE_PIE.SLICE_SOUTH
23 SLICE_SOUTH_EAST = qtpie.EIGHT_SLICE_PIE.SLICE_SOUTH_EAST
24 SLICE_EAST = qtpie.EIGHT_SLICE_PIE.SLICE_EAST
25 SLICE_NORTH_EAST = qtpie.EIGHT_SLICE_PIE.SLICE_NORTH_EAST
27 MAX_ANGULAR_SLICES = qtpie.EIGHT_SLICE_PIE.MAX_ANGULAR_SLICES
29 SLICE_DIRECTIONS = qtpie.EIGHT_SLICE_PIE.SLICE_DIRECTIONS
31 SLICE_DIRECTION_NAMES = qtpie.EIGHT_SLICE_PIE.SLICE_DIRECTION_NAMES
34 self._layout = QtGui.QGridLayout()
35 self._widget = QtGui.QWidget()
36 self._widget.setLayout(self._layout)
44 def add_pie(self, row, column, pieButton):
45 assert len(pieButton) == 8
46 self._layout.addWidget(pieButton, row, column, QtCore.Qt.AlignCenter)
47 self.__cells[(row, column)] = pieButton
49 def get_pie(self, row, column):
50 return self.__cells[(row, column)]
53 class KeyboardModifier(object):
55 def __init__(self, name):
62 return self.lock or self.once
64 def on_toggle_lock(self, *args, **kwds):
65 self.lock = not self.lock
67 def on_toggle_once(self, *args, **kwds):
68 self.once = not self.once
74 def parse_keyboard_data(text):
78 def _enumerate_pie_slices(pieData, iconPaths):
79 for direction, directionName in zip(
80 PieKeyboard.SLICE_DIRECTIONS, PieKeyboard.SLICE_DIRECTION_NAMES
82 if directionName in pieData:
83 sliceData = pieData[directionName]
85 action = QtGui.QAction(None)
87 action.setText(sliceData["text"])
91 relativeIconPath = sliceData["path"]
95 for iconPath in iconPaths:
96 absIconPath = os.path.join(iconPath, relativeIconPath)
97 if os.path.exists(absIconPath):
98 action.setIcon(QtGui.QIcon(absIconPath))
100 pieItem = qtpie.QActionPieItem(action)
101 actionToken = sliceData["action"]
103 pieItem = qtpie.PieFiling.NULL_CENTER
105 yield direction, pieItem, actionToken
108 def load_keyboard(keyboardName, dataTree, keyboard, keyboardHandler, iconPaths):
109 for (row, column), pieData in dataTree.iteritems():
110 pieItems = list(_enumerate_pie_slices(pieData, iconPaths))
111 assert pieItems[0][0] == PieKeyboard.SLICE_CENTER, pieItems[0]
112 _, center, centerAction = pieItems.pop(0)
114 pieButton = qtpie.QPieButton(center)
115 pieButton.set_center(center)
116 keyboardHandler.map_slice_action(center, centerAction)
117 for direction, pieItem, action in pieItems:
118 pieButton.insertItem(pieItem)
119 keyboardHandler.map_slice_action(pieItem, action)
120 keyboard.add_pie(row, column, pieButton)
123 class KeyboardHandler(object):
125 def __init__(self, keyhandler):
126 self.__keyhandler = keyhandler
127 self.__commandHandlers = {}
128 self.__modifiers = {}
129 self.__sliceActions = {}
131 self.register_modifier("Shift")
132 self.register_modifier("Super")
133 self.register_modifier("Control")
134 self.register_modifier("Alt")
136 def register_command_handler(self, command, handler):
137 # @todo Look into hooking these up directly to the pie actions
138 self.__commandHandlers["[%s]" % command] = handler
140 def unregister_command_handler(self, command):
141 # @todo Look into hooking these up directly to the pie actions
142 del self.__commandHandlers["[%s]" % command]
144 def register_modifier(self, modifierName):
145 mod = KeyboardModifier(modifierName)
146 self.register_command_handler(modifierName, mod.on_toggle_lock)
147 self.__modifiers["<%s>" % modifierName] = mod
149 def unregister_modifier(self, modifierName):
150 self.unregister_command_handler(modifierName)
151 del self.__modifiers["<%s>" % modifierName]
153 def map_slice_action(self, slice, action):
154 callback = lambda direction: self(direction, action)
155 slice.action().triggered.connect(callback)
156 self.__sliceActions[slice] = (action, callback)
158 def __call__(self, direction, action):
161 for mod in self.__modifiers.itervalues()
165 needResetOnce = False
166 if action.startswith("[") and action.endswith("]"):
167 commandName = action[1:-1]
168 if action in self.__commandHandlers:
169 self.__commandHandlers[action](commandName, activeModifiers)
172 warnings.warn("Unknown command: [%s]" % commandName)
173 elif action.startswith("<") and action.endswith(">"):
174 modName = action[1:-1]
175 for mod in self.__modifiers.itervalues():
176 if mod.name == modName:
180 warnings.warn("Unknown modifier: <%s>" % modName)
182 self.__keyhandler(action, activeModifiers)
186 for mod in self.__modifiers.itervalues():