Exemplo n.º 1
0
 def onBound(self):
     if hasattr(self.component, 'cursor'):
         self.component.delChild(self.component.cursor)
     self.activeColour = DEFAULT_TEXT_COLOUR_ACTIVE
     self.inactiveColour = DEFAULT_TEXT_COLOUR_INACTIVE
     text = self.component.text
     text.horizontalAnchor = 'LEFT'
     text.horizontalPositionMode = 'PIXEL'
     text.position.x = 0
     text.colour = self.inactiveColour
     if len(self.autoSelectionFonts) == 0:
         self.autoSelectionFonts = [self.component.text.font]
     self.cursor = BlinkingCursor()
     self.component.addChild(self.cursor.comp, 'cursor')
     self._updateCursor()
     self.cursor.enable(False)
     PyGUIBase.onBound(self)
     self._selectFontBestMatch()
Exemplo n.º 2
0
 def onBound(self):
     if hasattr(self.component, 'cursor'):
         self.component.delChild(self.component.cursor)
     self.activeColour = DEFAULT_TEXT_COLOUR_ACTIVE
     self.inactiveColour = DEFAULT_TEXT_COLOUR_INACTIVE
     text = self.component.text
     text.horizontalAnchor = 'LEFT'
     text.horizontalPositionMode = 'PIXEL'
     text.position.x = 0
     text.colour = self.inactiveColour
     if len(self.autoSelectionFonts) == 0:
         self.autoSelectionFonts = [self.component.text.font]
     self.cursor = BlinkingCursor()
     self.component.addChild(self.cursor.comp, 'cursor')
     self._updateCursor()
     self.cursor.enable(False)
     PyGUIBase.onBound(self)
     self._selectFontBestMatch()
Exemplo n.º 3
0
class EditField(PyGUIBase):
    factoryString = 'PyGUI.EditField'

    def __init__(self, component=None):
        PyGUIBase.__init__(self, component)
        self.cursorIndex = 0
        self.scrollInPixels = 0
        self.onEnter = None
        self.onEscape = None
        self.maxLength = 256
        self.enabled = True
        self.enableIME = False
        self.focusViaMouse = True
        self.focusObserver = None
        self.shouldAdjustClipping = False
        self.__externalKeyEventHandler = None
        self.__allowAutoDefocus = True
        if self.component is None:
            self.component = GUI.Window('system/maps/col_white.bmp')
            self.component.colour = (0, 0, 0, 255)
            self.component.materialFX = 'BLEND'
            self.component.width = 0.75
            self.component.height = 0.1
            self.component.heightMode = 'CLIP'
            self.component.widthMode = 'CLIP'
            self.component.minScroll = (-100, -100)
            self.component.maxScroll = (+100, +100)
            self.component.script = self
            self.onBound()
        self.autoSelectionFonts = ['default_medium.font']
        self.idealVisibleCharacters = 80
        registerDeviceListener(self)
        return

    def setExternalKeyEventHandler(self, cb):
        self.__externalKeyEventHandler = cb

    def onBound(self):
        if hasattr(self.component, 'cursor'):
            self.component.delChild(self.component.cursor)
        self.activeColour = DEFAULT_TEXT_COLOUR_ACTIVE
        self.inactiveColour = DEFAULT_TEXT_COLOUR_INACTIVE
        text = self.component.text
        text.horizontalAnchor = 'LEFT'
        text.horizontalPositionMode = 'PIXEL'
        text.position.x = 0
        text.colour = self.inactiveColour
        if len(self.autoSelectionFonts) == 0:
            self.autoSelectionFonts = [self.component.text.font]
        self.cursor = BlinkingCursor()
        self.component.addChild(self.cursor.comp, 'cursor')
        self._updateCursor()
        self.cursor.enable(False)
        PyGUIBase.onBound(self)
        self._selectFontBestMatch()

    def setEnabled(self, state):
        self.enabled = state
        if not state:
            self.focus(False)

    def fitVertically(self):
        heightMode = self.component.heightMode
        self.component.heightMode = 'PIXEL'
        _, self.component.height = self.component.text.stringDimensions('W')
        self.component.height *= getVPixelScalar()
        self.component.heightMode = heightMode

    def setText(self, text):
        c = self.component.text
        c.text = unicode(text[:self.maxLength])
        self.scrollInPixels = 0
        self.component.scroll.x = 0
        self.cursorIndex = len(c.text)
        self._updateCursor()

    def getText(self):
        return self.component.text.text

    def onLoad(self, dataSection):
        PyGUIBase.onLoad(self, dataSection)
        self.maxLength = dataSection.readInt('maxLength', self.maxLength)
        self.focusViaMouse = dataSection.readBool('focusViaMouse', True)
        self.enableIME = dataSection.readBool('enableIME', False)
        self.shouldAdjustClipping = dataSection.readBool(
            'shouldAdjustClipping', False)
        self.activeColour = dataSection.readVector4(
            'activeColour', DEFAULT_TEXT_COLOUR_ACTIVE)
        self.inactiveColour = dataSection.readVector4(
            'inactiveColour', DEFAULT_TEXT_COLOUR_INACTIVE)
        self.__allowAutoDefocus = dataSection.readBool('allowAutoDefocus',
                                                       True)
        self.idealVisibleCharacters = dataSection.readInt(
            'idealVisibleCharacters', self.idealVisibleCharacters)
        fonts = dataSection.readStrings('autoFont')
        if len(fonts) > 0:
            self.autoSelectionFonts = fonts

    def onSave(self, dataSection):
        PyGUIBase.onSave(self, dataSection)
        dataSection.writeInt('maxLength', self.maxLength)
        dataSection.writeBool('focusViaMouse', self.focusViaMouse)
        dataSection.writeBool('enableIME', self.enableIME)
        dataSection.writeBool('shouldAdjustClipping',
                              self.shouldAdjustClipping)
        dataSection.writeVector4('activeColour', self.activeColour)
        dataSection.writeVector4('inactiveColour', self.inactiveColour)
        dataSection.writeBool('allowAutoDefocus', self.__allowAutoDefocus)

    def addFocusObserver(self, focusObserver):
        self.focusObserver = focusObserver

    def handleKeyEvent(self, event):
        if not self.enabled:
            return False
        elif event.isMouseButton():
            return False
        else:
            c = self.component.text
            character = event.character
            handled = False
            touchCursor = False
            if event.isKeyDown():
                if event.key in [Keys.KEY_RETURN, Keys.KEY_NUMPADENTER]:
                    handled = True
                    if self.eventHandler is not None:
                        textString = c.text
                        self.eventHandler.onClick(c.text)
                    elif self.onEnter is not None:
                        self.onEnter(c.text)
                elif event.key == Keys.KEY_BACKSPACE:
                    if self.cursorIndex > 0:
                        c.text = c.text[:self.cursorIndex -
                                        1] + c.text[self.cursorIndex:]
                        self.cursorIndex -= 1
                        self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_DELETE:
                    if self.cursorIndex < len(c.text):
                        c.text = c.text[:self.cursorIndex] + c.text[
                            self.cursorIndex + 1:]
                        self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key in [Keys.KEY_LEFTARROW, Keys.KEY_RIGHTARROW]:
                    direction = 1 if event.key == Keys.KEY_RIGHTARROW else -1
                    if event.isCtrlDown():
                        self.cursorIndex = skipWord(c.text, self.cursorIndex,
                                                    direction)
                    else:
                        self.cursorIndex += direction
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_HOME:
                    self.cursorIndex = 0
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_END:
                    self.cursorIndex = len(self._getText().text)
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_ESCAPE:
                    if self.onEscape is not None:
                        self.onEscape()
                        handled = True
                elif character is not None:
                    self._insertString(character)
                    touchCursor = True
                    handled = True
                elif self.__externalKeyEventHandler is not None:
                    handled = self.__externalKeyEventHandler(event)
            if touchCursor:
                self.cursor.touch()
            return handled

    def handleMouseButtonEvent(self, comp, event):
        if self.enabled and event.isKeyDown(
        ) and event.key == Keys.KEY_LEFTMOUSE:
            setFocusedComponent(self.component)
            self.cursorIndex = self.screenToCharacterIndex(
                GUI.mcursor().position)
            self._updateCursor()
            self.cursor.touch()
            return True
        return False

    def handleIMEEvent(self, event):
        self._updateCursor()
        cursorPosClip = self.cursor.getScreenClipPosition()
        clipMin, clipMax = Utils.clipRegion(self.component)
        Helpers.PyGUI.IME.handleIMEEvent(event, cursorPosClip, clipMin,
                                         clipMax, self.component.text.font)
        return False

    def focus(self, state):
        if self.component.parent is not None and self.component.parent.script is not None:
            pscript = self.component.parent.script
            if hasattr(pscript, 'editFieldChangeFocus'):
                pscript.editFieldChangeFocus(self, state)
        if not self.enabled and state:
            setFocusedComponent(None)
            return
        else:
            BigWorld.ime.enabled = state and self.enableIME
            self.component.text.colour = self.activeColour if state else self.inactiveColour
            self._updateCursor()
            if not state:
                self.cursor.enable(False)
            return

    def screenToCharacterIndex(self, clipPos):
        """
                Given a screen clip space position, this will calculate
                the closest index into the edit field text.
        """
        oldWidthMode = self.component.widthMode
        self.component.widthMode = 'PIXEL'
        locPos = self.component.screenToLocal(clipPos)
        self.component.widthMode = oldWidthMode
        clickedAtPixel = locPos.x / getHPixelScalar()
        w = 0
        idx = 0
        text = self.component.text.text
        for c in text:
            cw = self.component.text.stringWidth(c)
            if clickedAtPixel <= w + cw / 2:
                return idx
            w += cw
            idx += 1

        return len(text)

    def allowAutoDefocus(self):
        return self.__allowAutoDefocus

    def _insertString(self, s):
        """
                Inserts the given string at the cursor position. Moves the cursor position
                along to the end of the inserted string.
        """
        c = self.component.text
        curLen = len(c.text)
        s = s[:max(self.maxLength - curLen, 0)]
        c.text = c.text[:self.cursorIndex] + s + c.text[self.cursorIndex:]
        self.cursorIndex += len(s)
        self._updateCursor()

    def _updateCursor(self):
        """
                Updates the cursor position, clamping it to a valid index range.
                The visual cursor representation is positioned.
        """
        text = self._getText()
        textLen = len(text.text)
        self.cursorIndex = max(self.cursorIndex, 0)
        self.cursorIndex = min(self.cursorIndex, textLen)
        cursorComp = self.cursor.comp
        cursorComp.position.x = text.stringWidth(
            text.text[:self.cursorIndex]) * getHPixelScalar()
        self._scrollIntoView()
        self.cursor.enable(self.enabled and not gotComposition()
                           and isFocusedComponent(self.component))

    def _scrollIntoView(self):
        """
                Makes sure the cursor is visible by applying an appropriate scroll amount.
        """
        hratio = getHPixelScalar()
        textArea = self.component
        widthMode = textArea.widthMode
        textArea.widthMode = 'PIXEL'
        textAreaWidth = textArea.width / hratio
        textArea.widthMode = widthMode
        cursorPosInPixels = textArea.cursor.position.x / hratio
        relCursorPos = cursorPosInPixels - self.scrollInPixels
        if relCursorPos > 0 and relCursorPos < textAreaWidth:
            return
        textComponent = textArea.text
        cursorIdx = self.cursorIndex
        if relCursorPos < 0:
            startingString = textComponent.text[cursorIdx -
                                                SCROLL_SKIP_AMOUNT:cursorIdx +
                                                1]
            startingWidth = textComponent.stringWidth(startingString)
            self.scrollInPixels = cursorPosInPixels - startingWidth
        elif relCursorPos > textAreaWidth - 5:
            trailingString = textComponent.text[cursorIdx - 1:cursorIdx +
                                                SCROLL_SKIP_AMOUNT]
            trailingWidth = textComponent.stringWidth(trailingString)
            self.scrollInPixels = cursorPosInPixels - textAreaWidth + trailingWidth
        self.scrollInPixels = max(self.scrollInPixels, 0)
        self.scrollInPixels = min(
            self.scrollInPixels,
            abs(self._textWidthInPixels() - textAreaWidth) + CURSOR_WIDTH)
        self._applyScroll()

    def _applyScroll(self):
        """
                Takes the internal scrollInPixels and applies it to the textArea.
        """
        scrollX = -self.scrollInPixels / (GUI.screenResolution()[0] * 0.5)
        scrollX = scrollX * getHPixelScalar()
        self.component.scroll = (scrollX, 0.0)

    def _getCursor(self):
        return self.component.cursor

    def _getText(self):
        return self.component.text

    def _textWidthInPixels(self):
        c = self._getText()
        return c.stringWidth(c.text)

    def _selectFontBestMatch(self):
        selectedFont = Utils.autoSelectFont(self.autoSelectionFonts,
                                            self.idealVisibleCharacters,
                                            self._widthInPixels(),
                                            self.component.text)
        self.component.text.font = selectedFont

    def _widthInPixels(self):
        widthMode = self.component.widthMode
        self.component.widthMode = 'PIXEL'
        w = self.component.width
        self.component.widthMode = widthMode
        return w / getHPixelScalar()

    def onRecreateDevice(self):
        self._selectFontBestMatch()
        self._updateCursor()
        if self.component.focus and self.enableIME:
            cursorPosClip = self.cursor.getScreenClipPosition()
            clipMin, clipMax = Utils.clipRegion(self.component)
            Helpers.PyGUI.IME.refresh(cursorPosClip, clipMin, clipMax,
                                      self.component.text.font)

    @staticmethod
    def create(self):
        return EditField().component
Exemplo n.º 4
0
class EditField(PyGUIBase):
    factoryString = 'PyGUI.EditField'

    def __init__(self, component = None):
        PyGUIBase.__init__(self, component)
        self.cursorIndex = 0
        self.scrollInPixels = 0
        self.onEnter = None
        self.onEscape = None
        self.maxLength = 256
        self.enabled = True
        self.enableIME = False
        self.focusViaMouse = True
        self.focusObserver = None
        self.shouldAdjustClipping = False
        self.__externalKeyEventHandler = None
        self.__allowAutoDefocus = True
        if self.component is None:
            self.component = GUI.Window('system/maps/col_white.bmp')
            self.component.colour = (0, 0, 0, 255)
            self.component.materialFX = 'BLEND'
            self.component.width = 0.75
            self.component.height = 0.1
            self.component.heightMode = 'CLIP'
            self.component.widthMode = 'CLIP'
            self.component.minScroll = (-100, -100)
            self.component.maxScroll = (+100, +100)
            self.component.script = self
            self.onBound()
        self.autoSelectionFonts = ['default_medium.font']
        self.idealVisibleCharacters = 80
        registerDeviceListener(self)
        return

    def setExternalKeyEventHandler(self, cb):
        self.__externalKeyEventHandler = cb

    def onBound(self):
        if hasattr(self.component, 'cursor'):
            self.component.delChild(self.component.cursor)
        self.activeColour = DEFAULT_TEXT_COLOUR_ACTIVE
        self.inactiveColour = DEFAULT_TEXT_COLOUR_INACTIVE
        text = self.component.text
        text.horizontalAnchor = 'LEFT'
        text.horizontalPositionMode = 'PIXEL'
        text.position.x = 0
        text.colour = self.inactiveColour
        if len(self.autoSelectionFonts) == 0:
            self.autoSelectionFonts = [self.component.text.font]
        self.cursor = BlinkingCursor()
        self.component.addChild(self.cursor.comp, 'cursor')
        self._updateCursor()
        self.cursor.enable(False)
        PyGUIBase.onBound(self)
        self._selectFontBestMatch()

    def setEnabled(self, state):
        self.enabled = state
        if not state:
            self.focus(False)

    def fitVertically(self):
        heightMode = self.component.heightMode
        self.component.heightMode = 'PIXEL'
        _, self.component.height = self.component.text.stringDimensions('W')
        self.component.height *= getVPixelScalar()
        self.component.heightMode = heightMode

    def setText(self, text):
        c = self.component.text
        c.text = unicode(text[:self.maxLength])
        self.scrollInPixels = 0
        self.component.scroll.x = 0
        self.cursorIndex = len(c.text)
        self._updateCursor()

    def getText(self):
        return self.component.text.text

    def onLoad(self, dataSection):
        PyGUIBase.onLoad(self, dataSection)
        self.maxLength = dataSection.readInt('maxLength', self.maxLength)
        self.focusViaMouse = dataSection.readBool('focusViaMouse', True)
        self.enableIME = dataSection.readBool('enableIME', False)
        self.shouldAdjustClipping = dataSection.readBool('shouldAdjustClipping', False)
        self.activeColour = dataSection.readVector4('activeColour', DEFAULT_TEXT_COLOUR_ACTIVE)
        self.inactiveColour = dataSection.readVector4('inactiveColour', DEFAULT_TEXT_COLOUR_INACTIVE)
        self.__allowAutoDefocus = dataSection.readBool('allowAutoDefocus', True)
        self.idealVisibleCharacters = dataSection.readInt('idealVisibleCharacters', self.idealVisibleCharacters)
        fonts = dataSection.readStrings('autoFont')
        if len(fonts) > 0:
            self.autoSelectionFonts = fonts

    def onSave(self, dataSection):
        PyGUIBase.onSave(self, dataSection)
        dataSection.writeInt('maxLength', self.maxLength)
        dataSection.writeBool('focusViaMouse', self.focusViaMouse)
        dataSection.writeBool('enableIME', self.enableIME)
        dataSection.writeBool('shouldAdjustClipping', self.shouldAdjustClipping)
        dataSection.writeVector4('activeColour', self.activeColour)
        dataSection.writeVector4('inactiveColour', self.inactiveColour)
        dataSection.writeBool('allowAutoDefocus', self.__allowAutoDefocus)

    def addFocusObserver(self, focusObserver):
        self.focusObserver = focusObserver

    def handleKeyEvent(self, event):
        if not self.enabled:
            return False
        elif event.isMouseButton():
            return False
        else:
            c = self.component.text
            character = event.character
            handled = False
            touchCursor = False
            if event.isKeyDown():
                if event.key in [Keys.KEY_RETURN, Keys.KEY_NUMPADENTER]:
                    handled = True
                    if self.eventHandler is not None:
                        textString = c.text
                        self.eventHandler.onClick(c.text)
                    elif self.onEnter is not None:
                        self.onEnter(c.text)
                elif event.key == Keys.KEY_BACKSPACE:
                    if self.cursorIndex > 0:
                        c.text = c.text[:self.cursorIndex - 1] + c.text[self.cursorIndex:]
                        self.cursorIndex -= 1
                        self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_DELETE:
                    if self.cursorIndex < len(c.text):
                        c.text = c.text[:self.cursorIndex] + c.text[self.cursorIndex + 1:]
                        self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key in [Keys.KEY_LEFTARROW, Keys.KEY_RIGHTARROW]:
                    direction = 1 if event.key == Keys.KEY_RIGHTARROW else -1
                    if event.isCtrlDown():
                        self.cursorIndex = skipWord(c.text, self.cursorIndex, direction)
                    else:
                        self.cursorIndex += direction
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_HOME:
                    self.cursorIndex = 0
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_END:
                    self.cursorIndex = len(self._getText().text)
                    self._updateCursor()
                    touchCursor = True
                    handled = True
                elif event.key == Keys.KEY_ESCAPE:
                    if self.onEscape is not None:
                        self.onEscape()
                        handled = True
                elif character is not None:
                    self._insertString(character)
                    touchCursor = True
                    handled = True
                elif self.__externalKeyEventHandler is not None:
                    handled = self.__externalKeyEventHandler(event)
            if touchCursor:
                self.cursor.touch()
            return handled

    def handleMouseButtonEvent(self, comp, event):
        if self.enabled and event.isKeyDown() and event.key == Keys.KEY_LEFTMOUSE:
            setFocusedComponent(self.component)
            self.cursorIndex = self.screenToCharacterIndex(GUI.mcursor().position)
            self._updateCursor()
            self.cursor.touch()
            return True
        return False

    def handleIMEEvent(self, event):
        self._updateCursor()
        cursorPosClip = self.cursor.getScreenClipPosition()
        clipMin, clipMax = Utils.clipRegion(self.component)
        Helpers.PyGUI.IME.handleIMEEvent(event, cursorPosClip, clipMin, clipMax, self.component.text.font)
        return False

    def focus(self, state):
        if self.component.parent is not None and self.component.parent.script is not None:
            pscript = self.component.parent.script
            if hasattr(pscript, 'editFieldChangeFocus'):
                pscript.editFieldChangeFocus(self, state)
        if not self.enabled and state:
            setFocusedComponent(None)
            return
        else:
            BigWorld.ime.enabled = state and self.enableIME
            self.component.text.colour = self.activeColour if state else self.inactiveColour
            self._updateCursor()
            if not state:
                self.cursor.enable(False)
            return

    def screenToCharacterIndex(self, clipPos):
        """
                Given a screen clip space position, this will calculate
                the closest index into the edit field text.
        """
        oldWidthMode = self.component.widthMode
        self.component.widthMode = 'PIXEL'
        locPos = self.component.screenToLocal(clipPos)
        self.component.widthMode = oldWidthMode
        clickedAtPixel = locPos.x / getHPixelScalar()
        w = 0
        idx = 0
        text = self.component.text.text
        for c in text:
            cw = self.component.text.stringWidth(c)
            if clickedAtPixel <= w + cw / 2:
                return idx
            w += cw
            idx += 1

        return len(text)

    def allowAutoDefocus(self):
        return self.__allowAutoDefocus

    def _insertString(self, s):
        """
                Inserts the given string at the cursor position. Moves the cursor position
                along to the end of the inserted string.
        """
        c = self.component.text
        curLen = len(c.text)
        s = s[:max(self.maxLength - curLen, 0)]
        c.text = c.text[:self.cursorIndex] + s + c.text[self.cursorIndex:]
        self.cursorIndex += len(s)
        self._updateCursor()

    def _updateCursor(self):
        """
                Updates the cursor position, clamping it to a valid index range.
                The visual cursor representation is positioned.
        """
        text = self._getText()
        textLen = len(text.text)
        self.cursorIndex = max(self.cursorIndex, 0)
        self.cursorIndex = min(self.cursorIndex, textLen)
        cursorComp = self.cursor.comp
        cursorComp.position.x = text.stringWidth(text.text[:self.cursorIndex]) * getHPixelScalar()
        self._scrollIntoView()
        self.cursor.enable(self.enabled and not gotComposition() and isFocusedComponent(self.component))

    def _scrollIntoView(self):
        """
                Makes sure the cursor is visible by applying an appropriate scroll amount.
        """
        hratio = getHPixelScalar()
        textArea = self.component
        widthMode = textArea.widthMode
        textArea.widthMode = 'PIXEL'
        textAreaWidth = textArea.width / hratio
        textArea.widthMode = widthMode
        cursorPosInPixels = textArea.cursor.position.x / hratio
        relCursorPos = cursorPosInPixels - self.scrollInPixels
        if relCursorPos > 0 and relCursorPos < textAreaWidth:
            return
        textComponent = textArea.text
        cursorIdx = self.cursorIndex
        if relCursorPos < 0:
            startingString = textComponent.text[cursorIdx - SCROLL_SKIP_AMOUNT:cursorIdx + 1]
            startingWidth = textComponent.stringWidth(startingString)
            self.scrollInPixels = cursorPosInPixels - startingWidth
        elif relCursorPos > textAreaWidth - 5:
            trailingString = textComponent.text[cursorIdx - 1:cursorIdx + SCROLL_SKIP_AMOUNT]
            trailingWidth = textComponent.stringWidth(trailingString)
            self.scrollInPixels = cursorPosInPixels - textAreaWidth + trailingWidth
        self.scrollInPixels = max(self.scrollInPixels, 0)
        self.scrollInPixels = min(self.scrollInPixels, abs(self._textWidthInPixels() - textAreaWidth) + CURSOR_WIDTH)
        self._applyScroll()

    def _applyScroll(self):
        """
                Takes the internal scrollInPixels and applies it to the textArea.
        """
        scrollX = -self.scrollInPixels / (GUI.screenResolution()[0] * 0.5)
        scrollX = scrollX * getHPixelScalar()
        self.component.scroll = (scrollX, 0.0)

    def _getCursor(self):
        return self.component.cursor

    def _getText(self):
        return self.component.text

    def _textWidthInPixels(self):
        c = self._getText()
        return c.stringWidth(c.text)

    def _selectFontBestMatch(self):
        selectedFont = Utils.autoSelectFont(self.autoSelectionFonts, self.idealVisibleCharacters, self._widthInPixels(), self.component.text)
        self.component.text.font = selectedFont

    def _widthInPixels(self):
        widthMode = self.component.widthMode
        self.component.widthMode = 'PIXEL'
        w = self.component.width
        self.component.widthMode = widthMode
        return w / getHPixelScalar()

    def onRecreateDevice(self):
        self._selectFontBestMatch()
        self._updateCursor()
        if self.component.focus and self.enableIME:
            cursorPosClip = self.cursor.getScreenClipPosition()
            clipMin, clipMax = Utils.clipRegion(self.component)
            Helpers.PyGUI.IME.refresh(cursorPosClip, clipMin, clipMax, self.component.text.font)

    @staticmethod
    def create(self):
        return EditField().component