[Python] TextReader & MultiTextLine

11/14/2014 18:06 xTryx#1
Hey,

1. Pythonseitiger TextReader
hier hab ich einen kleinen TextReader in Python für euch, durch den ihr Textdateien aus dem Clienten auslesen könnt inkl. Formatierung (automatisches [ENTER] nach jeder Zeile) und 3 Befehlen (if, elseif & else). Außerdem können Keywords angegeben werden, die er mit einem gewünschten Wert ersetzt. Somit könnt ihr sehr einfach "Template-Dateien" einlesen & "übersetzen" lassen. Hier eine kleine Beispiel-Datei, die der Reader lesen könnte:
Code:
Sei gegrüßt, [PLAYER_NAME]!

Ich habe dir den Auftrag gegeben, dass du
mir [ITEM_MAX_COUNT] Items bringen sollst.
[IF:[ITEM_COUNT]=0]
Du hast mir noch keins gebracht.
[ELSEIF:[ITEM_COUNT]=1]
Du hast mir bisher eins gebracht.
[ELSE]
Du hast mir bisher [ITEM_COUNT] Items gebracht.
[ENDIF]

Bring mir noch [ITEM_NEED_COUNT] Items!
Das dazugehörige Python-Script könnte in etwa so aussehen:
Code:
def GetTemplateText(fileName):
	import uiTextReader
	TextReader = uiTextReader.TextReader() # hier kann noch als Argument angegeben werden, ob nach jeder Zeile ein [ENTER] gemacht werden soll (TRUE = ja, FALSE = nein, standart: TRUE)

	TextReader.AddKeyWord("[PLAYER_NAME]", player.GetName())
	TextReader.AddKeyWord("[ITEM_NEED_COUNT]", 20)
	TextReader.AddKeyWord("[ITEM_COUNT]", 3)

	TextReader.LoadFile(fileName) # hier dateiname angeben (oder eben beim Funktionsaufruf wenn man es auf die Funktion bezieht, z.B.: "locale/de/template.txt")
	return TextReader.GetText()
Zurückgegeben wird folgender Text:
Code:
Sei gegrüßt, WieIchEbenHeiße!

Ich habe dir den Auftrag gegeben, dass du
mir 20 Items bringen sollst.
Du hast mir bisher 3 Items gebracht.

Bring mir noch 17 Items!
Download im Anhang.

2. Pythonseitige TextLine mit erzwungenem Zeilenumbruch
außerdem, als kleine Anbindung um von der [ENTER]-Rückgabe vom PyTextReader gebrauch zu machen, hab ich hier noch eine kleine Klasse für euch: die MultiTextLine-Klasse. Sie lässt sich - sobald sie wie gleich gesagt wird eingebaut wird - in jeder uiscript-Datei (z.B. inventorywindow.py etc.) durch den "type" : "multi_text" benutzen (dabei muss eine max. Breite festlegt werden durch "width", ansonsten einfach wie gewohnt als TextLine behandeln).

HowTo Einbauen:
1. Ihr öffnet eure ui.py (und entpackt davor eure root-Dateien).
2. Ihr sucht nach
Code:
class TextLine(Window):
3. Ihr fügt darüber folgenden Code ein:
Code:
class MultiTextLine(Window):

	RETURN_STRING = "[ENTER]"
	LINE_HEIGHT = 17

	def __init__(self):
		Window.__init__(self)

		self.lines = []
		self.alignCenter = FALSE
		self.text = ""

	def __del__(self):
		Window.__init__(self)

	def SetWidth(self, width):
		self.SetSize(width, self.GetHeight())
		self.SetText(self.GetText())

	def NewTextLine(self):
		line = TextLine()
		line.SetParent(self)
		line.SetPosition(0, len(self.lines) * self.LINE_HEIGHT)
		if self.alignCenter == TRUE:
			line.SetWindowHorizontalAlignCenter()
			line.SetHorizontalAlignCenter()
		line.Show()
		self.lines.append(line)

		return self.lines[len(self.lines) - 1]

	def Clear(self):
		self.text = ""
		self.lines = []

	def SetTextHorizontalAlignCenter(self):
		self.alignCenter = TRUE
		self.SetText(self.GetText())

	def SetText(self, text):
		self.Clear()

		self.text = text

		line = self.NewTextLine()
		pos = 0
		newStartPos = 0
		while pos < len(text):
			line.SetText(text[:pos+1])

			newLine = FALSE
			if len(text) >= pos + len(self.RETURN_STRING):
				if text[pos:pos+len(self.RETURN_STRING)] == self.RETURN_STRING:
					newLine = TRUE
					newStartPos = pos+len(self.RETURN_STRING)
			if newLine == FALSE and pos > 0:
				if line.GetTextWidth() > self.GetWidth():
					newLine = TRUE
					newStartPos = pos

			if newLine == TRUE:
				line.SetText(text[:pos])

				line = self.NewTextLine()
				text = text[newStartPos:]
				if text[:1] == " ":
					text = text[1:]
				pos = 0
			else:
				pos += 1

		self.SetSize(self.GetWidth(), len(self.lines) * self.LINE_HEIGHT)

	def GetText(self):
		return self.text
4. Ihr sucht nach
Code:
elif Type == "text":
5. Ihr fügt darüber folgenden Code ein:
Code:
			elif Type == "multi_text":
				parent.Children[Index] = MultiTextLine()
				parent.Children[Index].SetParent(parent)
				self.LoadElementMultiText(parent.Children[Index], ElementValue)
6. Ihr sucht nach
Code:
def LoadElementText(self, window, value):
7. Ihr fügt darüber folgenden Code ein:
Code:
## MultiTextLine
	def LoadElementMultiText(self, window, value):

		if TRUE == value.has_key("width"):
			window.SetWidth(int(value.get("width", 0)))

		if TRUE == value.has_key("text_horizontal_align"):
			if value["text_horizontal_align"] == "center":
				window.SetTextHorizontalAlignCenter()

		if TRUE == value.has_key("text"):
			window.SetText(value["text"])

		self.LoadDefaultData(window, value)

		return TRUE
So, das wars dann auch, ist alles nicht die einzige Möglichkeit es zu coden, es gibt noch andere Wege die ebenfalls zum Ziel führen und es ist möglicherweise auch nicht immer der allerperfekteste und performanteste Weg gewählt, aber zu Laggs führen wird es ganz bestimmt nicht. Dieser Code ist dazu da um zu funktionieren und nicht um perfekt zu sein.

Wünsche euch viel Spaß damit,

Liebe Grüße,
Das Cureya Team.
11/14/2014 18:17 Alergix2#2
Sehr interessant!
Weiter so
11/14/2014 18:23 Sir.?#3
Weiter so :)
11/14/2014 18:26 DEMONKING.#4
niice n usefull release . thank you :)
11/16/2014 17:17 sema1995#5
in the class ui.TextLine

if line.GetTextWidth() <--- dont exists the def GetTextWidth() <-- can u share it? Thanks.
11/16/2014 17:26 Lefloyd#6
Well just add this code below the other functions of the class (in the ui.py):
Code:
	def GetTextWidth(self):
		(w, h) = self.GetTextSize()
		return w

	def GetTextHeight(self):
		(w, h) = self.GetTextSize()
		return h
Kind Regards