basehandler.py (7508B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\services\ime\basehandler.py 2 import uthread 3 import blue 4 import inputmethod 5 from carbonui.control.singlelineedits.baseSingleLineEdit import BaseSingleLineEdit 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.fill import Fill 8 from carbonui.primitives.frame import Frame 9 from carbonui.control.editPlainText import EditPlainTextCore 10 from carbonui.control.label import LabelCore 11 import carbonui.const as uiconst 12 from carbonui.uicore import uicore 13 14 class BaseImeHandler(object): 15 16 def __init__(self): 17 self.insertOnType = False 18 self.currentLanguageMac = None 19 self.compositionWindow = None 20 self.compositionWindowParent = None 21 self.currentFocusWidget = None 22 self.allowedWidgetTypes = (EditPlainTextCore, BaseSingleLineEdit) 23 self.ime = inputmethod.Ime() 24 self._ResetCompositionString() 25 uthread.new(self._PositionWindowTasklet) 26 27 def __del__(self): 28 self._HideCompositionWindow() 29 30 def IsVisible(self): 31 return self.compositionWindow and self.compositionWindow.state != uiconst.UI_HIDDEN 32 33 def SetFocus(self, widget): 34 if self.currentFocusWidget: 35 self.KillFocus(self.currentFocusWidget) 36 self.currentFocusWidget = widget if self._IsImeWidget(widget) else None 37 self._SetImeState(True) 38 39 def KillFocus(self, widget): 40 if self.currentFocusWidget is not widget: 41 return 42 self._FinalizeCompositionString() 43 self._HideCompositionWindow() 44 self.currentFocusWidget = None 45 self._SetImeState(False) 46 47 def _SetImeState(self, enable): 48 enable = enable is True and self.currentFocusWidget is not None 49 return enable 50 51 def _IsImeWidget(self, widget): 52 return isinstance(widget, self.allowedWidgetTypes) 53 54 def _TruncateCompositionString(self, iNewStrLen = 0): 55 if not self._CheckFocusWidget() or not self.insertOnType: 56 return 57 cc = len(self.compositionString) 58 if iNewStrLen != 0 and iNewStrLen < cc: 59 return 60 _, char_handler = self.currentFocusWidget.FindEventHandler('OnChar') 61 _, key_down_handler = self.currentFocusWidget.FindEventHandler('OnKeyDown') 62 for i in xrange(cc - self.compositionCaretPosition): 63 if key_down_handler: 64 key_down_handler(uiconst.VK_RIGHT, 0) 65 66 for i in xrange(cc): 67 if char_handler: 68 char_handler(uiconst.VK_BACK, 0) 69 if key_down_handler: 70 key_down_handler(uiconst.VK_BACK, 0) 71 72 def _ResetCompositionString(self): 73 self.compositionCaretPosition = 0 74 self.compositionCaretWidth = 0 75 self.compositionString = '' 76 77 def _FinalizeCompositionString(self): 78 if not self.insertOnType: 79 self._SendCompositionString() 80 self._ResetCompositionString() 81 82 def _SendCompositionString(self): 83 if not self._CheckFocusWidget(): 84 return 85 _, handler = self.currentFocusWidget.FindEventHandler('OnChar') 86 if handler: 87 for char in self.compositionString: 88 handler(ord(char), 0) 89 90 def _ShowCompositionWindow(self): 91 if not self._CheckFocusWidget(): 92 return 93 fontsize = 14 94 if hasattr(self.currentFocusWidget, 'GetFontParams'): 95 fontsize = max(fontsize, self.currentFocusWidget.GetFontParams().fontsize) 96 if not self.compositionWindow: 97 self.compositionWindow = Container(name='IME', parent=uicore.desktop, align=uiconst.TOPLEFT, idx=0) 98 if self.compositionCaretWidth == 0: 99 self.compositionWindowCursor = Fill(parent=self.compositionWindow, align=uiconst.TOPLEFT, width=1, top=2, color=(1.0, 1.0, 1.0, 0.75)) 100 self.compositionWindowText = LabelCore(parent=self.compositionWindow, fontsize=fontsize, state=uiconst.UI_DISABLED, left=3, top=1) 101 Frame(parent=self.compositionWindow, color=(1, 1, 1, 0.3)) 102 Fill(parent=self.compositionWindow, color=(0.0, 0.0, 0.0, 1.0)) 103 self.compositionWindowText.fontsize = fontsize 104 self.compositionWindowText.text = self.compositionString 105 self.compositionWindow.state = uiconst.UI_HIDDEN if self.insertOnType else uiconst.UI_DISABLED 106 self.compositionWindow.width = self.compositionWindowText.textwidth + self.compositionWindowText.left * 2 107 self.compositionWindow.height = self.compositionWindowText.textheight + self.compositionWindowText.top * 2 108 if self.compositionCaretWidth == 0: 109 self.compositionWindowCursor.height = self.compositionWindow.height - self.compositionWindowCursor.top * 2 110 self.compositionWindowCursor.width = 1 111 self.compositionWindowCursor.align = uiconst.TOPLEFT 112 else: 113 self.compositionWindowCursor.height = 2 114 self.compositionWindowCursor.align = uiconst.BOTTOMLEFT 115 self.compositionWindowCursor.width = self._GetCompositionCursorPosition(self.compositionCaretWidth) 116 self.compositionWindowParent = self.currentFocusWidget 117 self.compositionWindowCursor.left = self.compositionWindowText.left + self._GetCompositionCursorPosition(self.compositionCaretPosition) 118 self._PositionCompositionWindow() 119 120 def _CheckFocusWidget(self): 121 if not self.currentFocusWidget or self.currentFocusWidget.destroyed: 122 self._HideCompositionWindow() 123 return False 124 return True 125 126 def _PositionWindowTasklet(self): 127 while getattr(uicore, 'uilib', None): 128 sleeptime = 5 if uicore.uilib.leftbtn else 250 129 if self.compositionWindow and self.compositionWindow.state == uiconst.UI_DISABLED: 130 self._PositionCompositionWindow() 131 blue.pyos.synchro.SleepWallclock(sleeptime) 132 133 def _PositionCompositionWindow(self): 134 edit = self.compositionWindowParent 135 if not edit or edit.destroyed: 136 return 137 if isinstance(edit, EditPlainTextCore): 138 entry = edit.GetActiveNode() 139 if not entry.panel: 140 return 141 panel = entry.panel 142 y = panel.absoluteTop - self.compositionWindow.height + 2 143 x = panel.absoluteLeft + panel.GetCursorOffset() - 1 144 elif isinstance(edit, BaseSingleLineEdit): 145 x, y = edit.get_absolute_caret_position() 146 y -= self.compositionWindow.height 147 elif hasattr(edit, 'get_ime_position'): 148 x, y = edit.get_ime_position(self.compositionWindow.height, self.compositionWindow.width) 149 else: 150 return 151 self.compositionWindow.left = min(uicore.desktop.width - self.compositionWindow.width - 6, x) 152 self.compositionWindow.top = y 153 154 def _HideCompositionWindow(self): 155 if self.compositionWindow: 156 self.compositionWindow.state = uiconst.UI_HIDDEN 157 self._ResetCompositionString() 158 159 def _GetCompositionCursorPosition(self, pos): 160 if not pos or not self.compositionString: 161 return 0 162 if getattr(self, 'compositionWindowText', None): 163 textWidth, textHeight = self.compositionWindowText.MeasureTextSize(self.compositionString[:pos], fontsize=self.compositionWindowText.fontsize) 164 else: 165 textWidth, textHeight = LabelCore.MeasureTextSize(self.compositionString[:pos]) 166 return textWidth