Source code for lib.clui.textinput

# MusicDB,  a music manager with web-bases UI that focus on music.
# Copyright (C) 2017  Ralf Stemmer <ralf.stemmer@gmx.net>
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from lib.clui.text import Text
import unicodedata

[docs]class TextInput(Text): """ This class provides a simple one-line text input element. The cursor mentioned in this class documentation is not related to the cursor of the terminal! Each TextInput maintain its own cursor. Args: x,y (int): Position of the list view w (int): Width """ def __init__(self, x=0, y=0, w=0): Text.__init__(self) self.x = x self.y = y self.w = w self.data = "" # text buffer self.cursor= 0 self.offset= 0 # where to start printing - important when data is larger than input element self.textfg = "1;37" self.textbg = "44" self.cursorbg = "46"
[docs] def SetData(self, string): """ This method sets the data of the input element. The cursor points to the end of the input data. .. note:: The string gets normalized (NFC). All further manipulations of the string won't be normalized. Args: string (str): String that will be used as the input Returns: *Nothing* Raises: TypeError: When string is not of type string """ if type(string) != str: raise TypeError("Data must be of type string!") self.data = string self.data = unicodedata.normalize("NFC", self.data)
[docs] def GetData(self): """ Returns the string from the input element Returns: The input as string """ return self.data
[docs] def Draw(self): """ This method draws the input control and the cursor. The input elements color are white text on blue background. The element the cursor points to has a cyan background. Returns: *Nothing* """ # Print text segment character by character and handle special Unicode characters self.SetColor(self.textfg, self.textbg) self.SetCursor(self.x, self.y) string = self.data[self.offset:self.offset+self.w] string = string.ljust(self.w) self.PrintText(string) # Place cursor on text, or one character behind if end of text was reached self.SetCursor(self.x+self.cursor, self.y) self.SetBGColor(self.cursorbg) self.PrintText(string[self.cursor])
[docs] def HandleKey(self, key): """ This method handled the users input. The keys are expected as the method :meth:`lib.clui.text.Text.GetKey` returns. With the ``"right"`` and ``"left"`` key, the user can navigate through the text. With ``"backspace"`` the character left to the cursor gets removed. With ``"delete"`` the character right below the cursor. Each printable character gets inserted left to the cursor. Args: key (str): Key name that shall be handled Returns: *Nothing* """ # It is allowed to pass a key that is None, so just make a robust escape for values that cannot be handled # by the following code if type(key) != str: return if key == "left": if self.cursor > 0: self.cursor -= 1 elif self.offset > 0: self.offset -= 1 elif key == "right": if self.cursor < min(len(self.data), self.w-1): self.cursor += 1 elif self.offset + len(self.data) > self.w and self.offset+self.cursor < len(self.data): self.offset += 1 elif key == "home": self.cursor = 0 self.offset = 0 elif key == "end": self.cursor = min(len(self.data), self.w-1) if len(self.data) > self.w: self.offset = len(self.data)-self.w + 1 elif key == "backspace" and self.cursor > 0: self.data = self.data[:self.offset + self.cursor-1] + self.data[self.offset + self.cursor:] self.cursor -= 1 elif key == "delete" and self.cursor < len(self.data): self.data = self.data[:self.offset + self.cursor] + self.data[self.offset + self.cursor+1:] elif len(key) == 1 and key.isprintable(): self.data = self.data[:self.offset + self.cursor] + key + self.data[self.offset + self.cursor:] if self.cursor < min(len(self.data), self.w-1): self.cursor += 1 elif self.offset + len(self.data) >= self.w: self.offset += 1 self.Draw()
[docs]class NoTextInput(TextInput): """ This is a *read-only* variation of the :class:`~TextInput` element. Args: x,y (int): Position of the list view w (int): Width """ def __init__(self, x=0, y=0, w=0): TextInput.__init__(self, x, y, w) self.textfg = "1;36" self.textbg = "40" self.cursorbg = "40"
[docs] def HandleKey(self, key=None): """ This method does nothing. This is a read-only control element. Args: key: *will be ignored* Returns: *Nothing* """ pass
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4