CanvasGadget-based alternative to Scintilla
CanvasGadget-based alternative to Scintilla
Hi guys,
this is a project that is running since a while. i have openned the original thread in the german forum
http://forums.purebasic.com/german/view ... 08#p349822
but link the same content also here.
its about the essential thing, that i believe, will interest also some of you. a real alternative to scintilla.
the reasons why that alternative:
-> better handling of unicode-characters in situations like seek&replace, recognizing keywords etc.
-> an integrated intellisence-box
-> an internal tooltip-function to blow-up informative tooltip while typing a function-name to give info about its parameters and so on
-> easy usage
-> Cross-Plattform, auch mit möglichst Abwertskompatibilität
-----
this module does not need threads yet. but its a question to you all, isn't it better to integrate? specially to allocate keyword-matchings faster in background, while user is typing.
everyone who is interested, contact me at aziz@5m-ware.de so that we can coordinate the coding-stuff. i believe that we can finish that tool together.
-----
what's working now:
-> a relative acceptable speed while typing and scrolling up- and down. but it could be better optimized.
-> recognizing keywords (i added some pb-keys for sample) and colorize them
-> recognizing comments
-> recognizing strings between ""
-> recognizing numbers
-> reasonably working "Selecting" and copying with CTRL+C and cuttign with CTRL+x. Has a lot of to do.
-----
what's planned:
-> fixing problems in selecting, speed-stuff, comments over multiple lines, intellisence-box
-> internally seek&replace
-> Folding
-> Undo-Redo
-> ToolTip
-> recognizing row and columns
-> Syntax-Checking with Callback to realize error-handling
you can also give more tips.
-----
i am working on mac(montainlion) and have tested the stuff on mac, not on windows and linux yet.
i am using PB 5.60.
-----
big-code, i place it here in peaces:
this is a project that is running since a while. i have openned the original thread in the german forum
http://forums.purebasic.com/german/view ... 08#p349822
but link the same content also here.
its about the essential thing, that i believe, will interest also some of you. a real alternative to scintilla.
the reasons why that alternative:
-> better handling of unicode-characters in situations like seek&replace, recognizing keywords etc.
-> an integrated intellisence-box
-> an internal tooltip-function to blow-up informative tooltip while typing a function-name to give info about its parameters and so on
-> easy usage
-> Cross-Plattform, auch mit möglichst Abwertskompatibilität
-----
this module does not need threads yet. but its a question to you all, isn't it better to integrate? specially to allocate keyword-matchings faster in background, while user is typing.
everyone who is interested, contact me at aziz@5m-ware.de so that we can coordinate the coding-stuff. i believe that we can finish that tool together.
-----
what's working now:
-> a relative acceptable speed while typing and scrolling up- and down. but it could be better optimized.
-> recognizing keywords (i added some pb-keys for sample) and colorize them
-> recognizing comments
-> recognizing strings between ""
-> recognizing numbers
-> reasonably working "Selecting" and copying with CTRL+C and cuttign with CTRL+x. Has a lot of to do.
-----
what's planned:
-> fixing problems in selecting, speed-stuff, comments over multiple lines, intellisence-box
-> internally seek&replace
-> Folding
-> Undo-Redo
-> ToolTip
-> recognizing row and columns
-> Syntax-Checking with Callback to realize error-handling
you can also give more tips.
-----
i am working on mac(montainlion) and have tested the stuff on mac, not on windows and linux yet.
i am using PB 5.60.
-----
big-code, i place it here in peaces:
Re: CanvasGadget-based alternative to Scintilla
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Keyboard
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
Enumeration
#pure_keycode_down = 40
#pure_keycode_up = 38
#pure_keycode_left = 37
#pure_keycode_right = 39
#pure_keycode_enter = 13
#pure_keycode_delete = 8
#pure_keycode_space = 32
#pure_keycode_escape = 27
#pure_keycode_p_down = 34
#pure_keycode_p_up = 33
#pure_keycode_pos = 36
#pure_keycode_end = 35
#pure_keycode_shifted = 16
#pure_keycode_tabbed = 9
#pure_keycode_remove = 127
EndEnumeration
CompilerCase #PB_OS_MacOS
Enumeration
#pure_keycode_down = 31
#pure_keycode_up = 30
#pure_keycode_left = 28
#pure_keycode_right = 29
#pure_keycode_enter = 13
#pure_keycode_delete = 8
#pure_keycode_space = 32
#pure_keycode_escape = 27
#pure_keycode_p_down = 22
#pure_keycode_p_up = 11
#pure_keycode_pos = 1
#pure_keycode_end = 4
#pure_keycode_shifted = 16 ; ???? 16
#pure_keycode_tabbed = 9
#pure_keycode_remove = 127
EndEnumeration
CompilerCase #PB_OS_Linux
Enumeration
#pure_keycode_down = 65364
#pure_keycode_up = 65362
#pure_keycode_left = 65361
#pure_keycode_right = 65363
#pure_keycode_enter = 65293
#pure_keycode_delete = 65535
#pure_keycode_space = 32
#pure_keycode_escape = 65307
#pure_keycode_p_down = 65365
#pure_keycode_p_up = 65366
#pure_keycode_pos = 65360
#pure_keycode_end = 65367
#pure_keycode_shifted = 65505
#pure_keycode_tabbed = 9
#pure_keycode_remove = 65288
EndEnumeration
CompilerEndSelect
Enumeration
#fenster = 10
#feld
#hintergrund ; Hintergrundabbild
#eingabe ; Aktuelle Eingabe
EndEnumeration
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Wie groß ist ein Integer?
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
#intsize = 8
CompilerElse
#intsize = 4
CompilerEndIf
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Türkisch LCase
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure.s TLCase( value.s )
Protected t.s = value
; ; ***
; t = ReplaceString( t, "I", "ı" )
; t = ReplaceString( t, "İ", "i" )
; t = ReplaceString( t, "Ş", "ş" )
; t = ReplaceString( t, "Ç", "ç" )
; t = ReplaceString( t, "Ğ", "ğ" )
; ***
ProcedureReturn LCase(t)
EndProcedure
Procedure.s TUCase( value.s )
Protected t.s = value
; ***
; t = ReplaceString( t, "ı", "I" )
; t = ReplaceString( t, "i", "İ" )
; t = ReplaceString( t, "ş", "Ş" )
; t = ReplaceString( t, "ç", "Ç" )
; t = ReplaceString( t, "ğ", "Ğ" )
; ***
ProcedureReturn LCase(t)
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Der Stringlisten-Objekt wird verwendet, um String-Arrays zu realisieren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Interface stringlist
add( value.s )
set( index.i, value.s )
get.s( index.i )
length.i()
find.a( value.s, casesens.a = #False, index.i = -1 )
count.i( value.s, casesens.a = #False, index.i = -1 )
lines.i()
remove( index.i )
clear()
EndInterface
Structure stringlist_body
met.i
cnt.i
*ram
EndStructure
Procedure stringlist__add( *this.stringlist_body, value.s )
Protected p.i, *mem
; ***
If *this\ram = 0
*this\ram = AllocateMemory( #intsize )
Else
*this\ram = ReAllocateMemory( *this\ram, MemorySize(*this\ram) + #intsize )
EndIf
; ***
p = MemorySize(*this\ram) - #intsize
; ***
*mem = AllocateMemory( (Len(value)*2) + 2 )
; ***
PokeS( *mem, value, (Len(value)*2) + 2, #PB_Unicode )
; ***
PokeI( *this\ram + p, *mem )
; ***
*this\cnt + 1
EndProcedure
Procedure stringlist__set( *this.stringlist_body, index.i, value.s )
Protected p.i, *mem
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = #intsize * index
; ***
*mem = PeekI( *this\ram + p )
; ***
*mem = ReAllocateMemory( *mem, (Len(value)*2) + 2 )
; ***
PokeS( *mem, value, (Len(value)*2) + 2, #PB_Unicode )
; ***
PokeI( *this\ram + p, *mem )
EndIf
EndProcedure
Procedure.s stringlist__get( *this.stringlist_body, index.i )
Protected p.i, *mem
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = #intsize * index
; ***
*mem = PeekI( *this\ram + p )
; ***
ProcedureReturn PeekS( *mem, -1, #PB_Unicode )
EndIf
EndProcedure
Procedure.i stringlist__length( *this.stringlist_body )
; - wegen dem chr(13)
If *this\cnt
If *this\ram
ProcedureReturn MemorySize( *this\ram ) - *this\cnt
EndIf
EndIf
EndProcedure
Procedure.a stringlist__find( *this.stringlist_body, value.s, casesens.a = #False, index.i = -1 )
Protected p.i, i.i = 0, l.i, sz.i, s.s = "", c.i = 0, f.i = 0
; ***
Protected *tmp = AllocateMemory( 2048 )
; ***
If *this\ram And *this\cnt
For p = 0 To MemorySize(*this\ram) - 1
If PeekA( *this\ram + p ) = 13
s = PeekS( *tmp, -1, #PB_Unicode )
; ***
If casesens = #False
s = TLCase(s)
EndIf
; ***
If index = -1
If FindString( s, value )
f = 1
Break
EndIf
Else
If i = index
If FindString( s, value )
f = 1
EndIf
; ***
Break
EndIf
EndIf
; ***
sz + ( Len(s) * 2 ) + 1
l = p + 1
i + 1
; ***
s = ""
; ***
c = 0
; ***
FreeMemory( *tmp )
*tmp = AllocateMemory( 2048 )
Else
PokeA( *tmp + c, PeekA( *this\ram + p ) )
c + 1
EndIf
Next
EndIf
; ***
FreeMemory( *tmp )
; ***
ProcedureReturn f
EndProcedure
Procedure.i stringlist__count( *this.stringlist_body, value.s, casesens.a = #False, index.i = -1 )
Protected p.i, i.i = 0, l.i, sz.i, s.s = "", c.i = 0, f.i = 0
; ***
Protected *tmp = AllocateMemory( 2048 )
; ***
If *this\ram And *this\cnt
For p = 0 To MemorySize(*this\ram) - 1
If PeekA( *this\ram + p ) = 13
s = PeekS( *tmp, -1, #PB_Unicode )
; ***
If casesens = #False
s = TLCase(s)
EndIf
; ***
If index = -1
f + CountString( s, value )
Else
If i = index
f + CountString( s, value )
; ***
Break
EndIf
EndIf
; ***
sz + ( Len(s) * 2 ) + 1
l = p + 1
i + 1
; ***
s = ""
; ***
c = 0
; ***
FreeMemory( *tmp )
*tmp = AllocateMemory( 2048 )
Else
PokeA( *tmp + c, PeekA( *this\ram + p ) )
c + 1
EndIf
Next
EndIf
; ***
FreeMemory( *tmp )
; ***
ProcedureReturn f
EndProcedure
Procedure.i stringlist__lines( *this.stringlist_body )
ProcedureReturn *this\cnt
EndProcedure
Procedure stringlist__remove( *this.stringlist_body, index.i )
Protected p.i, n.i = -1, *mem
Protected Dim *lst(*this\cnt)
; ***
If *this\ram
For p = 0 To *this\cnt - 1
If p <> index
n + 1
; ***
*lst(n) = PeekI( *this\ram + (p * #intsize) )
EndIf
Next
; ***
FreeMemory( *this\ram )
; ***
*this\cnt - 1
; ***
If *this\cnt
*this\ram = AllocateMemory( *this\cnt * #intsize )
; ***
For p = 0 To *this\cnt - 1
If *lst(p)
PokeI( *this\ram + (p * #intsize), *lst(p) )
EndIf
Next
EndIf
EndIf
EndProcedure
Procedure stringlist__clear( *this.stringlist_body )
Protected p.i, *mem
; ***
If *this\ram
For p = 0 To *this\cnt - 1
*mem = PeekI( *this\ram + (p * #intsize) )
FreeMemory( *mem )
Next
; ***
FreeMemory( *this\ram )
; ***
*this\ram = 0
*this\cnt = 0
EndIf
EndProcedure
Procedure stringlist()
Protected *this.stringlist_body
*this = AllocateMemory(SizeOf(stringlist_body))
If *this
InitializeStructure(*this, stringlist_body)
; ***
*this\ram = *ram
; ***
*this\Met.i = ?_stringlist_
EndIf
ProcedureReturn *this
EndProcedure
DataSection
_stringlist_:
Data.i @stringlist__add()
Data.i @stringlist__set()
Data.i @stringlist__get()
Data.i @stringlist__length()
Data.i @stringlist__find()
Data.i @stringlist__count()
Data.i @stringlist__lines()
Data.i @stringlist__remove()
Data.i @stringlist__clear()
EndDataSection
Re: CanvasGadget-based alternative to Scintilla
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Der editor_dataset-Objekt wird verwendet, um String-Arrays zu realisieren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Interface editor_dataset
add( value.s, intvalue.i = 0, mode.a = 0, altindex.i = 0, flag.a = 0 )
set( index.i, value.s )
get.s( index.i )
length.i()
find.a( value.s, casesens.a = #False, index.i = -1 )
count.i( value.s, casesens.a = #False, index.i = -1 )
lines.i()
remove( index.i )
clear()
cursor.w( index.i, value.w = -1 )
fold.a( index.i, value.a = 200 )
locked.a( index.i, value.a = 200 )
attr.l( index.i, value.i = -2147483648 )
insert( index.i, value.s, intvalue.i = 0 )
EndInterface
Structure editor_dataset_body
met.i
cnt.u
*ram
*atr
*org
EndStructure
Procedure editor_dataset__add( *this.editor_dataset_body, value.s, intvalue.i = 0, mode.a = 0, altindex.i = 0, flag.a = 0 )
; value = Die Stringzeile selbst
; intvalue = Attributswert
; mode = Passt die relativen Zeilenpositionen an
; altindex = Relevant ab mode>=1 und definiert den relativen Zeilenindex für die Verschiebung
; flag = Regelt die Darstellbarkeit und Erreichbarkeit der Zeilen in Kombination mit dem Verhalten des Code-Editors
; ***
Protected p.i, *mem, u.u, aix.i, rix.u, flg.a
; ***
If *this\ram = 0
*this\ram = AllocateMemory( #intsize )
*this\atr = AllocateMemory( 4 )
*this\org = AllocateMemory( 3 )
Else
*this\ram = ReAllocateMemory( *this\ram, MemorySize(*this\ram) + #intsize )
*this\atr = ReAllocateMemory( *this\atr, MemorySize(*this\atr) + 4 )
*this\org = ReAllocateMemory( *this\org, MemorySize(*this\org) + 3 )
EndIf
; ***
p = MemorySize(*this\ram) - #intsize
; ***
*mem = AllocateMemory( (Len(value)*2) + 2 )
; ***
PokeS( *mem, value, (Len(value)*2) + 2, #PB_Unicode )
; ***
PokeI( *this\ram + p, *mem )
; ***
p = MemorySize(*this\atr) - 4
; ***
PokeL( *this\atr + p, intvalue )
; ***
p = MemorySize(*this\org) - 3
; ***
Select mode
Case 0
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Die neue Zeile wurde ganz unten normal angehangen.
; Deshalb ist die absolute sowie die relative
; Zeilennummer dieselbe.
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
u = *this\cnt
Case 1
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Der Anwender hat im Editor auf den Enter gedrückt
; und damit alle anderen Zeilen, welche unterhalb
; des Cursors lagen, nach untenhin verschoben
; ***
; Der altindex ist nun die absolute Zeilennummer
; der Zeile, auf dem sich der Anwender gerade
; befindet, die nun als "LEER" markiert ist.
; ***
; Diese Zeile wird zur relativen Index dieser neu
; angelegten Zeile.
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
u = altindex
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Nun haben wir das Problem, dass auch alle anderen
; relativen Zeilennummern, die nach dem Cursor
; folgen, um einen Punkt nach untenhin verschoben
; werden. Da die Cursorposition altindex ist, wird
; also dessen absolute Gegenstück im DataSet als
; Grundlage genommen und von dort aus wird nun
; die Anpassung durchgeführt.
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
If MemorySize(*this\org) > 3
For aix = (altindex + 1) * 3 To (MemorySize(*this\org) - 1) - 3 Step 3
rix = PeekU( *this\org + aix + 0 )
flg = PeekA( *this\org + aix + 2 )
; ***
rix + 1
; ***
PokeU( *this\org + aix + 0, rix )
PokeA( *this\org + aix + 2, flg )
Next
EndIf
Case 2
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Der Anwender hat im Editor die aktuelle Zeile
; getilgt, in dem er mit dem Cursor zum übergeordneten
; Zeile gesprungen ist, in dem er an der Cursor-
; Position 0 auf die Delete-Taste gedrückt hat.
; ***
; Die altindex ist nun die Zeilennummer der
; übergeordneten Zeile. Die relative Index der
; gelöschten Zeile wird nun auf den maximalen Wert
; 65535 gesetzt.
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
aix = altindex + 1
; ***
PokeU( *this\org + aix + 0, 65535 ) ; Die Position wird ganz nach hinten verlegt
PokeA( *this\org + aix + 2, 10 ) ; Die Zeile wird als Gelöscht markiert
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; alle anderen Zeilen nach dem Cursor werden num um
; eine Position nach oben verschoben.
; - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
If MemorySize(*this\org) > 6
For aix = (altindex + 2) * 3 To (MemorySize(*this\org) - 1) - 3 Step 3
rix = PeekU( *this\org + aix + 0 )
flg = PeekA( *this\org + aix + 2 )
; ***
rix - 1
; ***
PokeU( *this\org + aix + 0, rix )
PokeA( *this\org + aix + 2, flg )
Next
EndIf
EndSelect
; ***
; Relative Index einer Zeile nach außen (rli)
PokeU( *this\org + p + 0, u )
; Flag um das Verhalten der Zeile im Code-Editor zu regeln
PokeA( *this\org + p + 2, flag )
; ***
*this\cnt + 1
EndProcedure
Procedure editor_dataset__set( *this.editor_dataset_body, index.i, value.s )
Protected p.i, *mem, idx.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
idx = PeekU( *this\org + (index * 3) )
; ***
p = #intsize * index;idx
; ***
*mem = PeekI( *this\ram + p )
; ***
*mem = ReAllocateMemory( *mem, (Len(value)*2) + 2 )
; ***
PokeS( *mem, value, (Len(value)*2) + 2, #PB_Unicode )
; ***
PokeI( *this\ram + p, *mem )
EndIf
EndProcedure
Procedure.s editor_dataset__get( *this.editor_dataset_body, index.i )
Protected p.i, *mem, idx.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
idx = PeekU( *this\org + (index * 3) )
; ***
p = #intsize * index;idx
; ***
*mem = PeekI( *this\ram + p )
; ***
ProcedureReturn PeekS( *mem, -1, #PB_Unicode )
EndIf
EndProcedure
Procedure.i editor_dataset__length( *this.editor_dataset_body )
; - wegen dem chr(13)
If *this\cnt
If *this\ram
ProcedureReturn MemorySize( *this\ram ) - *this\cnt
EndIf
EndIf
EndProcedure
Procedure.a editor_dataset__find( *this.editor_dataset_body, value.s, casesens.a = #False, index.i = -1 )
Protected p.i, i.i = 0, l.i, sz.i, s.s = "", c.i = 0, f.i = 0
; ***
Protected *tmp = AllocateMemory( 2048 )
; ***
If *this\ram And *this\cnt
For p = 0 To MemorySize(*this\ram) - 1
If PeekA( *this\ram + p ) = 13
s = PeekS( *tmp, -1, #PB_Unicode )
; ***
If casesens = #False
s = TLCase(s)
EndIf
; ***
If index = -1
If FindString( s, value )
f = 1
Break
EndIf
Else
If i = index
If FindString( s, value )
f = 1
EndIf
; ***
Break
EndIf
EndIf
; ***
sz + ( Len(s) * 2 ) + 1
l = p + 1
i + 1
; ***
s = ""
; ***
c = 0
; ***
FreeMemory( *tmp )
*tmp = AllocateMemory( 2048 )
Else
PokeA( *tmp + c, PeekA( *this\ram + p ) )
c + 1
EndIf
Next
EndIf
; ***
FreeMemory( *tmp )
; ***
ProcedureReturn f
EndProcedure
Procedure.i editor_dataset__count( *this.editor_dataset_body, value.s, casesens.a = #False, index.i = -1 )
Protected p.i, i.i = 0, l.i, sz.i, s.s = "", c.i = 0, f.i = 0
; ***
Protected *tmp = AllocateMemory( 2048 )
; ***
If *this\ram And *this\cnt
For p = 0 To MemorySize(*this\ram) - 1
If PeekA( *this\ram + p ) = 13
s = PeekS( *tmp, -1, #PB_Unicode )
; ***
If casesens = #False
s = TLCase(s)
EndIf
; ***
If index = -1
f + CountString( s, value )
Else
If i = index
f + CountString( s, value )
; ***
Break
EndIf
EndIf
; ***
sz + ( Len(s) * 2 ) + 1
l = p + 1
i + 1
; ***
s = ""
; ***
c = 0
; ***
FreeMemory( *tmp )
*tmp = AllocateMemory( 2048 )
Else
PokeA( *tmp + c, PeekA( *this\ram + p ) )
c + 1
EndIf
Next
EndIf
; ***
FreeMemory( *tmp )
; ***
ProcedureReturn f
EndProcedure
Procedure.i editor_dataset__lines( *this.editor_dataset_body )
ProcedureReturn *this\cnt
EndProcedure
Procedure editor_dataset__remove( *this.editor_dataset_body, index.i )
Protected p.i, n.i = -1, *mem
Protected Dim *lst(*this\cnt)
Protected Dim atr.l(*this\cnt)
; ***
If *this\ram
For p = 0 To *this\cnt - 1
If p <> index
n + 1
; ***
*lst(n) = PeekI( *this\ram + (p * #intsize) )
; ***
atr(n) = PeekL( *this\atr + (p * 4) )
EndIf
Next
; ***
FreeMemory( *this\ram )
FreeMemory( *this\atr )
; ***
*this\cnt - 1
; ***
If *this\cnt
*this\ram = AllocateMemory( *this\cnt * #intsize )
*this\atr = AllocateMemory( *this\cnt * 4 )
; ***
For p = 0 To *this\cnt - 1
If *lst(p)
PokeI( *this\ram + (p * #intsize), *lst(p) )
; ***
PokeL( *this\atr + (p * 4), atr(p) )
EndIf
Next
EndIf
EndIf
EndProcedure
Procedure editor_dataset__clear( *this.editor_dataset_body )
Protected p.i, *mem
; ***
If *this\ram
For p = 0 To *this\cnt - 1
*mem = PeekI( *this\ram + (p * #intsize) )
FreeMemory( *mem )
Next
; ***
FreeMemory( *this\ram )
FreeMemory( *this\atr )
FreeMemory( *this\org )
; ***
*this\org = 0
*this\atr = 0
*this\ram = 0
*this\cnt = 0
EndIf
EndProcedure
Procedure.w editor_dataset__cursor( *this.editor_dataset_body, index.i, value.w = -1 )
Protected p.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = 4 * index
; ***
If value <= -1
ProcedureReturn PeekW( *this\atr + p )
Else
PokeW( *this\atr + p, value )
EndIf
EndIf
EndProcedure
Procedure.a editor_dataset__fold( *this.editor_dataset_body, index.i, value.a = 200 )
Protected p.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = 4 * index
; ***
If value = 200
ProcedureReturn PeekA( *this\atr + p + 1 )
Else
If value = #True Or value = #False
PokeA( *this\atr + p + 1, value )
EndIf
EndIf
EndIf
EndProcedure
Procedure.a editor_dataset__locked( *this.editor_dataset_body, index.i, value.a = 200 )
Protected p.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = 4 * index
; ***
If value = 200
ProcedureReturn PeekA( *this\atr + p + 2 )
Else
If value = #True Or value = #False
PokeA( *this\atr + p + 2, value )
EndIf
EndIf
EndIf
EndProcedure
Procedure.l editor_dataset__attr( *this.editor_dataset_body, index.i, value.i = -2147483648 )
Protected p.i
; ***
If *this\ram And index >= 0 And index < *this\cnt And *this\cnt
p = 4 * index
; ***
If value = -2147483648
ProcedureReturn PeekL( *this\atr + p )
Else
PokeL( *this\atr + p, value )
EndIf
EndIf
EndProcedure
Procedure editor_dataset__insert( *this.editor_dataset_body, index.i, value.s, intvalue.i = 0 )
Protected n.i, g.i = 0, p.i, p1.i, p2.i, *adr, *ram, *atr
; ***
If *this\ram
editor_dataset__add(*this,"")
; ***
If *this\cnt And index < *this\cnt - 1
p = *this\cnt -1
; ***
p1 = MemorySize(*this\ram)
p2 = MemorySize(*this\atr)
; ***
*adr = PeekI( *this\ram + p1 - #intsize )
; ***
*ram = AllocateMemory(p1)
*atr = AllocateMemory(p2)
; ***
For n = 0 To p
If g = index
g + 1
EndIf
; ***
PokeI( *ram + (g * #intsize), PeekI( *this\ram + (n * #intsize) ) )
PokeL( *atr + (g * 4), PeekL( *this\atr + (n * 4) ) )
; ***
g + 1
Next
; ***
PokeI( *ram + (index * #intsize), *adr )
PokeL( *atr + (index * 4), intvalue )
; ***
FreeMemory(*this\ram) : *this\ram = *ram
FreeMemory(*this\atr) : *this\atr = *atr
EndIf
EndIf
EndProcedure
Procedure editor_dataset()
Protected *this.editor_dataset_body
*this = AllocateMemory(SizeOf(editor_dataset_body))
If *this
InitializeStructure(*this, editor_dataset_body)
; ***
*this\ram = *ram
; ***
*this\Met.i = ?_editor_dataset_
EndIf
ProcedureReturn *this
EndProcedure
DataSection
_editor_dataset_:
Data.i @editor_dataset__add()
Data.i @editor_dataset__set()
Data.i @editor_dataset__get()
Data.i @editor_dataset__length()
Data.i @editor_dataset__find()
Data.i @editor_dataset__count()
Data.i @editor_dataset__lines()
Data.i @editor_dataset__remove()
Data.i @editor_dataset__clear()
Data.i @editor_dataset__cursor()
Data.i @editor_dataset__fold()
Data.i @editor_dataset__locked()
Data.i @editor_dataset__attr()
Data.i @editor_dataset__insert()
EndDataSection
Last edited by 5mware on Mon Nov 12, 2018 12:04 pm, edited 1 time in total.
Re: CanvasGadget-based alternative to Scintilla
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Daten des Editors
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Structure struct_intellisence
; Das sind die CommandKeys, die zum Aufklappen der
; Intellisence-Box erkannt werden
groupkeys.stringlist
; Der Inhalt
content.stringlist
; Einfügen mit oder ohne Leerabstand
space.a
; Maximalbreite der Liste
width.u
EndStructure
Structure struct_intellisence_list
cnt.u
lst.struct_intellisence[1000]
EndStructure
Structure struct_current_line_char
char.s
color.l
pos.w
EndStructure
Structure struct_pure_multiline_code_editor
; Aktueller Zeichnen-Status
justdraw.a
; CanvasGadet
id.i
; Intellisense-Anbindung
*intellisence.struct_intellisence_list
; Inhalt
content.editor_dataset
; Syntax-Highlighting für die Schlüsselwörter
*keywords.editor_dataset
; Groß- und Kleinschreibung beachten für Keywords?
casesens.a
; Kommantierung aktiv?
comment.a
; Stringeingabe aktiv?
stringi.a
; Kommentarzeichen
comment_char.s
; Stringketten-Zeichen
string_char.s
; Double-Trenner für Zahlen
double_separator.s
; Farben
color_comment.l
color_string.l
color_number.l
color_operator.l
color_bkg.l
color_selbkg.l
color_errorbkg.l
color_marked_bkg.l
color_marked_border.l
color_number_block_txt.l
color_number_block_bkg.l
color_number_block_active.l
color_intelli_background.l
color_intelli_border.l
color_intelli_lborder.l
color_intelli_dborder.l
color_intelli_text.l
color_intelli_sel_bkg.l
color_intelli_sel_txt.l
; Zeilennummer anzeigen
linenumbers.a
; Temporärer Abbild
tempor.i
; Visible Background:
; Das ist der aktuelle Hintergrund, der alle sichtbaren
; Code-Zeilen wiedergibt
visbkg.i
; Temporary Background:
; Dieses Bild wird bei up/down gentzt, um eine Kopie
; des visbkg zu nehmen und es um eine Zeile nach oben
; oder nach unten zu reduzieren und die neu dazu kommende
; Zeile anzuhängen
tmpbkg.i
; Last active Line- Image
lalimg.i
; Current Line Inkey
inkey.s
; Current Line:
; Das Abbild der aktuellen Zeile wird beim up/down oder
; Mausklick aus dem Background-Bereich herauskopiert oder
; beim JIT-Eingabe automatisch realisiert, jedoch nur ab dem
; Part, der gerade bearbeitet wird
curlin.i
; Aktuelles Start-Zeichen der aktuellen Zeile, ab dem
; neugezeichnet wird
curpos.w
; Aktuelle Tokenlänge
curlen.w
; Zeichencursor
cursor.w
; Aktuelle Länge der Eingabe
length.w
; Zeichenstrom der aktuellen Zeile
strom.struct_current_line_char[20000]
; Temporärer Token
tmptok.s
; Letzte Tokenstart
lastpo.w
; Aktuelle Zeilenindex : Tatsächliche Zeilennummer
index.i
; Top-Limit
toplimit.i
; Vis-Limit
vislimit.u
; Cursor-Row-Position : Relative Zeilennummer im sichtbaren Feld
; Ermittlung: position = index - toplimit
position.i
; Hintergrund-Update
update_bkg.a
; Nummernblock-Abstand
nwid.u
; Text-Height
theight.u
; Cursor-Display
cursorDisplay.a
; Richtung der Content-Aktualisierung
condir.a
; Cursor-Blinker
curstate.w
; Den Cursor ganz nach hinter der Zeile verschieben
movetolast.a
; Letzte Zeichenfolge
lastkey.s
; Letzte im Intellisence-Box ausgewählter Eintrag
intellitok.s
; Intellisence-Anzeige-Modus
intellivis.a
; Intellisence-Index
intellicur.w
; Intellisence-Total vom aktuellen Inhalt
intellitot.u
; Intellisence-Abstand
intellimar.a
; Letzte Intellisence-Breite
intelliLastWidth.l
; Markierungsflag
mark.a
; Markierungsmodus:
; 0 = Nur die aktuelle Zeile
; 1 = Mehrere Zeilen
markmode.a
; Markierungspunkt
markrow.l : markrel.l
; Startposition der Markierung auf der Startzeile für die Markierung
markCursorFrom.w
; Endposition der Markierung auf der Endzeile für die Markierung
markCursorInto.w
; Startzeile
markstart.u
; Endzeile
markclose.u
; Begin der Markierung an Zeichen X
markpos.w
; Ende der Markierung an Zeichen N
marklen.w
; Markierungsstartzeichen-Differenz variiert um einen Wert zwischen
; der Tastaturmarkierung und der Mauszeigermarkierung
markdif.a
EndStructure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Funktionen
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure.s pick( index.l, char.s, value.s )
Protected n.l, s.s, idx.l = 0
; ***
For n = 1 To Len( value )
Select Mid( value, n, 1 )
Case char
If idx = index
Break
Else
idx + 1
; ***
s = ""
EndIf
Default
s + Mid( value, n, 1 )
EndSelect
Next
; ***
If idx > index
s = ""
EndIf
; ***
If index < 0
s = ""
EndIf
; ***
If index > CountString( value, char )
s = ""
EndIf
; ***
ProcedureReturn s
EndProcedure
Procedure.i opaque( value.i, transparency.u = 255 )
ProcedureReturn RGBA( Red(value), Green(value), Blue(value), transparency )
EndProcedure
;https://physikunterricht-online.de/hilfsmittel/physikalische-groessen-und-einheiten/
; ***
;https://www.gut-erklaert.de/mathematik/gewichtseinheiten-tabelle.html
;https://www.gut-erklaert.de/mathematik/volumeneinheiten-tabelle-mit-liter.html
;https://www.gut-erklaert.de/mathematik/laengeneinheiten-tabelle.html
;https://www.frustfrei-lernen.de/mathematik/laengeneinheiten.html
;https://www.gut-erklaert.de/mathematik/zeiteinheiten-tabelle-und-abkuerzungen.html
;http://www.tabelle.info/elektrische_einheiten.htm
Procedure.a is_arithmetical( value.s )
Protected p.i, ret.a = 1, v.s = value, tk.s, ti.s, fn.s, nu.a = 0
; ***
; ha = Hektar
; g = gramm
; mg = milligramm
; kg = kilogramm
; dt = Dezitonne
; cg = Centigramm
; t = Tonne
; kt = Kilotonne
; mt = Megatonne
; gt = Gigatonne
; ml = milliliter
; cl = centiliter
; dl = deziliter
; hl = hektoliter
; mi,mil = mil
; yd = yard
; ft = foot
; sm = seemeile
; in,inc=inc
; a=ampere,strom
; c=coulomb,ladung
; v=volt,spannung
; w=watt,leistung
; o=ohm,Widerstand
; f=farad,Kapazität
; si=siemens,leitwert
tk = "yıl,gün,hafta,ay,saat,dakika,saniye,milisaniye,bayt,ppi,dpi,kb,mb,tb,bit,mbit,kbit,tbit,km,dm,cm,mm,ml,ms,pt,px,inç,mil,ha,mg,kg,dt,cg,kt,mt,gt,cl,dl,hl,in,mi,yd,ft,sm,si,a,c,v,w,o,f,m,t,l,s,h,b,o,g"
; ***
v = TLCase(v)
v = Trim(v)
; ***
For p = 0 To CountString(tk,",")+1
ti = pick(p,",",tk)
; ***
If ti
If FindString( v, ti )
fn = ti
; ***
v = Trim(ReplaceString( v, ti, "" ))
; ***
Break
EndIf
EndIf
Next
; ***
For p = 1 To Len(v)
Select Mid( v, p, 1 )
Case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
nu = 1
Default
nu = 0
ret = 0
Break
EndSelect
Next
; ***
If nu = 0
ret = 0
EndIf
; ***
ProcedureReturn ret
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Zeichnen
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
LoadFont(100,"Anonymous Pro",20)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Markierungsfeldinhalt ermitteln
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure.s getMarkedText(*daten.struct_pure_multiline_code_editor)
Protected p.w, y.w, h.w, x.w, w.w, t.s
; ***
y = *daten\markstart + *daten\toplimit
h = *daten\markclose + *daten\toplimit
; ***
If h > y
h - 1
EndIf
; ***
x = *daten\markpos
w = *daten\marklen
; ***
If w < x
p = x
x = w
w = p
EndIf
; ***
x + *daten\markdif
; ***
For p = y To h
If p > y
t + #CRLF$
EndIf
; ***
t + Mid( *daten\content\get(p), x, (w - x) + 1 )
Next
; ***
ProcedureReturn t
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Markierungsfeldinhalt leeren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure clearMarkedText(*daten.struct_pure_multiline_code_editor)
Protected p.w, n.i, y.w, h.w, x.w, w.w, t.s, s.s
; ***
y = *daten\markstart + *daten\toplimit
h = *daten\markclose + *daten\toplimit
; ***
x = *daten\markpos
w = *daten\marklen
; ***
If w < x
p = x
x = w
w = p
EndIf
; ***
For p = y To h
t = Mid( *daten\content\get(p), x, (w - x) + 1 )
; ***
For n = 1 To Len(t)
If n >= x And n <= (w - x) + 1
s + " "
Else
s + Mid( t, n, 1 )
EndIf
Next
; ***
*daten\content\set(p,s)
Next
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Ermittelt die Zeichen des aktuell angesteuerten Zeile
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure update_current_token(*daten.struct_pure_multiline_code_editor,pos.w,lth.w)
If IsGadget(#feld)
Protected w.i, h.i, p.i, n.i, c.i, g.i = 0, t.s, s.s, b.s, com.a = 0, stg.a = 0, ps.i, ls.i, spa.a = 0
; ***
w = GadgetWidth(#feld)
h = GadgetHeight(#feld)
; ***
ls = lth
; ***
ps = pos
; ***
For p = ps To ls
*daten\strom[p]\color = 0
; ***
If com = 1 And stg = 0
*daten\strom[p]\color = *daten\color_comment
ElseIf stg = 1 And com = 0
*daten\strom[p]\color = *daten\color_string
EndIf
; ***
Select *daten\strom[p]\char
Case *daten\comment_char
If stg = 0
com = 1
; ***
*daten\strom[p]\color = *daten\color_comment
EndIf
Case *daten\string_char
If com = 0
Select stg
Case 0 : stg = 1
Case 1 : spa = 1
EndSelect
; ***
*daten\strom[p]\color = *daten\color_string
EndIf
Case " ", ".", "(", ")", "{", "}", "[", "]", "/", "\", "%", "+", "-", "&", "'",
"*", ":", ";", ",", "<", ">", "|", "#", "=", "!", "|", "^", "°", "$", "§",
"~", "≈", Chr(10), Chr(13)
If com = 0 And stg = 1
*daten\strom[p]\color = *daten\color_string
ElseIf com = 1 And stg = 0
*daten\strom[p]\color = *daten\color_comment
ElseIf com = 0 And stg = 0
*daten\strom[p]\color = *daten\color_operator
; ***
g = p - Len(t)
; ***
For c = 0 To Len(b) - 1
*daten\strom[g + c]\color = 0
Next
; ***
If *daten\keywords
For n = 0 To *daten\keywords\lines() -1
If TLCase(*daten\keywords\get(n)) = TLCase(t)
t = *daten\keywords\get(n)
; ***
g = p - Len(*daten\keywords\get(n))
; ***
For c = 0 To Len(*daten\keywords\get(n)) - 1
*daten\strom[c + g]\color = *daten\keywords\attr(n)
*daten\strom[c + g]\char = Mid( t, c + 1, 1 )
Next
; ***
Break
EndIf
Next
EndIf
EndIf
; ***
t = ""
; ***
If spa = 1
spa = 0
stg = 0
EndIf
Default
t + *daten\strom[p]\char
EndSelect
Next
; ***
If spa = 1
spa = 0
stg = 0
EndIf
; ***
If t
p = *daten\cursor + lth
; ***
If com = 0 And stg = 0
*daten\strom[p]\color = *daten\color_operator
; ***
g = p - Len(t)
; ***
For c = 0 To Len(b) - 1
*daten\strom[g + c]\color = 0
Next
; ***
If *daten\keywords
For n = 0 To *daten\keywords\lines() -1
If TLCase(*daten\keywords\get(n)) = TLCase(t)
t = *daten\keywords\get(n)
; ***
g = p - Len(*daten\keywords\get(n))
; ***
For c = 0 To Len(*daten\keywords\get(n)) - 1
*daten\strom[c + g]\color = *daten\keywords\attr(n)
*daten\strom[c + g]\char = Mid( t, c + 1, 1 )
Next
; ***
Break
EndIf
Next
EndIf
EndIf
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Setzt den Syntax-Färbung der aktuellen Zeile
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure update_current_syntax(*daten.struct_pure_multiline_code_editor)
If IsGadget(#feld)
Protected w.i, h.i, p.i, n.i, c.i, g.i = 0, t.s, s.s, b.s, com.a = 0, stg.a = 0, ps.i, ls.i, spa.a = 0
; ***
w = GadgetWidth(#feld)
h = GadgetHeight(#feld)
; ***
ls = *daten\length
; ***
ps = 0
; ***
If ps < 0 : ProcedureReturn : EndIf
If ls > 19999 : ProcedureReturn : EndIf
; ***
For p = ps To ls
*daten\strom[p]\color = 0
; ***
If com = 1 And stg = 0
*daten\strom[p]\color = *daten\color_comment
ElseIf stg = 1 And com = 0
*daten\strom[p]\color = *daten\color_string
EndIf
; ***
Select *daten\strom[p]\char
Case *daten\comment_char
If stg = 0
com = 1
; ***
*daten\strom[p]\color = *daten\color_comment
EndIf
Case *daten\string_char
If com = 0
Select stg
Case 0 : stg = 1
Case 1 : spa = 1
EndSelect
; ***
*daten\strom[p]\color = *daten\color_string
EndIf
Case " ", ".", "(", ")", "{", "}", "[", "]", "/", "\", "%", "+", "-", "&", "'",
"*", ":", ";", ",", "<", ">", "|", "#", "=", "!", "|", "^", "°", "$", "§",
"~", "≈", Chr(10), Chr(13)
If com = 0 And stg = 1
*daten\strom[p]\color = *daten\color_string
ElseIf com = 1 And stg = 0
*daten\strom[p]\color = *daten\color_comment
ElseIf com = 0 And stg = 0
*daten\strom[p]\color = *daten\color_operator
; ***
If t
If is_arithmetical( t ) = #True
g = p - Len(t)
; ***
For c = 0 To Len(t) - 1
*daten\strom[g + c]\color = *daten\color_number
Next
; ***
Select *daten\strom[p]\char
Case ".", "%"
*daten\strom[p]\color = *daten\color_number
EndSelect
; ***
If g - 1 > 0
If *daten\strom[g - 1]\char = "%"
*daten\strom[g - 1]\color = *daten\color_number
EndIf
EndIf
Else
g = p - Len(t)
; ***
For c = 0 To Len(b) - 1
*daten\strom[g + c]\color = 0
Next
; ***
If *daten\keywords
For n = 0 To *daten\keywords\lines() -1
If TLCase(*daten\keywords\get(n)) = TLCase(t)
t = *daten\keywords\get(n)
; ***
g = p - Len(*daten\keywords\get(n))
; ***
For c = 0 To Len(*daten\keywords\get(n)) - 1
*daten\strom[c + g]\color = *daten\keywords\attr(n)
*daten\strom[c + g]\char = Mid( t, c + 1, 1 )
Next
; ***
Break
EndIf
Next
EndIf
EndIf
EndIf
EndIf
; ***
t = ""
; ***
If spa = 1
spa = 0
stg = 0
EndIf
Default
t + *daten\strom[p]\char
EndSelect
; ***
*daten\comment = com
*daten\stringi = stg
Next
; ***
If spa = 1
spa = 0
stg = 0
EndIf
; ***
If t
p = ls
; ***
If com = 0 And stg = 0
*daten\strom[p]\color = *daten\color_operator
; ***
If is_arithmetical( t ) = #True
g = p - Len(t)
; ***
For c = 0 To Len(t) - 1
*daten\strom[g + c]\color = *daten\color_number
Next
; ***
Select *daten\strom[p]\char
Case ".", "%"
*daten\strom[p]\color = *daten\color_number
EndSelect
; ***
If g - 1 > 0
If *daten\strom[g - 1]\char = "%"
*daten\strom[g - 1]\color = *daten\color_number
EndIf
EndIf
Else
g = p - Len(t)
; ***
For c = 0 To Len(b) - 1
*daten\strom[g + c]\color = 0
Next
; ***
If *daten\keywords
For n = 0 To *daten\keywords\lines() -1
If TLCase(*daten\keywords\get(n)) = TLCase(t)
t = *daten\keywords\get(n)
; ***
g = p - Len(*daten\keywords\get(n))
; ***
For c = 0 To Len(*daten\keywords\get(n)) - 1
*daten\strom[c + g]\color = *daten\keywords\attr(n)
*daten\strom[c + g]\char = Mid( t, c + 1, 1 )
Next
; ***
Break
EndIf
Next
EndIf
EndIf
EndIf
EndIf
EndIf
; ***
*daten\comment = com
*daten\stringi = stg
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Beim Eintritt auf die neue Zeile wird dieser leer geräumt, wenn sie keine
; Tokens enthalten darf, weil sie eigentlich leer ist
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure clear_new_line(*daten.struct_pure_multiline_code_editor)
Protected p.i
; ***
*daten\length = 19999
; ***
For p = 0 To *daten\length
*daten\strom[p]\char = ""
; ***
*daten\strom[p]\color = 0
*daten\strom[p]\pos = 0
; ***
If *daten\strom[p]\char = ""
Break
EndIf
Next
; ***
*daten\strom[0]\char = ""
EndProcedure
Re: CanvasGadget-based alternative to Scintilla
Code: Select all
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Threadspezifisch, leert den Rest einer Zeile
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure clear_current_line(*daten.struct_pure_multiline_code_editor)
Protected p.i
; ***
For p = *daten\length To 19999
*daten\strom[p]\color = 0
*daten\strom[p]\char = ""
*daten\strom[p]\pos = 0
Next
; ***
If IsThread(*daten)
KillThread(*daten)
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Ermittelt die aktuell angesteuerte Zeile
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure allocate_current_line(*daten.struct_pure_multiline_code_editor)
Protected p.i, s.s
; ***
*threaded_current_line = *daten
; ***
*daten\strom[0]\color = 0
*daten\strom[0]\char = ""
*daten\strom[0]\pos = 0
; ***
*daten\strom[1]\color = 0
*daten\strom[1]\char = ""
*daten\strom[1]\pos = 0
; ***
*daten\strom[2]\color = 0
*daten\strom[2]\char = ""
*daten\strom[2]\pos = 0
; ***
If *daten\content\lines()
*daten\index = *daten\position + *daten\toplimit
; ***
*daten\length = Len(s)
; ***
If IsThread(*daten)
KillThread(*daten)
EndIf
; ***
CreateThread( @clear_current_line(), *daten )
; ***
If *daten\index >= 0 And *daten\index < *daten\content\lines()
s = *daten\content\get(*daten\index)
; ***
If Trim(s)
*daten\length = 19999
; ***
For p = 1 To *daten\length
If p <= Len(s)
*daten\strom[p]\char = Mid( s, p, 1 )
Else
*daten\strom[p]\char = ""
EndIf
; ***
*daten\strom[p]\color = 0
*daten\strom[p]\pos = 0
; ***
If p > Len(s)
If *daten\strom[p]\char = ""
Break
EndIf
EndIf
Next
; ***
*daten\strom[0]\char = ""
; ***
*daten\length = Len(s) + 1
; ***
update_current_syntax( *daten )
Else
*daten\cursor = 1
*daten\length = 0
; ***
*daten\strom[0]\color = 0
*daten\strom[0]\char = ""
*daten\strom[0]\pos = 0
EndIf
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Geht zu einer Zeile
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure goto_current_line(*daten.struct_pure_multiline_code_editor,w.i,h.i,currentUpdate.a=#False)
Protected ww.d, hh.i
; ***
If *daten\index >= 0
If *daten\index < *daten\content\lines()
*daten\position = *daten\index - *daten\toplimit
; ***
;Debug Str(*daten\position) + ":" + Str(*daten\index) + " > " + *daten\content\get(*daten\index)
allocate_current_line( *daten )
; ***
If IsImage( *daten\visbkg ) > 0
CopyImage( *daten\visbkg, *daten\tmpbkg )
EndIf
; ***
If *daten\justdraw = 0
*daten\justdraw = 1
; ***
If CreateImage( *daten\visbkg, w, h, 32, #PB_Image_Transparent ) And
StartDrawing( ImageOutput( *daten\visbkg ) )
; ***
DrawingMode( #PB_2DDrawing_AlphaBlend )
; ***
If IsFont(100):DrawingFont(FontID(100)):EndIf
; ***
If IsImage( *daten\tmpbkg )
DrawAlphaImage( ImageID( *daten\tmpbkg ), 0, 0 )
EndIf
; ***
DrawingMode( #PB_2DDrawing_AlphaChannel )
; ***
Box( 0, TextHeight("A") * *daten\position, w, TextHeight("A"), RGBA(0,0,0,0) )
; ***
StopDrawing()
; ***
CopyImage( *daten\visbkg, *daten\tmpbkg )
; ***
If currentUpdate
ww = 0
; ***
If CreateImage( *daten\curlin, w, 100, 32, #PB_Image_Transparent ) And
StartDrawing( ImageOutput( *daten\curlin ) )
If IsFont(100):DrawingFont(FontID(100)):EndIf
; ***
hh = TextHeight("A")
; ***
StopDrawing()
EndIf
; ***
If CreateImage( *daten\curlin, w, hh, 32, #PB_Image_Transparent ) And
StartDrawing( ImageOutput( *daten\curlin ) )
DrawingMode( #PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend )
; ***
If IsFont(100):DrawingFont(FontID(100)):EndIf
; ***
For p = 0 To *daten\length ;- 1
DrawText( ww, 0, *daten\strom[p]\char, opaque(*daten\strom[p]\color) )
; ***
*daten\strom[p]\pos = ww : ww + TextWidth(*daten\strom[p]\char)
Next
; ***
StopDrawing()
EndIf
EndIf
; ***
*daten\justdraw = 0
EndIf
EndIf
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Hintergrundbild zeichnen
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure update_content(*daten.struct_pure_multiline_code_editor,id,w.i,h.i)
Protected p.i, a.a = 0, tw.i
; ***
If IsGadget(id)
If *daten\condir <> 0
allocate_current_line( *daten )
; ***
If *daten\theight < 8
*daten\theight = 8
EndIf
; ***
If CreateImage(*daten\curlin,w,*daten\theight) And StartDrawing(ImageOutput(*daten\curlin))
Box( 0, 0, w, h, $FFFFFF ) ; VORÜBRGEHEND
; ***
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
If evt = #PB_EventType_Input
*daten\theight = TextHeight("A")
; ***
*daten\vislimit = (h / *daten\theight) - 1
; ***
If *daten\vislimit <= 0
*daten\vislimit = 1
EndIf
EndIf
; ***
For p = 0 To *daten\length -1
If p = 0
DrawText( 0, 0, *daten\strom[p]\char, *daten\strom[p]\color )
Else
DrawText( tw, 0, *daten\strom[p]\char, *daten\strom[p]\color )
EndIf
; ***
tw + TextWidth(*daten\strom[p]\char)
Next
; ***
StopDrawing()
EndIf
EndIf
; ***
If IsImage(*daten\visbkg)
a = 1
CopyImage( *daten\visbkg, *daten\tmpbkg )
EndIf
; ***
If CreateImage(*daten\visbkg,w,h) And StartDrawing(ImageOutput(*daten\visbkg))
If a = 0
; Es wird das erste Mal gezeichnet, deshalb kommt auch der
; vollständige Hintergrund gleich mit
Box( 0, 0, w, h, *daten\color_bkg )
EndIf
; ***
Select *daten\condir
Case 0 ; Normal
If a = 1
If IsImage(*daten\tmpbkg)
DrawImage( ImageID(*daten\tmpbkg), 0, 0 )
EndIf
EndIf
; ***
If IsImage(*daten\curlin)
DrawImage( ImageID(*daten\curlin), 0, *daten\position * *daten\theight )
EndIf
Case 1 ; Rauf
If a = 1
If IsImage(*daten\tmpbkg)
DrawImage( ImageID(*daten\tmpbkg), 0, *daten\theight )
EndIf
EndIf
; ***
If IsImage(*daten\curlin)
DrawImage( ImageID(*daten\curlin), 0, 0 )
EndIf
Case 2 ; Runter
If a = 1
If IsImage(*daten\tmpbkg)
DrawImage( ImageID(*daten\tmpbkg), 0, - *daten\theight )
EndIf
EndIf
; ***
If IsImage(*daten\curlin)
DrawImage( ImageID(*daten\curlin), 0, h - *daten\theight )
EndIf
EndSelect
; ***
*daten\condir = 0
; ***
StopDrawing()
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Aktuelle Zeile in ein echtes String umwandeln
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure.s getInputStringLine(*daten.struct_pure_multiline_code_editor)
Protected p.i, s.s
; ***
For p = 0 To *daten\length
s + *daten\strom[p]\char
Next
; ***
ProcedureReturn s
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Markierungsfeldumfeld leeren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure clearImageArea(*daten.struct_pure_multiline_code_editor,id,w,h)
Protected mmx.i
; ***
y = *daten\markstart + *daten\toplimit
h = *daten\markclose + *daten\toplimit
; ***
x = *daten\markCursorFrom
w = *daten\markCursorInto
; ***
Debug "Y: " + Str(y) + " | H: " + Str(h) + " | X: " + Str(x) + " | W: " + Str(w)
If IsGadget(id)
If StartDrawing(ImageOutput(*daten\visbkg))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
mmx = ImageWidth(*daten\visbkg) - (*daten\markCursorInto - *daten\markCursorFrom)
; ***
Box( ImageWidth(*daten\tempor) + 6 + *daten\markCursorFrom, *daten\markstart * *daten\theight, w - mmx, (*daten\markclose - *daten\markstart) * *daten\theight, *daten\color_bkg )
; ***
StopDrawing()
EndIf
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Markierungsstart und Richtungskorrektur setzen, sobald die Markierung
; mittels Tastatur durchgeführt wird
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
Procedure setKeyMarkStart(key.i, *daten.struct_pure_multiline_code_editor)
Protected p.i, tww.i, cc.i = *daten\cursor
; ***
Select key
Case #pure_keycode_left
cc + 1
Case #pure_keycode_right
cc - 1
EndSelect
; ***
If StartDrawing(ImageOutput(*daten\curlin))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
For p = 0 To 19999
If cc = p
Break
EndIf
; ***
*daten\markpos = p
*daten\markCursorFrom = tww
; ***
If *daten\strom[p]\char
tww + TextWidth(*daten\strom[p]\char)
Else
tww + TextWidth(" ")
EndIf
Next
; ***
StopDrawing()
; ***
*daten\marklen = *daten\markpos
*daten\markCursorInto = *daten\markCursorFrom
; ***
;Debug Str(*daten\markpos) + " -> " + Str(*daten\markCursorFrom)
*daten\mark = #True
*daten\markmode = #False
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Realisiert den Syntax-Editor, samt Eingabe und Maus-Events
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
#ControlUpMore = #PB_Canvas_Command
CompilerElse
#ControlUpMore = #PB_Canvas_Control
CompilerEndIf
Procedure update(*daten.struct_pure_multiline_code_editor,id.i,evt.i,key.i,inp.i,mx.i,my.i)
If IsGadget(id)
Protected w.i, h.i, p.i, n.i, tw.d, cc.s, du.a = #False, sb.a = #False, top.i, pos.i
Protected tt.i, tx.s, ti.i, m.i, tww.d, mmx.i, emi.a = 0, gi.i, gu.i, tps.s = "", dd.d
Protected tix.i, tiy.i, tiw.i, tih.i
; ***
w = GadgetWidth(id)
h = GadgetHeight(id)
; ***
Select evt
Case #PB_EventType_LeftButtonDown, #PB_EventType_RightButtonDown, #PB_EventType_MiddleButtonDown
;{
mmx = -90000
; ***
*daten\markdif = 0
; ***
If *daten\mark = #True
tix = ImageWidth(*daten\tempor) + 6 + *daten\markCursorFrom
tiy = *daten\markstart * *daten\theight
tiw = w - ImageWidth(*daten\visbkg) - (*daten\markCursorInto - *daten\markCursorFrom)
tih = (*daten\markclose - *daten\markstart) * *daten\theight
; ***
;Box( ImageWidth(*daten\tempor) + 6 + *daten\markCursorFrom, *daten\markstart * *daten\theight, w - mmx, (*daten\markclose - *daten\markstart) * *daten\theight, *daten\color_marked_bkg )
If mx >= tix And mx <= tix + tiw And my >= tiy And my <= tiy + tih
; nix
Else
*daten\mark = #False
*daten\markmode = #False
EndIf
EndIf
; ***
For m = 0 To *daten\vislimit
If my >= ( m * *daten\theight ) And my <= ( m * *daten\theight ) + *daten\theight
*daten\index = *daten\position + *daten\toplimit
; ***
update_current_syntax(*daten)
; ***
update_content( *daten, id, w, h )
; ***
*daten\content\set( *daten\index, getInputStringLine(*daten) )
; ***
*daten\position = m
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
allocate_current_line( *daten )
; ***
mmx = mx - ImageWidth(*daten\tempor)
; ***
If mmx < 0
*daten\cursor = 1
Else
If StartDrawing(ImageOutput(*daten\curlin))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
For p = 0 To *daten\length -1
If mmx >= tww And mmx <= tww + TextWidth(*daten\strom[p]\char)
*daten\cursor = p
; ***
emi = 1
; ***
*daten\markCursorFrom = tww
; ***
*daten\markpos = p
; ***
Break
EndIf
; ***
tww + TextWidth(*daten\strom[p]\char)
Next
; ***
StopDrawing()
; ***
If emi = 0
*daten\cursor = *daten\length
EndIf
EndIf
EndIf
; ***
du = #True
; ***
Break
EndIf
Next
; ***
If mx <= ImageWidth(*daten\tempor)
*daten\markpos = 0
*daten\marklen = 19999
*daten\markCursorFrom = 0
*daten\markCursorInto = ImageWidth(*daten\visbkg) - ImageWidth(*daten\tempor) - 6
EndIf
; ***
If mmx <> -90000
If evt = #PB_EventType_LeftButtonDown
*daten\mark = #True
; ***
*daten\markrel = *daten\position
*daten\markrow = *daten\index
; ***
*daten\markstart = *daten\markrel
*daten\markclose = *daten\markrel
EndIf
EndIf
;}
Case #PB_EventType_LeftButtonUp
;{
*daten\markmode = #True
ProcedureReturn
;}
Case #PB_EventType_MouseMove
;{
If *daten\mark = #True And *daten\markmode = #False
mmx = mx - ImageWidth(*daten\tempor) : tww = 0
; ***
If StartDrawing(ImageOutput(*daten\curlin))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
For p = 0 To 19999
If tww >= w - ImageWidth(*daten\tempor)
Break
EndIf
; ***
If mmx >= tww And mmx <= tww + TextWidth(*daten\strom[p]\char)
*daten\markCursorInto = tww
; ***
*daten\marklen = p
; ***
Break
EndIf
; ***
If *daten\strom[p]\char
tww + TextWidth(*daten\strom[p]\char)
Else
tww + TextWidth(" ")
EndIf
Next
; ***
StopDrawing()
EndIf
; ***
mmx = -90000
; ***
tww = 0
; ***
For m = 0 To *daten\vislimit
If my >= ( m * *daten\theight ) And my <= ( m * *daten\theight ) + *daten\theight
mmx = m
; ***
Break
EndIf
Next
; ***
If mmx <> -90000
If mmx >= *daten\markrel
*daten\markstart = *daten\markrel
*daten\markclose = mmx + 1
Else
*daten\markstart = mmx
*daten\markclose = *daten\markrel + 1
EndIf
EndIf
Else
ProcedureReturn
EndIf
;}
Case #PB_EventType_MouseWheel
;{
;}
Case #PB_EventType_Input
;{
If Not GetGadgetAttribute(id, #PB_Canvas_Modifiers) & #ControlUpMore
If inp = 32 Or inp = 9 Or inp = 10 Or inp = 13
If *daten\curlen
If *daten\curpos >= 0 And *daten\curpos < *daten\length
cc = ""
; ***
update_current_token( *daten, *daten\curpos, *daten\curlen )
EndIf
EndIf
; ***
*daten\curpos = *daten\cursor + 1
*daten\curlen = 0
ElseIf inp <> 32 And inp <> 9
*daten\curlen + 1
EndIf
; ***
If *daten\cursor = 0
If *daten\length
p = *daten\length
; ***
If p >= 0 And p < 20000
Repeat
*daten\strom[p+1]\char = *daten\strom[p]\char
*daten\strom[p+1]\color = *daten\strom[p]\color
*daten\strom[p]\color = 0
; ***
p - 1
Until p = 0
EndIf
EndIf
; ***
*daten\strom[0]\char = Chr(inp)
ElseIf *daten\cursor = *daten\length
*daten\strom[*daten\cursor]\char = Chr(inp)
Else
p = *daten\length
; ***
Repeat
If p >= 0 And p <= 19998
*daten\strom[p+1]\char = *daten\strom[p]\char
*daten\strom[p+1]\color = *daten\strom[p]\color
Else
Break
EndIf
; ***
p - 1
Until p = *daten\cursor -1
; ***
*daten\strom[*daten\cursor]\char = Chr(inp)
*daten\strom[*daten\cursor]\color = 0
EndIf
; ***
*daten\cursor + 1
*daten\length + 1
; ***
*daten\cursorDisplay = #True
; ***
update_current_syntax(*daten)
; ***
*daten\mark = #False
*daten\markmode = #False
; ***
*daten\markrel = *daten\position
*daten\markrow = *daten\index
; ***
*daten\markstart = *daten\markrel
*daten\markclose = *daten\markrel
; ***
du = #True
EndIf
;}
Case #PB_EventType_KeyUp
;{
If *daten\intellivis = #False
If *daten\mark = #True
*daten\markmode = #True
; ***
*daten\markdif = 1
; ***
;*daten\markrel = *daten\position
;*daten\markrow = *daten\index
; ***
*daten\markstart = *daten\markrel
*daten\markclose = *daten\markrel + 1
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
update_current_syntax(*daten)
; ***
update_content( *daten, id, w, h )
; ***
*daten\content\set( *daten\index, getInputStringLine(*daten) )
EndIf
EndIf
;}
Case #PB_EventType_KeyDown
Select key
Case #pure_keycode_tabbed
;{
If *daten\cursor < 19998 - 1
*daten\length + 1
*daten\cursor + 1
*daten\strom[*daten\cursor]\char = " "
*daten\strom[*daten\cursor]\color = 0
*daten\strom[*daten\cursor]\pos = 0
; ***
If *daten\cursor < 19998 - 1
*daten\length + 1
*daten\cursor + 1
*daten\strom[*daten\cursor]\char = " "
*daten\strom[*daten\cursor]\color = 0
*daten\strom[*daten\cursor]\pos = 0
; ***
If *daten\cursor < 19998 - 1
*daten\length + 1
*daten\cursor + 1
*daten\strom[*daten\cursor]\char = " "
*daten\strom[*daten\cursor]\color = 0
*daten\strom[*daten\cursor]\pos = 0
; ***
SetActiveGadget( id )
; ***
du = #True
EndIf
EndIf
EndIf
;}
Case #pure_keycode_pos
*daten\cursor = 1
Case #pure_keycode_end
*daten\cursor = *daten\length
Case #pure_keycode_up
;{
If *daten\intellivis = #False
If *daten\position = 0 And *daten\toplimit = 0
ProcedureReturn
EndIf
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
update_current_syntax(*daten)
; ***
update_content( *daten, id, w, h )
; ***
*daten\content\set( *daten\index, getInputStringLine(*daten) )
; ***
*daten\position - 1
; ***
If *daten\position < 0
*daten\toplimit - 1
*daten\position = 0
; ***
If *daten\toplimit < 0
*daten\toplimit = 0
EndIf
; ***
*daten\condir = 1
update_content( *daten, id, w, h )
; ***
sb = #True
EndIf
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
allocate_current_line( *daten )
; ***
If *daten\movetolast = #True
*daten\movetolast = #False
; ***
*daten\cursor = *daten\length
EndIf
; ***
du = #True
Else
*daten\intellicur - 1
; ***
If *daten\intellicur < 0
*daten\intellicur = 0
EndIf
EndIf
;}
Case #pure_keycode_enter, #pure_keycode_down
;{
If *daten\intellivis = #False
*daten\index = *daten\position + *daten\toplimit
; ***
update_current_syntax(*daten)
; ***
update_content( *daten, id, w, h )
; ***
*daten\content\set( *daten\index, getInputStringLine(*daten) )
; ***
If *daten\index > *daten\content\lines() -2
If key = #pure_keycode_down
ProcedureReturn
EndIf
EndIf
; ***
*daten\position + 1
; ***
If *daten\position > *daten\vislimit
*daten\toplimit + 1
; ***
If *daten\toplimit > *daten\content\length() - 1 - *daten\vislimit
*daten\toplimit = *daten\content\length() - 1 - *daten\vislimit
*daten\position = *daten\vislimit
Else
*daten\position - 1
EndIf
; ***
*daten\condir = 2
update_content( *daten, id, w, h )
; ***
sb = #True
EndIf
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
du = #True
; ***
If key = #pure_keycode_enter
*daten\content\add(" ")
; ***
*daten\cursor = 1
ElseIf key = #pure_keycode_down
If *daten\index > *daten\content\length() - 1
*daten\index = *daten\content\length() - 1
*daten\toplimit = *daten\content\length() - *daten\vislimit
*daten\position = *daten\index - *daten\toplimit
EndIf
EndIf
; ***
allocate_current_line( *daten )
Else
If key = #pure_keycode_enter
If *daten\intellimar
tps + " "
EndIf
; ***
tps + *daten\intellitok
; ***
*daten\intellivis = 12
; ***
*daten\intellitok = ""
; ***
*daten\index = *daten\position + *daten\toplimit
; ***
*daten\content\set( *daten\index, getInputStringLine(*daten) + tps )
; ***
*daten\cursor + Len(tps)
*daten\length + Len(tps)
; ***
allocate_current_line( *daten )
; ***
update_current_syntax(*daten)
; ***
update_content( *daten, id, w, h )
; ***
du = #True
ElseIf key = #pure_keycode_down
*daten\intellicur + 1
; ***
If *daten\intellicur > *daten\intellitot -1
*daten\intellicur = *daten\intellitot -1
EndIf
EndIf
EndIf
;}
Case #pure_keycode_delete
;{
If *daten\cursor = 0
; Rauf auf die obere Zeile oder ignorieren
ElseIf *daten\cursor = *daten\length
*daten\strom[*daten\cursor]\char = ""
*daten\strom[*daten\cursor]\color = 0
*daten\strom[*daten\cursor]\pos = 0
*daten\cursor -1
*daten\length -1
Else
For p = *daten\cursor To *daten\length
*daten\strom[p-1]\char = *daten\strom[p]\char
*daten\strom[p-1]\color = *daten\strom[p]\color
*daten\strom[p-1]\pos = *daten\strom[p]\pos
Next
; ***
*daten\strom[*daten\length]\char = ""
*daten\strom[*daten\length]\color = 0
*daten\strom[*daten\length]\pos = 0
; ***
*daten\cursor -1
*daten\length -1
EndIf
; ***
If *daten\cursor = 1
If *daten\length <= 1
*daten\strom[0]\char = ""
*daten\strom[0]\color = 0
*daten\strom[0]\pos = 0
EndIf
EndIf
; ***
du = #True
;}
Case #pure_keycode_left
;{
If *daten\intellivis = #False
If *daten\cursor <= 1
*daten\movetolast = #True
update(*daten,id,#PB_EventType_KeyDown,#pure_keycode_up,0,0,0)
ProcedureReturn
Else
*daten\cursor - 1
; ***
If *daten\cursor < 0
*daten\cursor = 0
EndIf
; ***
*daten\curpos = *daten\cursor
; ***
du = #True
EndIf
; ***
;setKeyMarkStart(*daten)
Else
*daten\intellivis = 12
EndIf
;}
Case #pure_keycode_right
;{
If *daten\intellivis = #False
If *daten\cursor = *daten\length
update(*daten,id,#PB_EventType_KeyDown,#pure_keycode_down,0,0,0)
ProcedureReturn
Else
*daten\cursor + 1
; ***
If *daten\cursor > *daten\length
*daten\cursor = *daten\length
EndIf
; ***
*daten\curpos = *daten\cursor
; ***
du = #True
EndIf
; ***
;setKeyMarkStart(*daten)
Else
*daten\intellivis = 12
EndIf
;}
Case #pure_keycode_escape, #pure_keycode_space
;{
If *daten\intellivis = #True
*daten\intellivis = 12
EndIf
;}
EndSelect
; ***
If GetGadgetAttribute(id, #PB_Canvas_Modifiers) & #ControlUpMore
Select key
Case Asc("c"), Asc("C") ; Kopieren
ClearClipboard()
SetClipboardText(getMarkedText(*daten))
Case Asc("x"), Asc("X") ; Schneiden
ClearClipboard()
SetClipboardText(getMarkedText(*daten))
clearMarkedText(*daten)
clearImageArea(*daten,id,w,h)
Case Asc("v"), Asc("V") ; Einfügen
Debug "Paste"
Case Asc("a"), Asc("A") ; Alles markieren
Debug "Select all"
EndSelect
ElseIf GetGadgetAttribute(id, #PB_Canvas_Modifiers) & #PB_Canvas_Shift
tww = 0
; ***
Select key
Case #pure_keycode_up
If *daten\mark = #True
*daten\markstart - 1
; ***
If *daten\markstart < 0
*daten\markstart = 0
Else
*daten\markclose = *daten\markrel + 1
; ***
If *daten\markclose > *daten\vislimit
*daten\markclose = *daten\vislimit
EndIf
EndIf
EndIf
Case #pure_keycode_down
If *daten\mark = #True
*daten\markclose + 1
; ***
If *daten\markclose > *daten\vislimit
*daten\markclose = *daten\vislimit
Else
*daten\markstart = *daten\markrel
; ***
If *daten\markstart < 0
*daten\markstart = 0
EndIf
EndIf
EndIf
Case #pure_keycode_left, #pure_keycode_right
If *daten\mark = #False
setKeyMarkStart(key,*daten)
; ***
*daten\markrel = *daten\position
*daten\markrow = *daten\index
Else;If *daten\mark = #True And *daten\markmode = #False
If StartDrawing(ImageOutput(*daten\curlin))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
For p = 0 To 19999
If tww >= w - ImageWidth(*daten\tempor)
Break
EndIf
; ***
If *daten\cursor = p
Break
EndIf
; ***
*daten\marklen = p
*daten\markCursorInto = tww
; ***
If *daten\strom[p]\char
tww + TextWidth(*daten\strom[p]\char)
Else
tww + TextWidth(" ")
EndIf
Next
; ***
StopDrawing()
EndIf
EndIf
EndSelect
; ***
tww = 0
Else
*daten\mark = #False
*daten\markmode = #False
EndIf
EndSelect
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Cursor korrigieren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
;{
If *daten\cursor <= 0
*daten\cursor = 1
EndIf
; ***
If *daten\length < *daten\cursor
*daten\length = *daten\cursor
EndIf
;}
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Zeilennummernblock
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
;{
If *daten\theight = 0
sb = #True
EndIf
; ***
If sb
du = #True
; ***
If CreateImage(*daten\tempor,w,h) And StartDrawing(ImageOutput(*daten\tempor))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
*daten\theight = TextHeight("A")
; ***
*daten\vislimit = (h / *daten\theight) - 1
; ***
If *daten\vislimit <= 0
*daten\vislimit = 1
EndIf
; ***
ti = TextWidth(Str(*daten\content\lines())) + 60
; ***
StopDrawing()
EndIf
; ***
If CreateImage(*daten\tempor,ti,h) And StartDrawing(ImageOutput(*daten\tempor))
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
Box( 0, 0, ti, h, *daten\color_number_block_bkg )
; ***
For n = 0 To *daten\vislimit + 2
tx = Str(n + *daten\toplimit + 1)
; ***
DrawText( ti - 50 - TextWidth(tx), n * *daten\theight, tx, *daten\color_number_block_txt )
Next
; ***
StopDrawing()
EndIf
EndIf
;}
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Aktuelle Zeile zeichnen
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
;{
If du
*daten\lastkey = ""
; ***
If CreateImage(*daten\curlin,w,*daten\theight) And StartDrawing(ImageOutput(*daten\curlin))
Box( 0, 0, w, h, $FFFFFF ) ; VORÜBRGEHEND
; ***
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
If evt = #PB_EventType_Input
*daten\theight = TextHeight("A")
; ***
*daten\vislimit = (h / *daten\theight) - 1
; ***
If *daten\vislimit <= 0
*daten\vislimit = 1
EndIf
EndIf
; ***
For p = 0 To *daten\length -1
If p = 0
DrawText( 0, 0, *daten\strom[p]\char, *daten\strom[p]\color )
Else
DrawText( tw, 0, *daten\strom[p]\char, *daten\strom[p]\color )
EndIf
; ***
If *daten\strom[p]\char = " "
*daten\lastkey = ""
Else
*daten\lastkey + *daten\strom[p]\char
EndIf
; ***
*daten\strom[p]\pos = tw
; ***
tw + TextWidth(*daten\strom[p]\char)
; ***
If p = *daten\cursor -1
pos = tw
EndIf
Next
; ***
StopDrawing()
EndIf
EndIf
;}
; ***
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; CanvasGadget aktualisieren
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; ***
;{
top = *daten\position * *daten\theight
; ***
If du
*daten\curstate = pos + ImageWidth(*daten\tempor) + 6
EndIf
; ***
If StartDrawing(CanvasOutput(id))
;{ Abbilder für die Darstellung
Box( 0, 0, w, h, *daten\color_bkg )
; ***
If IsFont(100)
DrawingFont( FontID(100) )
EndIf
; ***
If IsImage(*daten\tempor)
DrawImage( ImageID(*daten\tempor), 0, 0 )
EndIf
; ***
If IsImage(*daten\visbkg)
DrawImage( ImageID(*daten\visbkg), ImageWidth(*daten\tempor) + 6, 0 )
EndIf
; ***
If IsImage(*daten\curlin)
DrawImage( ImageID(*daten\curlin), ImageWidth(*daten\tempor) + 6, top )
EndIf
; ***
If *daten\cursorDisplay; And *daten\intellivis = #False
Box( *daten\curstate, top, 2, *daten\theight, 0 )
EndIf
; ***
Box( ImageWidth(*daten\tempor) - 50 + 4, top, 46, *daten\theight, *daten\color_number_block_active )
;}
; ***
;{ Markierung zeichnen
DrawingMode( #PB_2DDrawing_Transparent )
; ***
If *daten\mark = #True
If *daten\markstart * *daten\theight - (*daten\markclose - *daten\markstart) * *daten\theight <> 6
Box( ImageWidth(*daten\tempor) - 50 + 4, *daten\markstart * *daten\theight, 46, (*daten\markclose - *daten\markstart) * *daten\theight, *daten\color_number_block_active )
; ***
DrawingMode( #PB_2DDrawing_AlphaBlend )
; ***
mmx = ImageWidth(*daten\visbkg) - (*daten\markCursorInto - *daten\markCursorFrom)
; ***
Box( ImageWidth(*daten\tempor) + 6 + *daten\markCursorFrom, *daten\markstart * *daten\theight, w - mmx, (*daten\markclose - *daten\markstart) * *daten\theight, *daten\color_marked_bkg )
; ***
DrawingMode( #PB_2DDrawing_Outlined )
; ***
Box( ImageWidth(*daten\tempor) + 6 + *daten\markCursorFrom, *daten\markstart * *daten\theight, w - mmx, (*daten\markclose - *daten\markstart) * *daten\theight, *daten\color_marked_border )
EndIf
EndIf
;}
; ***
;{ Cursor
Box( ImageWidth(*daten\tempor), 0, 6, h, *daten\color_bkg )
;}
; ***
; DIESEN PART IN EIN THREAD AUSLAGERN!!!
;{ Intellisence*
If *daten\intellivis = 12
*daten\intellivis = #False
ElseIf evt = #PB_EventType_KeyDown Or *daten\intellivis = #True
If key = 46 Or *daten\intellivis = #True Or TLCase(*daten\lastkey) = "belirle" Or TLCase(*daten\lastkey) = "dizilim" Or TLCase(*daten\lastkey) = "değişken"
If *daten\intellivis = #False
*daten\intellivis = #True
*daten\intellicur = 0
EndIf
; ***
If *daten\lastkey And *daten\intellisence And *daten\comment = 0 And *daten\stringi = 0
For p = 0 To *daten\intellisence\cnt -1
For x = 0 To *daten\intellisence\lst[p]\groupkeys\lines() -1
If Trim(TLCase(*daten\intellisence\lst[p]\groupkeys\get(x))) = Trim(TLCase(*daten\lastkey))
*daten\intelliLastWidth = *daten\intellisence\lst[p]\width + 16
; ***
If *daten\curstate + *daten\intelliLastWidth > w
*daten\curstate = w - *daten\intelliLastWidth
EndIf
; ***
If top > h - (4 * *daten\theight) - 16
top = h - (4 * *daten\theight) - 16
EndIf
; ***
Box( *daten\curstate + 10, top, *daten\intellisence\lst[p]\width + 6, (4 * *daten\theight) + 6, *daten\color_intelli_background )
; ***
DrawingMode( #PB_2DDrawing_Outlined )
; ***
Box( *daten\curstate + 10, top, *daten\intellisence\lst[p]\width + 5, (4 * *daten\theight) + 5, *daten\color_intelli_dborder )
Box( *daten\curstate + 10 + 1, top + 1, *daten\intellisence\lst[p]\width + 5, (4 * *daten\theight) + 5, *daten\color_intelli_lborder )
Box( *daten\curstate + 10, top, *daten\intellisence\lst[p]\width + 6, (4 * *daten\theight) + 6, *daten\color_intelli_border )
; ***
DrawingMode( #PB_2DDrawing_Transparent )
; ***
m = 0
; ***
*daten\intellimar = *daten\intellisence\lst[p]\space
; ***
*daten\intellitot = *daten\intellisence\lst[p]\content\lines()
; ***
ti = *daten\intellicur
; ***
If ti > *daten\intellitot - 4
ti = *daten\intellitot - 4
EndIf
; ***
For n = ti To ti + 3
If n = *daten\intellicur
Box( *daten\curstate + 13, top + 3 + (m * *daten\theight), *daten\intellisence\lst[p]\width, *daten\theight, *daten\color_intelli_sel_bkg )
DrawText( *daten\curstate + 10 + 6, top + 3 + (m * *daten\theight), *daten\intellisence\lst[p]\content\get(n), *daten\color_intelli_sel_txt )
*daten\intellitok = *daten\intellisence\lst[p]\content\get(n)
Else
DrawText( *daten\curstate + 10 + 6, top + 3 + (m * *daten\theight), *daten\intellisence\lst[p]\content\get(n), *daten\color_intelli_text )
EndIf
m + 1
Next
; ***
Break
EndIf
Next
Next
EndIf
EndIf
EndIf
;}
; ***
StopDrawing()
EndIf
;}
EndIf
EndProcedure
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
; Test
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ;
ExamineDesktops()
OpenWindow(#fenster,0,0,800,700,"Eingabe",
#PB_Window_SystemMenu|#PB_Window_Invisible)
CanvasGadget(#feld,0,0,800,700,#PB_Canvas_Keyboard)
SetActiveGadget(#feld)
ResizeWindow(#fenster,DesktopWidth(0)-800,
DesktopHeight(0)-800,800,700)
StickyWindow(#fenster,1)
HideWindow(#fenster,0)
AddWindowTimer(#fenster,#fenster,400)
Global ib.struct_intellisence_list
; ***
ib\cnt = 0
keyw.editor_dataset = editor_dataset()
mich.struct_pure_multiline_code_editor
mich\intellisence = ib
mich\content = editor_dataset()
For vi = 0 To 99
mich\content\add( "" )
Next
mich\color_comment = RGB( 147, 133, 148 )
mich\color_string = RGB( 106, 144, 166 )
mich\color_number = RGB( 204, 51, 153 )
mich\color_operator = RGB( 170, 148, 84 );RGB( 153, 51, 255 );RGB( 118, 92, 163 )
mich\color_bkg = RGB( 255, 255, 255 )
mich\color_selbkg = RGB( 238, 238, 238 )
mich\color_errorbkg = RGB( 239, 207, 203 )
mich\color_number_block_active = RGB( 228, 228, 228 )
mich\color_number_block_bkg = RGB( 238, 238, 238 );RGB( 154, 149, 166 );RGB( 137, 121, 158 );RGB( 98, 62, 133 )
mich\color_number_block_txt = RGB( 154, 149, 166 );RGB(255,255,255)
mich\color_intelli_background = RGB( 238, 238, 238 )
mich\color_intelli_border = RGB(140,150,160)
mich\color_intelli_lborder = RGB(245,248,251)
mich\color_intelli_dborder = RGB(160,170,180)
mich\color_intelli_text = 0
mich\color_intelli_sel_bkg = RGB( 0, 153, 204 )
mich\color_intelli_sel_txt = RGB( 243, 255, 255 )
mich\color_marked_border = RGB( 0, 153, 204 )
mich\color_marked_bkg = RGBA( 0, 153, 204, 20 )
mich\intellivis = #False
c = RGB( 51, 153, 204 );RGB( 36, 134, 255 )
keyw\add( "Define", c )
keyw\add( "Global", c )
keyw\add( "Protected", c )
keyw\add( "Static", c )
keyw\add( "Threaded", c )
keyw\add( "ElseIf", c )
keyw\add( "Else", c )
keyw\add( "EndIf", c )
keyw\add( "If", c )
keyw\add( "ForEach", c )
keyw\add( "For", c )
keyw\add( "Next", c )
keyw\add( "Break", c )
keyw\add( "Repeat", c )
keyw\add( "Forever", c )
keyw\add( "Until", c )
keyw\add( "EndProcedure", c )
keyw\add( "Procedure", c )
keyw\add( "EndInterface", c )
keyw\add( "Interface", c )
keyw\add( "EndStructure", c )
keyw\add( "Structure", c )
keyw\add( "ReDim", c )
keyw\add( "Dim", c )
keyw\add( "XIncludeFile", c )
keyw\add( "IncludeFile", c )
keyw\add( "Debug", c )
keyw\add( "CompilerElseIf", c )
keyw\add( "CompilerElse", c )
keyw\add( "CompilerIf", c )
keyw\add( "CompilerEndIf", c )
keyw\add( "And", c )
keyw\add( "Not", c )
keyw\add( "Or", c )
keyw\add( "CompilerEndSelect", c )
keyw\add( "CompilerCase", c )
keyw\add( "CompilerDefault", c )
keyw\add( "CompilerSelect", c )
keyw\add( "EndSelect", c )
keyw\add( "Case", c )
keyw\add( "Default", c )
keyw\add( "Select", c )
; ***
c = RGB( 102, 102, 153 )
keyw\add( "Len", c )
keyw\add( "Mid", c )
keyw\add( "Left", c )
keyw\add( "Right", c )
keyw\add( "Trim", c )
keyw\add( "LTrim", c )
keyw\add( "RTrim", c )
keyw\add( "ReplaceString", c )
keyw\add( "FindString", c )
keyw\add( "CountString", c )
keyw\add( "ReverseString", c )
keyw\add( "LCase", c )
keyw\add( "UCase", c )
keyw\add( "StrD", c )
keyw\add( "StrF", c )
keyw\add( "Str", c )
keyw\add( "ValD", c )
keyw\add( "ValF", c )
keyw\add( "Val", c )
keyw\add( "RunProgram", c )
keyw\add( "Delay", c )
keyw\add( "OpenWindow", c )
keyw\add( "ButtonGadget", c )
keyw\add( "ButtonImageGadget", c )
keyw\add( "CheckBoxGadget", c )
keyw\add( "OptionGadget", c )
keyw\add( "CanvasGadget", c )
keyw\add( "ImageGadget", c )
keyw\add( "PanelGadget", c )
keyw\add( "TreeGadget", c )
keyw\add( "ListViewGadget", c )
keyw\add( "ListIconGadget", c )
keyw\add( "SpinGadget", c )
keyw\add( "SplitterGadget", c )
keyw\add( "WebGadget", c )
keyw\add( "StringGadget", c )
keyw\add( "TextGadget", c )
keyw\add( "ComboBoxGadget", c )
keyw\add( "DateGadget", c )
keyw\add( "CalenderGadget", c )
; ***
c = RGB( 154, 71, 193 )
keyw\add( "PB_Compiler_OS", c )
keyw\add( "PB_OS_MacOS", c )
keyw\add( "PB_OS_Linux", c )
keyw\add( "PB_OS_Windows", c )
keyw\add( "PB_Event_Gadget", c )
keyw\add( "PB_Event_CloseWindow", c )
keyw\add( "PB_Event_SizeWindow", c )
keyw\add( "PB_Event_MoveWindow", c )
keyw\add( "PB_Event_MaximizeWindow", c )
keyw\add( "PB_Event_MinimizeWindow", c )
keyw\add( "True", c )
keyw\add( "False", c )
keyw\add( "PB_Any", c )
keyw\add( "PB_Ignore", c )
mich\comment_char = ";"
mich\string_char = Chr(34)
mich\double_separator = "."
mich\keywords = keyw
mich\visbkg = 10
mich\tmpbkg = 11
mich\curlin = 12
mich\tempor = 13
update(mich,#feld,0,0,0,0,0)
Repeat
ev.i = WaitWindowEvent()
; ***
If ev = #PB_Event_CloseWindow
;For r = 0 To mich\content\lines() -1
;Debug Str(r) + ":" + Str(r+1) + " >> " + mich\content\get(r)
;Next
EndIf
; ***
If ev = #PB_Event_Timer And EventTimer() = #fenster
Select mich\cursorDisplay
Case 0 : mich\cursorDisplay = 1
Case 1 : mich\cursorDisplay = 0
EndSelect
; ***
update(mich,#feld,0,0,0,0,0)
EndIf
; ***
If ev = #PB_Event_Gadget And EventGadget() = #feld
Select EventType()
Case #PB_EventType_Input, #PB_EventType_KeyDown, #PB_EventType_KeyUp,
#PB_EventType_LeftButtonDown, #PB_EventType_LeftButtonUp,
#PB_EventType_RightButtonUp, #PB_EventType_MouseMove,
#PB_EventType_MouseWheel
update(mich,#feld,EventType(),
GetGadgetAttribute(#feld,#PB_Canvas_Key),
GetGadgetAttribute(#feld,#PB_Canvas_Input),
GetGadgetAttribute(#feld,#PB_Canvas_MouseX),
GetGadgetAttribute(#feld,#PB_Canvas_MouseY))
EndSelect
EndIf
Until ev = #PB_Event_CloseWindow
End
Re: CanvasGadget-based alternative to Scintilla
can you share it via dropbox, quite a bit of code for copy and paste.
Windows 11, Manjaro, Raspberry Pi OS
Re: CanvasGadget-based alternative to Scintilla
The Debugger states an invalid MemoryID in Procedure editor_dataset__add() at tis line
*this\org = ReAllocateMemory( *this\org, MemorySize(*this\org) + 3 )
[08:27:26] Warte auf den Start des Executable...
[08:27:26] Executable-Typ: Windows - x64 (64bit, Unicode)
[08:27:26] Executable gestartet.
[08:27:26] [ERROR] Zeile: 409
[08:27:26] [ERROR] Das angegebene '*MemoryID' ist ungültig.
Re: CanvasGadget-based alternative to Scintilla
now available on github
https://github.com/5m-ware/syntax-highl ... -PureBasic
i tested it on windows xp in virtualbox, no problems, it is working. maybe it has todo with the 64bit windows release. please check the code, because i am not running windows 64bit based release. mainly i am working on mac.
https://github.com/5m-ware/syntax-highl ... -PureBasic
i tested it on windows xp in virtualbox, no problems, it is working. maybe it has todo with the 64bit windows release. please check the code, because i am not running windows 64bit based release. mainly i am working on mac.
Re: CanvasGadget-based alternative to Scintilla
i get the same error as Lord (both 32bit and 64bit)
Greetings ... Peter (Windows 10 Pro)
Greetings ... Peter (Windows 10 Pro)
Hygge
Re: CanvasGadget-based alternative to Scintilla
That part
under editor_dataset_add, has to be changed to
i have no idea why mac doesnt fire the same error. it would be make it easer to find such problems earlier.
Code: Select all
p = MemorySize(*this\org) - 5
Code: Select all
p = MemorySize(*this\org) - 3