Seite 2 von 2

Re: Gadget für CanvasGadget

Verfasst: 29.11.2011 21:45
von Kiffi
cOoki3druqs hat geschrieben:hm.. also zum editieren möchte ich nicht auf ein string gadget verzichten.. wie könnte ich das realisieren so dass es auch mitscrollt und sich innerhalb des canvas gadgets befindet?
wenn ich das richtig verstanden habe, dann ist ein CanvasGadget eher
ein aufgebohrtes ImagesGadget. Demzufolge müsstest Du die Gadgets,
die Du darauf platzieren willst, selber malen und auf die CanvasGadgets-
Events dementsprechend reagieren ('Combobox' aufklappen, Textcursor
in Deinem 'StringGadget' setzen, Buchstaben beim Eintippen selber malen,
etc.).

Vielleicht wäre für Deine Zwecke eher ein ScrollAreaGadget geeignet?

Ich habe mal auf die schnelle was zusammengehackt:

Code: Alles auswählen

EnableExplicit

Define.s sXML
Define   oXML

sXML = "<tbox>"
sXML + "<gadget type='StringGadget' caption='Vorname:' value='' />"
sXML + "<gadget type='StringGadget' caption='Nachname:' value='' />"
sXML + "<gadget type='StringGadget' caption='Strasse:' value='' />"
sXML + "<gadget type='StringGadget' caption='Platz:' value='' />"
sXML + "<gadget type='StringGadget' caption='Ort:' value='' />"
sXML + "<gadget type='ComboBoxGadget' caption='Land:' value='Deutschland|Oesterreich|Schweiz' />"
sXML + "<gadget type='StringGadget' caption='Telefon:' value='' />"
sXML + "</tbox>"

oXML = CatchXML(#PB_Any, @sXML, StringByteLength(sXML))

; #############

Structure sGadget
  Type.s
  Caption.s
  Value.s
EndStructure

Procedure ParseXml(oXml)
  
  Protected GadgetNode
  Protected GadgetNodeCounter
  
  Protected GadgetID
  Protected Gadget.sGadget
  Protected newY, Counter
  
  GadgetNodeCounter = 1
  
  newY = 5
  
  Repeat
    
    GadgetNode = XMLNodeFromPath(oXML, "tbox/gadget[" + Str(GadgetNodeCounter) + "]")
    
    If GadgetNode = 0
      Break
    EndIf
    
    ExamineXMLAttributes(GadgetNode)
    
    If ExamineXMLAttributes(GadgetNode)
      
      While NextXMLAttribute(GadgetNode)
        
        Select XMLAttributeName(GadgetNode)
            
          Case "type"    : Gadget\Type    = XMLAttributeValue(GadgetNode)
          Case "caption" : Gadget\Caption = XMLAttributeValue(GadgetNode)
          Case "value"   : Gadget\Value   = XMLAttributeValue(GadgetNode)
            
        EndSelect
        
      Wend
      
    EndIf
    
    TextGadget(#PB_Any, 5, newY, 100, 20, Gadget\Caption, #SS_CENTERIMAGE)
    
    Select Gadget\Type
        
      Case "StringGadget"
        
        GadgetID = StringGadget(#PB_Any, 120, newY, 150, 20, Gadget\Value)
        
      Case "ComboBoxGadget"
        
        GadgetID = ComboBoxGadget(#PB_Any, 120, newY, 150, -1)
        
        For Counter = 1 To CountString(Gadget\Value, "|") + 1
          AddGadgetItem(GadgetID, -1, StringField(Gadget\Value, Counter, "|"))
        Next
        
        
    EndSelect 
    
    SetXMLAttribute(GadgetNode, "GadgetID", Str(GadgetID))
    
    newY + 25
    
    GadgetNodeCounter + 1
    
  ForEver
  
EndProcedure

Procedure ProcessGadget(GadgetID, oXML)
  
  Protected GadgetNode
  Protected GadgetNodeCounter
  
  Repeat
    
    GadgetNode = XMLNodeFromPath(oXML, "tbox/gadget[" + Str(GadgetNodeCounter) + "]")
    
    If GadgetNode = 0
      Break
    EndIf
    
    ExamineXMLAttributes(GadgetNode)
    
    If ExamineXMLAttributes(GadgetNode)
      
      While NextXMLAttribute(GadgetNode)
        
        If XMLAttributeName(GadgetNode) = "GadgetID" And XMLAttributeValue(GadgetNode) = Str(GadgetID)
          
          SetXMLAttribute(GadgetNode, "value", GetGadgetText(GadgetID))
          
          Break 2 
          
        EndIf
        
        
      Wend
      
    EndIf
    
    GadgetNodeCounter + 1

  ForEver
  
  
EndProcedure

Define myWindow
Define myScrollAreaGadget
Define myButton
Define WWE, Quit

myWindow = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 300, 400, "tbox-Example")

myScrollAreaGadget = ScrollAreaGadget(#PB_Any, 5, 5, WindowWidth(myWindow) - 10, WindowHeight(myWindow) - 50, WindowWidth(myWindow) - 20, WindowHeight(myWindow) - 60)

ParseXml(RootXMLNode(oXML))

CloseGadgetList()

myButton = ButtonGadget(#PB_Any, 5, WindowHeight(myWindow) - 35, 100, 25, "Zeige ResultXml")

Repeat
  
  WWE = WaitWindowEvent()  
  
  Select WWE
      
    Case #PB_Event_Gadget
      
      If EventGadget()=myButton
        
        FormatXML(oXML, #PB_XML_ReFormat|#PB_XML_ReIndent)
        sXML = Space(ExportXMLSize(oXML))
        ExportXML(oXML, @sXML, Len(sXML))
        MessageRequester("", PeekS(@sXML,-1,#PB_UTF8))
        
      Else
        
        ProcessGadget(EventGadget(), RootXMLNode(oXML))
        
      EndIf
      
    Case #PB_Event_CloseWindow
      
      Quit = #True
      
  EndSelect
  
Until Quit = #True
Grüße ... Kiffi

// Edit: CatchXml() mit StringByteLength() versehen. Danke an Thomas!
// Edit2: Fehlerhafte Ausgabe des ResultXml bei eingeschalteter Unicode-Option behoben. Danke an Danilo!

Re: Gadget für CanvasGadget

Verfasst: 29.11.2011 21:54
von ts-soft
@Kiffi :allright:
Schönes Beispiel, nur Zeile 16 noch in:

Code: Alles auswählen

oXML = CatchXML(#PB_Any, @sXML, StringByteLength(sXML))
und es klappt in allen Compilermodes.

Gruß
Thomas

Re: Gadget für CanvasGadget

Verfasst: 29.11.2011 21:58
von Kiffi
ts-soft hat geschrieben:nur Zeile 16 noch in:

Code: Alles auswählen

oXML = CatchXML(#PB_Any, @sXML, StringByteLength(sXML))
und es klappt in allen Compilermodes.
danke für den Tipp! Vergesse ich immer wieder :oops: Ist jetzt oben korrigiert.

Grüße ... Kiffi

Re: Gadget für CanvasGadget

Verfasst: 30.11.2011 02:45
von STARGÅTE
So, wie versprochen hier mal das Beispiel für das editieren von Strings im CanvasGadget:

Code: Alles auswählen

Structure StringEditor
	String.s            ; veränderbare Zeichenkette
	CursorPosition.i    ; aktuelle Cursorposition
	FixCursorPosition.i ; verankerte Cursorposition
	CursorLength.i
	Time.i
EndStructure

Procedure StringEditor_GetMousePosition(Gadget.i, String.s, X.i, Y.i)
	Protected Length = Len(String)
	Protected MouseX.i, MouseY.i, MinDistance.f = Infinity(), CursorPosition.i, Distance.f, CursorX.i, CursorY.i, Index.i
	MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
	MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
	StartDrawing(CanvasOutput(Gadget))
	CursorY = Y + TextHeight(String)/2
	For Index = 0 To Length
		CursorX = X + TextWidth(Left(String, Index))
		Distance = (MouseX-CursorX)*(MouseX-CursorX)+(MouseY-CursorY)*(MouseY-CursorY)
		If Distance < MinDistance
			MinDistance = Distance
			CursorPosition = Index
		EndIf
	Next
	StopDrawing()
	If Not IsInfinity(MinDistance)
		ProcedureReturn CursorPosition
	Else
		ProcedureReturn -1
	EndIf
EndProcedure

Procedure StringEditor_DeleteSelection(*StringEditor.StringEditor)
	With *StringEditor
		If \CursorLength < 0
			\String = Left(\String, \FixCursorPosition) + Mid(\String, \CursorPosition+1)
			\CursorPosition = \FixCursorPosition
			\CursorLength = 0
			ProcedureReturn #True
		ElseIf \CursorLength > 0
			\String = Left(\String, \CursorPosition) + Mid(\String, \FixCursorPosition+1)
			\FixCursorPosition = \CursorPosition
			\CursorLength = 0
			ProcedureReturn #True
		EndIf
	EndWith
EndProcedure

Procedure StringEditorEvent(*StringEditor.StringEditor, Gadget.i, X.i, Y.i, WindowEvent.i)
	Protected Event.i = #False
	Protected CursorPosition.i
	Static SelectMode = #False
	With *StringEditor
		Select WindowEvent
			Case #PB_Event_Gadget
				If EventGadget() = Gadget
					Select EventType()
						Case #PB_EventType_LeftButtonDown
							CursorPosition = StringEditor_GetMousePosition(Gadget, \String, X, Y)
							If CursorPosition <> -1
								\CursorPosition = CursorPosition
								\FixCursorPosition = CursorPosition
								\CursorLength = 0
								Event = #True
							EndIf
							SelectMode = #True 
						Case #PB_EventType_MouseMove
							If SelectMode
								CursorPosition = StringEditor_GetMousePosition(Gadget, \String, X, Y)
								If CursorPosition <> -1 And \CursorPosition <> CursorPosition
									\CursorPosition = CursorPosition
									\CursorLength = \FixCursorPosition-CursorPosition
									Event = #True
								EndIf
							EndIf
						Case #PB_EventType_LeftButtonUp
							SelectMode = #False
						Case #PB_EventType_Input
							StringEditor_DeleteSelection(*StringEditor)
							\String = Left(\String, \CursorPosition) + Chr(GetGadgetAttribute(Gadget, #PB_Canvas_Input)) + Mid(\String, \CursorPosition+1)
							\CursorPosition + 1
							Event = #True
						Case #PB_EventType_KeyDown
							Select GetGadgetAttribute(Gadget, #PB_Canvas_Key)
								Case #PB_Shortcut_Left
									If \CursorPosition > 0 : \CursorPosition - 1 : EndIf
									Event = #True
								Case #PB_Shortcut_Right
									If \CursorPosition < Len(\String) : \CursorPosition + 1 : EndIf
									Event = #True
								Case #PB_Shortcut_End
									\CursorPosition = Len(\String)
									Event = #True
								Case #PB_Shortcut_Home
									\CursorPosition = 0
									Event = #True
								Case #PB_Shortcut_Back
									If Not StringEditor_DeleteSelection(*StringEditor)
										If \CursorPosition > 0
											\String = Left(\String, \CursorPosition-1) + Mid(\String, \CursorPosition+1)
											\CursorPosition - 1
										EndIf
									EndIf
									Event = #True
								Case #PB_Shortcut_Delete
									If Not StringEditor_DeleteSelection(*StringEditor)
										If \CursorPosition < Len(\String)
											\String = Left(\String, \CursorPosition) + Mid(\String, \CursorPosition+2)
										EndIf
									EndIf
									Event = #True
							EndSelect
					EndSelect
				EndIf
		EndSelect
		If Event = #True
			\Time = ElapsedMilliseconds()+500
			ProcedureReturn #True
		EndIf
	EndWith
EndProcedure

Procedure GetCursorPosition(*StringEditor.StringEditor)
	ProcedureReturn TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition))
EndProcedure

Procedure GetCursorLength(*StringEditor.StringEditor)
	ProcedureReturn TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition+*StringEditor\CursorLength)) - TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition))
EndProcedure



Enumeration
	#Window
	#Gadget
	#Timer
EndEnumeration

Global MyText.StringEditor\String = "Hallo Welt!"

Procedure Update(On=#False)
	Static Blink
	If On
		Blink = 1
	Else
		Blink = 1-Blink
	EndIf
	With MyText
		StartDrawing(CanvasOutput(#Gadget))
		Box(0, 0, 800, 600, $FFFFFFFF)
		DrawText(50, 50, MyText\String, $FF000000, $FFFFFFFFF)
		DrawingMode(#PB_2DDrawing_XOr)
		If MyText\CursorLength < 0
			Box(50+GetCursorPosition(@MyText)+GetCursorLength(@MyText), 50, -GetCursorLength(@MyText), TextHeight(" "))
		ElseIf MyText\CursorLength > 0
			Box(50+GetCursorPosition(@MyText)+1, 50, GetCursorLength(@MyText)-1, TextHeight(" "))
		EndIf
		DrawingMode(#PB_2DDrawing_Default)
		If Blink = 1
			Line(50+GetCursorPosition(@MyText), 50, 1, TextHeight(" "), $FF000000)
		EndIf
		StopDrawing()
	EndWith
EndProcedure


OpenWindow(#Window, 0, 0, 800, 600, "StringEditor", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
	CanvasGadget(#Gadget, 0, 0, 800, 600, #PB_Canvas_Keyboard)
	SetGadgetAttribute(#Gadget, #PB_Canvas_Cursor, #PB_Cursor_IBeam)
	Update()
	
	AddWindowTimer(#Window, #Timer, 250)
	
Repeat
	
	Event = WaitWindowEvent()
	If StringEditorEvent(@MyText, #Gadget, 50, 50, Event)
		Update(#True)
	EndIf
	Select Event
		Case #PB_Event_CloseWindow
			End
		Case #PB_Event_Timer
			Select EventTimer()
				Case #Timer
					Update()
			EndSelect
	EndSelect
	
ForEver

Re: Gadget für CanvasGadget

Verfasst: 30.11.2011 11:31
von c4s
@Kiffi, @STARGÅTE
Hui, gleich zwei sehr hilfreiche und nützliche Codes. Danke euch beiden! :allright:

Re: Gadget für CanvasGadget

Verfasst: 30.11.2011 11:45
von Danilo
ts-soft hat geschrieben:@Kiffi :allright:
Schönes Beispiel, nur Zeile 16 noch in:

Code: Alles auswählen

oXML = CatchXML(#PB_Any, @sXML, StringByteLength(sXML))
und es klappt in allen Compilermodes.
In dem MessageRequester zeigt es trotzdem chinesische Zeichen.

Das XML-Zeug arbeitet wohl nur mit ASCII oder UTF8 und schreibt es auch so.
Ich musste

Code: Alles auswählen

MessageRequester("", sXML)
noch zu

Code: Alles auswählen

MessageRequester("", PeekS(@sXML,-1,#PB_UTF8))
ändern, damit es mit Unicode (mein Default) richtig angezeigt wird.

Re: Gadget für CanvasGadget

Verfasst: 30.11.2011 11:57
von Kiffi
Danilo hat geschrieben:In dem MessageRequester zeigt es trotzdem chinesische Zeichen.
Danke für den Tipp und die Lösung! Ist oben korrigiert worden.

Grüße ... Kiffi

Re: Gadget für CanvasGadget

Verfasst: 30.10.2016 21:11
von mestnyi
TextWidth() work bad

Code: Alles auswählen

EnableExplicit

Enumeration
  #Window
  #Gadget
  #Gadget1
  #Timer
EndEnumeration

Structure StringEditor
  String.s            ; veränderbare Zeichenkette
  CursorPosition.i    ; aktuelle Cursorposition
  FixCursorPosition.i ; verankerte Cursorposition
  CursorLength.i
  Time.i
  
  Array Length.i(0)
  Map TextWidth.i()
EndStructure

Global MyText.StringEditor, ReadString.S
Define i
For i=0 To 100
  If i = 22 Or i = 42 Or i = 62 Or i = 82
    ReadString.S + #CRLF$
  EndIf
  ReadString.S + Str(i)+"Hallo "
Next
MyText.StringEditor\String = ReadString.S
Global Txt_X = 3, Txt_Y = 3

Procedure _DrawText(X,Y,Text.S, FrontColor, BackColor)
  With MyText
    Protected LeftText.S = Left(Text.S, \CursorPosition)
    Protected CursorPos = TextWidth(LeftText.S)
    Protected CursorLen = TextWidth(Left(Text.S, \CursorPosition+\CursorLength)) - CursorPos
    
    If \CursorLength
      ;DrawText(X, Y, Text.S, FrontColor, BackColor )
      DrawText(X, Y, LeftText.S, FrontColor, BackColor )
      DrawText(X+CursorPos+CursorLen, Y, Mid(Text.S, \FixCursorPosition + 1, Len(Text.S)-\FixCursorPosition), FrontColor, BackColor )
      
      If \CursorLength < 0
        DrawText(X+CursorPos+CursorLen, Y, Mid(Text.S, \FixCursorPosition + 1, Abs(\CursorLength)), $FFFFFF, $D89900 )
      ElseIf \CursorLength > 0
        DrawText(X+CursorPos+1, Y, Mid(Text.S, \CursorPosition + 1, Abs(\CursorLength)), $FFFFFF, $D89900 )
      EndIf
    Else
      DrawText(X, Y, Text.S, FrontColor, BackColor )
    EndIf
  EndWith
EndProcedure

Procedure _TextWidth(Text.S,i)
  
  Static  Result
  ;For i = 0 To Length;Len(Text.S)
  If i = 0
    Result = 0
  EndIf
  Result+MyText\TextWidth(Mid(Text.S, i , 1))
  ;Next
  ProcedureReturn Result
EndProcedure

Procedure StringEditor_GetMousePosition(Gadget.i, String.s, X.i, Y.i)
  Protected Length = Len(String)
  Protected MouseX.i, MouseY.i, MinDistance.f = Infinity(), CursorPosition.i, Distance.f, CursorX.i, CursorY.i, Index.i
  MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
  MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
  
  StartDrawing(CanvasOutput(Gadget))
  DrawingFont(GetGadgetFont(#PB_Default))
  
  CursorY = Y + TextHeight(String)/2
  For Index = 0 To Length
    ;CursorX = X + TextWidth(Left(String, Index))
    CursorX = X + _TextWidth(Left(String, Index),Index)
    
    Distance = (MouseX-CursorX)*(MouseX-CursorX)+(MouseY-CursorY)*(MouseY-CursorY)
    If Distance < MinDistance
      MinDistance = Distance
      CursorPosition = Index
    EndIf
  Next
  
  StopDrawing()
  
  If Not IsInfinity(MinDistance)
    ProcedureReturn CursorPosition
  Else
    ProcedureReturn -1
  EndIf
EndProcedure

Procedure StringEditor_DeleteSelection(*StringEditor.StringEditor)
  With *StringEditor
    If \CursorLength < 0
      \String = Left(\String, \FixCursorPosition) + Mid(\String, \CursorPosition+1)
      \CursorPosition = \FixCursorPosition
      \CursorLength = 0
      ProcedureReturn #True
    ElseIf \CursorLength > 0
      \String = Left(\String, \CursorPosition) + Mid(\String, \FixCursorPosition+1)
      \FixCursorPosition = \CursorPosition
      \CursorLength = 0
      ProcedureReturn #True
    EndIf
  EndWith
EndProcedure

Procedure StringEditorEvent(*StringEditor.StringEditor, Gadget.i, X.i, Y.i, WindowEvent.i)
  Protected Event.i = #False
  Protected CursorPosition.i
  Static SelectMode = #False
  With *StringEditor
    Select WindowEvent
      Case #PB_Event_Gadget
        If EventGadget() = Gadget
          Select EventType()
            Case #PB_EventType_LeftButtonDown
              CursorPosition = StringEditor_GetMousePosition(Gadget, \String, X, Y)
              If CursorPosition <> -1
                \CursorPosition = CursorPosition
                \FixCursorPosition = CursorPosition
                \CursorLength = 0
                Event = #True
              EndIf
              SelectMode = #True 
            Case #PB_EventType_MouseMove
              If SelectMode
                CursorPosition = StringEditor_GetMousePosition(Gadget, \String, X, Y)
                If CursorPosition <> -1 And \CursorPosition <> CursorPosition
                  \CursorPosition = CursorPosition
                  \CursorLength = \FixCursorPosition-CursorPosition
                  Event = #True
                EndIf
              EndIf
            Case #PB_EventType_LeftButtonUp
              SelectMode = #False
            Case #PB_EventType_Input
              StringEditor_DeleteSelection(*StringEditor)
              \String = Left(\String, \CursorPosition) + Chr(GetGadgetAttribute(Gadget, #PB_Canvas_Input)) + Mid(\String, \CursorPosition+1)
              \CursorPosition + 1
              Event = #True
            Case #PB_EventType_KeyDown
              Select GetGadgetAttribute(Gadget, #PB_Canvas_Key)
                Case #PB_Shortcut_Left
                  If \CursorPosition > 0 : \CursorPosition - 1 : EndIf
                  Event = #True
                Case #PB_Shortcut_Right
                  If \CursorPosition < Len(\String) : \CursorPosition + 1 : EndIf
                  Event = #True
                Case #PB_Shortcut_End
                  \CursorPosition = Len(\String)
                  Event = #True
                Case #PB_Shortcut_Home
                  \CursorPosition = 0
                  Event = #True
                Case #PB_Shortcut_Back
                  If Not StringEditor_DeleteSelection(*StringEditor)
                    If \CursorPosition > 0
                      \String = Left(\String, \CursorPosition-1) + Mid(\String, \CursorPosition+1)
                      \CursorPosition - 1
                    EndIf
                  EndIf
                  Event = #True
                Case #PB_Shortcut_Delete
                  If Not StringEditor_DeleteSelection(*StringEditor)
                    If \CursorPosition < Len(\String)
                      \String = Left(\String, \CursorPosition) + Mid(\String, \CursorPosition+2)
                    EndIf
                  EndIf
                  Event = #True
              EndSelect
          EndSelect
        EndIf
    EndSelect
    If Event = #True
      \Time = ElapsedMilliseconds()+500
      ProcedureReturn #True
    EndIf
  EndWith
EndProcedure

Procedure GetCursorPosition(*StringEditor.StringEditor)
  ProcedureReturn TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition))
EndProcedure

Procedure GetCursorLength(*StringEditor.StringEditor)
  ProcedureReturn TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition+*StringEditor\CursorLength)) - TextWidth(Left(*StringEditor\String, *StringEditor\CursorPosition))
EndProcedure



Procedure Update(On=#False)
  Static Blink
  If On
    Blink = 1
  Else
    Blink = 1-Blink
  EndIf
  With MyText
    StartDrawing(CanvasOutput(#Gadget))
    DrawingFont(GetGadgetFont(#PB_Default))
    Protected Width = OutputWidth()
    Protected Height = OutputHeight()
    
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(0, 0, Width, Height, 0)
    DrawingMode(#PB_2DDrawing_Default)
    Box(1, 1, Width-2, Height-2, $FFFFFFFF)
    
    _DrawText(Txt_X, Txt_Y, \String, $FF000000, $FFFFFFFFF)
    
;     DrawingMode(#PB_2DDrawing_XOr)
;     If \CursorLength < 0
;       Box(Txt_X+GetCursorPosition(@MyText)+GetCursorLength(@MyText), Txt_Y, -GetCursorLength(@MyText), TextHeight(" "))
;     ElseIf \CursorLength > 0
;       Box(Txt_X+GetCursorPosition(@MyText)+1, Txt_Y, GetCursorLength(@MyText)-1, TextHeight(" "))
;     EndIf
    
    DrawingMode(#PB_2DDrawing_Default)
    If Blink = 1
      Line(Txt_X+GetCursorPosition(@MyText), Txt_Y, 1, TextHeight(" "), $FF000000)
    EndIf
    StopDrawing()
  EndWith
EndProcedure


OpenWindow(#Window, 0, 0, 800, 600, "StringEditor", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
;StringGadget(#Gadget1, 0, 0, 800, 300, ReadString.S)
EditorGadget(#Gadget1, 0, 0, 800, 300)
SetGadgetText(#Gadget1,ReadString.S)

CanvasGadget(#Gadget, 0, 300, 800, 300, #PB_Canvas_Keyboard)
SetGadgetAttribute(#Gadget, #PB_Canvas_Cursor, #PB_Cursor_IBeam)

If StartDrawing(CanvasOutput(#Gadget))
  DrawingFont(GetGadgetFont(#PB_Default))
  For i=0 To Len(ReadString)
    ReDim MyText.StringEditor\Length(i)
    MyText.StringEditor\Length(i) = TextWidth(Mid(ReadString, i , 1))
    MyText.StringEditor\TextWidth(Mid(ReadString, i , 1))=MyText.StringEditor\Length(i)
  Next
  StopDrawing()
EndIf

Update()

AddWindowTimer(#Window, #Timer, 600)

Repeat
  
  Define Event = WaitWindowEvent()
  If StringEditorEvent(@MyText, #Gadget, Txt_X, Txt_Y, Event)
    Update(#True)
  EndIf
  Select Event
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Timer
      Select EventTimer()
        Case #Timer
          ;Update()
      EndSelect
  EndSelect
  
ForEver