me2 beats
me2 beats

Reputation: 824

Disabling text wrapping in TextInput

Is there a way to disable text wrapping in TextInput widget? That is, I still would like to have line breaks, but I don’t want to wrap words inside a paragraph. So it seems multiline=False is not what I'm looking for

Update: I mean there's "Word Wrap" option in Windows (windows 7 for example) Microsoft Notepad (Format - Word Wrap). I want to disable this option in kivy TextInput

Upvotes: 1

Views: 672

Answers (1)

John Anderson
John Anderson

Reputation: 38822

I don't do Windows, but that sounds like horizontal scrolling to me. The TextInput does horizontal scrolling by default if you set multiline to False, but not when multiline is True. So here is a hack to put a TextInput inside a ScrollView to provide horizontal scrolling when multiline is True:

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.textinput import TextInput


class MyTextInput(TextInput):
    minimum_width = NumericProperty(1)

    def on_cursor(self, instance, newPos):
        # determine scroll position of parent ScrollView if multiline is True
        if not (isinstance(self.parent, ScrollView) and self.multiline):
            return super(MyTextInput, self).on_cursor(instance, newPos)
        if newPos[0] == 0:
            self.parent.scroll_x = 0
        else:
            over_width = self.width - self.parent.width
            if over_width <= 0.0:
                return super(MyTextInput, self).on_cursor(instance, newPos)
            view_start = over_width * self.parent.scroll_x
            view_end = view_start + self.parent.width
            offset = self.cursor_offset()
            desired_view_start = offset - 5
            desired_view_end = offset + self.padding[0] + self.padding[2] + self.cursor_width + 5
            if desired_view_start < view_start:
                self.parent.scroll_x = max(0, desired_view_start / over_width)
            elif desired_view_end > view_end:
                self.parent.scroll_x = min(1, (desired_view_end - self.parent.width) / over_width)
        return super(MyTextInput, self).on_cursor(instance, newPos)

    def on_text(self, instance, newText):
        # calculate minimum width
        width_calc = 0
        for line_label in self._lines_labels:
            width_calc = max(width_calc, line_label.width + 20)   # add 20 to avoid automatically creating a new line
        self.minimum_width = width_calc


theRoot = Builder.load_string('''
ScrollView:
    id: scroller
    effect_cls: 'ScrollEffect'  # keeps from scrolling to far
    MyTextInput:
        size_hint: (None, 1)
        width: max(self.minimum_width, scroller.width)
''')

class TI_in_SV(App):
    def build(self):
        return theRoot

TI_in_SV().run()

Note that MyTextInput extends TextInput.

Upvotes: 3

Related Questions