4 from __future__ import division
9 from PyQt4 import QtGui
10 from PyQt4 import QtCore
15 class PieKeyboard(object):
27 MAX_ANGULAR_SLICES = 8
41 SLICE_DIRECTION_NAMES = [
53 def __init__(self, rows, columns):
54 self._layout = QtGui.QGridLayout()
62 def add_pie(self, row, column, pieButton):
63 assert len(pieButton) == 8
64 self._layout.addWidget(pieButton, row, column)
65 self.__cells[(row, column)] = pieButton
67 def get_pie(self, row, column):
68 return self.__cells[(row, column)]
71 class KeyboardModifier(object):
73 def __init__(self, name):
80 return self.lock or self.once
82 def on_toggle_lock(self, *args, **kwds):
83 self.lock = not self.lock
85 def on_toggle_once(self, *args, **kwds):
86 self.once = not self.once
92 def parse_keyboard_data(text):
96 def _enumerate_pie_slices(pieData, iconPaths):
97 for direction, directionName in zip(
98 PieKeyboard.SLICE_DIRECTIONS, PieKeyboard.SLICE_DIRECTION_NAMES
100 if directionName in pieData:
101 sliceData = pieData[directionName]
103 action = QtGui.QAction(None)
105 action.setText(sliceData["text"])
109 relativeIconPath = sliceData["path"]
113 for iconPath in iconPaths:
114 absIconPath = os.path.join(iconPath, relativeIconPath)
115 if os.path.exists(absIconPath):
116 action.setIcon(QtGui.QIcon(absIconPath))
118 pieItem = qtpie.QActionPieItem(action)
120 pieItem = qtpie.PieFiling.NULL_CENTER
122 yield direction, pieItem, action
125 def load_keyboard(keyboardName, dataTree, keyboard, keyboardHandler, iconPaths):
126 for (row, column), pieData in dataTree.iteritems():
127 pieItems = list(_enumerate_pie_slices(pieData, iconPaths))
128 assert pieItems[0][0] == PieKeyboard.SLICE_CENTER, pieItems[0]
129 _, center, centerAction = pieItems.pop(0)
131 pieButton = qtpie.QPieButton(center)
132 pieButton.set_center(center)
133 for direction, pieItem, action in pieItems:
134 pieButton.insertItem(pieItem)
135 keyboard.add_pie(row, column, pieButton)
138 class KeyboardHandler(object):
140 def __init__(self, keyhandler):
141 self.__keyhandler = keyhandler
142 self.__commandHandlers = {}
143 self.__modifiers = {}
144 self.__sliceActions = {}
146 self.register_modifier("Shift")
147 self.register_modifier("Super")
148 self.register_modifier("Control")
149 self.register_modifier("Alt")
151 def register_command_handler(self, command, handler):
152 #@todo Make this handle multiple handlers or switch to gobject events
153 self.__commandHandlers["[%s]" % command] = handler
155 def unregister_command_handler(self, command):
156 #@todo Make this handle multiple handlers or switch to gobject events
157 del self.__commandHandlers["[%s]" % command]
159 def register_modifier(self, modifierName):
160 mod = KeyboardModifier(modifierName)
161 self.register_command_handler(modifierName, mod.on_toggle_lock)
162 self.__modifiers["<%s>" % modifierName] = mod
164 def unregister_modifier(self, modifierName):
165 self.unregister_command_handler(modifierName)
166 del self.__modifiers["<%s>" % modifierName]
168 def map_slice_action(self, slice, action):
169 self.__sliceActions[slice.name] = action
171 def __call__(self, pie, slice, direction):
173 action = self.__sliceActions[slice.name]
179 for mod in self.__modifiers.itervalues()
183 needResetOnce = False
184 if action.startswith("[") and action.endswith("]"):
185 commandName = action[1:-1]
186 if action in self.__commandHandlers:
187 self.__commandHandlers[action](commandName, activeModifiers)
190 warnings.warn("Unknown command: [%s]" % commandName)
191 elif action.startswith("<") and action.endswith(">"):
192 modName = action[1:-1]
193 for mod in self.__modifiers.itervalues():
194 if mod.name == modName:
198 warnings.warn("Unknown modifier: <%s>" % modName)
200 self.__keyhandler(action, activeModifiers)
204 for mod in self.__modifiers.itervalues():