Gadget für CanvasGadget

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Gadget für CanvasGadget

Beitrag 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!
Zuletzt geändert von Kiffi am 30.11.2011 11:55, insgesamt 2-mal geändert.
a²+b²=mc²
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Gadget für CanvasGadget

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Gadget für CanvasGadget

Beitrag 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
a²+b²=mc²
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Gadget für CanvasGadget

Beitrag 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Gadget für CanvasGadget

Beitrag von c4s »

@Kiffi, @STARGÅTE
Hui, gleich zwei sehr hilfreiche und nützliche Codes. Danke euch beiden! :allright:
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: Gadget für CanvasGadget

Beitrag 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.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Gadget für CanvasGadget

Beitrag 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
a²+b²=mc²
mestnyi
Beiträge: 15
Registriert: 25.02.2014 22:00

Re: Gadget für CanvasGadget

Beitrag 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
Antworten