Texteditor source
AGK V1 and V2
Okay, I have rewritten the textfield function. Just copy/paste
this code, it should work without media.
All the speed problems with bigger files are gone.
I would really like to hear your comments on this code
If you find any bugs, please report it here.
Features:
* Edit text on Windows/Android
* Input char replacement system
* Syntax Highlight
* Comments
* Dynamic size
* Fast Loading/Saving/Editing
There are still some bugs in it, I will try to fix these first
But it looks quite finished yet. The next thing will be an open/save dialogue for the glsl mobile app.
// AGK Textboxfield Online Arts 2015 - online-arts.de - Alex Schmidt
// set the resolution to 1280,720 this is good enough.
setvirtualresolution(1280,720)
// get the device name in order to add char replacements for the editbox input
global Device$ as string
Device$=GetDeviceName()
// textfield main type
type textfield_def
// handling
active as integer // currently active, or not
// information on the creation
px as integer // position x of the textfield
py as integer // position y
sx as integer // size x
sy as integer // size y
textsize as integer // textsize
scrollbox_size as integer // scrollbox_size
// text
text as integer // referes to the array
maxwidth as integer // results of text specifications
maxheight as integer // results of text specifications
// media for the scrollboxes
bgs1 as integer
bgs2 as integer
sb1 as integer
sb2 as integer
sb3 as integer
sb4 as integer
sbs0 as integer
sbs1 as integer
sbs2 as integer
sbs3 as integer
sbs4 as integer
// cursor
cursor as integer // cursor sprite
tcoordx as integer // tempcoord
tcoordy as integer // tempcoord
curblink as integer // responsible for the blinking
t_curx# as float // needed for some operation
t_cury# as float // needed for some operation
curx as integer // current cursor x coord
cury as integer // current cursor y coord
// mark a segment
selst1 as integer
selst2 as integer
setlt as integer
endtype
// syntax highlight main type
type syntax_highlight_def
keyword$ as string
follow as integer
r as integer
g as integer
b as integer
endtype
// initialize textfields - this command will initialize all the stuff for the textbox
// editbox 1 is used by this code, so don't use it any more while using this textfield.
init_textfields()
// char replacements
if Device$="android"
// for the input code "51" add chr(35) "#" because the standard editbox cant display this
add_char_rep(51,35)
endif
// This command will create a textfield
// It will create an empty file, if it doesnt exist
create_textfield("shader.vs",0,80,1280-40-0,720+20-100-40,40,2,40,0)
// add syntax highlight for the shader code
add_syntax("",1,0,0,0)
add_syntax("// ",1,170,85,85)
add_syntax("{",0,150,150,150)
add_syntax("}",0,150,150,150)
add_syntax("(",0,150,150,150)
add_syntax(")",0,150,150,150)
add_syntax(";",0,150,150,150)
add_syntax(",",0,150,150,150)
add_syntax(".",0,150,150,150)
add_syntax("attribute",0,130,30,30)
add_syntax("varying",0,130,30,30)
add_syntax("uniform",0,130,30,30)
add_syntax("sin",0,50,0,170)
add_syntax("cos",0,50,0,170)
add_syntax("tan",0,50,0,170)
add_syntax("abs",0,50,0,170)
add_syntax("mat2",0,161,30,130)
add_syntax("mat3",0,161,30,130)
add_syntax("mat4",0,161,30,130)
add_syntax("vec2",0,161,30,130)
add_syntax("vec3",0,161,30,130)
add_syntax("vec4",0,161,30,130)
add_syntax("const in vec2",0,161,30,130)
add_syntax("const in vec3",0,161,30,130)
add_syntax("const in vec4",0,161,30,130)
add_syntax("const in float",0,161,30,130)
add_syntax("const float",0,161,30,130)
add_syntax("gl_FragColor",0,161,30,130)
// resetting textfield:
// it is even possible to resize/ reposition the textfield or give
// a new textsize
// reset_textfield(num,x,y,sx,sy,textsize,scrollbox,scrollboxsize)
// main game loop
do
// write some basic information about some data
print("x:"+str(textfields[1].curx)+" y:"+str(textfields[1].cury)+" maxlines: "+textfiles[1,0]+" maxwidth: "+str(textfields[1].maxwidth)+" maxheight: "+str(textfields[1].maxheight))
print("tcoordx: "+str(textfields[1].tcoordx)+" tcoordy:"+str(textfields[1].tcoordy)+" lastchar:"+str(last_text_char(1,textfields[1].cury)))
// this is just a simple command to add a save text feature
// for windows. I think its F5 what will trigger a save^^
if Device$="windows"
if getrawkeystate(116)
save_text(1,"newtext.txt")
endif
endif
// this two commands will handle the textfields
// the control_textfield routine will manage all
// key input for windows and android systems
// Handle_textfields will manage the modifications
// and display the textfield
control_textfields()
handle_textfields()
Sync()
loop
// end of the loop
// =========================================================================
// ===== Char replacement system ========== Online Arts ============ 1.0 ===
// =========================================================================
// This char system can add accitional editbox keys. Some chars are not
// available by standard in the editbox format. This function can help to
// replace all the missing chars. If you push the right android button now,
// you will also get the right char
// this system is used during the initialization and during the
// handle_textfield routine
// Find the char in the register and return the char as string
function get_char_rep(num)
g$=chr(char_replacements[num])
endfunction g$
// Add a char to the replacement system
// You have to find out the keys by a simple "scancode" program
function add_char_rep(charin,charout)
char_replacements[charin]=charout
endfunction
// =========================================================================
// =========================================================================
// =========================================================================
// === syntax highlight ================== Online Arts ============== 1.0 ==
// =========================================================================
function add_syntax(keyword$,follow,r,g,b)
inc syntax_highlightstart
syntax_hightlight[syntax_highlightstart].keyword$=keyword$
syntax_hightlight[syntax_highlightstart].follow=follow
syntax_hightlight[syntax_highlightstart].r=r
syntax_hightlight[syntax_highlightstart].g=g
syntax_hightlight[syntax_highlightstart].b=b
endfunction
// =========================================================================
// =========================================================================
// =========================================================================
// == Online Arts Textfield Library ========================================
// =========================================================================
// =========================================================================
// This functions will help you to add a nice textfield to you applications
// There are a lot of functions and I try to comment everyone
// initialize textfields, if you came here, you are really intrested in
// this function! congratulation! :) This command initialize the whole
// textfield. It will set the arrays maximal length and also create the editbox
// Warning: Editbox "1" is used by this code to manage the input for all textfields
// do not use editbox 1 for other purposes :)
function init_textfields()
// limitations of the textfields
char_rep_length=256
textfield_length=16
textfield_lines_length=65536
syntax_highlight_length=64
// this is the maximum of all chars. As the editor only needs 255 char ASCII,
// the lenght of 256 is good
dim char_replacements[char_rep_length] as integer
// this will contain the textfield information
dim textfields[textfield_length] as textfield_def
// this will contain all the text as single lines
dim textfiles[textfield_length,textfield_lines_length] as string
// this will count all inputs to the text
global textfieldstart as integer
// create the syntax highlight array
dim syntax_hightlight[syntax_highlight_length] as syntax_highlight_def
// count the syntax highlight
global syntax_highlightstart as integer
// create a editbox
CreateEditBox(1)
SetEditBoxPosition(1,0,-50)
endfunction
// create textfield
// this command will create the textfield by the given variables
function create_textfield(file$,px,py,sx,sy,textsize,scrollboxes,scrollbox_size,debug)
inc textfieldstart // count all textfields
spritedepth=20 // this is the depth of all sprites, useful to combine this function with other creations
// background media
i1=img_create_RGBA(2,2,20,20,20,255) // shadow of the textfield
i2=img_create_RGBA(2,2,255,255,255,255) // textfield main color
i3=img_create_RGBA(2,textsize,250,20,20,255) // create cursor image
// shadow background
bgs1=createsprite(i1)
setspritedepth(bgs1,spritedepth)
setspriteposition(bgs1,px-2,py-2)
setspritesize(bgs1,sx+6,sy+6)
// create main textfield background
bgs2=createsprite(i2)
setspritedepth(bgs2,spritedepth)
setspriteposition(bgs2,px,py)
setspritesize(bgs2,sx,sy)
// load the textfile
setfolder("/media")
if file$<>""
if getfileexists(file$)=1 // if the textfile exists
max_lines=max_file_lines(file$,65536) // get the max file length, check for maximal 65536 chars
file=opentoread(file$) // open the file
for i=1 to max_lines
line$=readline(file)
// check for useless tab symbols
outl$=""
for x=1 to len(line$)
if asc(mid(line$,x,1))<>9
outl$=outl$+mid(line$,x,1)
endif
next x
textfiles[textfieldstart,i]=outl$
next i
textfiles[textfieldstart,0]=str(max_lines-1) // save the max_lines into the arrayslot 0 as string
closefile(file)
else
max_lines=1
textfiles[textfieldstart,0]=str(0)
endif
else
max_lines=1
textfiles[textfieldstart,0]=str(0)
endif
// fill the string with the first content
for lines=1 to sy/scrollbox_size
line$=textfiles[textfieldstart,lines]
linestring$=linestring$+line$+chr(10)
next lines
// okay, this one will display the text as it is in one text file
// with every movement of the slider, this text will be replaced,
// but it will now only update the visible part
text=createtext(linestring$)
settextdepth(text,spritedepth)
settextsize(text,textsize)
settextposition(text,px,py)
settextcolor(text,0,0,255,255)
SetTextScissor(text,px,py,px+sx,py+sy)
// text cursor
cursor=createsprite(i3)
setspritedepth(cursor,spritedepth)
setspriteposition(cursor,px,py)
setspritesize(cursor,2,textsize)
// if scrollboxes is 1 then show the vertical scrollbox
if scrollboxes>0
si2=img_create_RGBA(2,2,0,0,255,255) // sliderbg
si3=img_create_RGBA(2,2,100,100,100,255) // slider
si6=img_create_RGBA(2,2,255,255,0,255) // scroll up
si7=img_create_RGBA(2,2,255,255,0,255) // scroll down
remstart
si2=loadimage("textures/slider.png")
si3=loadimage("textures/sliderbg.png")
si6=loadimage("textures/sl_u.png")
si7=loadimage("textures/sl_d.png")
remend
// vertical buttons
// up
v_sb_up=createsprite(si6)
setspritedepth(v_sb_up,spritedepth)
setspritesize(v_sb_up,scrollbox_size,scrollbox_size)
setspriteposition(v_sb_up,px+sx,py)
// down
v_sb_down=createsprite(si7)
setspritedepth(v_sb_down,spritedepth)
setspritesize(v_sb_down,scrollbox_size,scrollbox_size)
setspriteposition(v_sb_down,px+sx,py+sy-scrollbox_size)
// vertical slider
// ===============
// vertical slider background
v_sliderbg=createsprite(si3)
setspritedepth(v_sliderbg,spritedepth)
setspritesize(v_sliderbg,scrollbox_size,sy-scrollbox_size*2)
setspriteposition(v_sliderbg,px+sx,py+scrollbox_size)
// vertical slider
v_slider=createsprite(si2)
setspritedepth(v_slider,spritedepth)
setspritesize(v_slider,scrollbox_size,scrollbox_size*2)
setspriteposition(v_slider,px+sx,py+scrollbox_size)
endif
// if scrollboxes is 2 then show also the horizontal scrollbox
if scrollboxes=2
si4=img_create_RGBA(2,2,255,255,0,255) // scroll left
si5=img_create_RGBA(2,2,255,255,0,255) // scroll right
remstart
si4=loadimage("textures/sl_l.png")
si5=loadimage("textures/sl_r.png")
remend
rem si5=
// horizontal buttons
// left
h_sb_left=createsprite(si4)
setspritedepth(h_sb_left,spritedepth)
setspritesize(h_sb_left,scrollbox_size,scrollbox_size)
setspriteposition(h_sb_left,px,py+sy)
// right
h_sb_right=createsprite(si5)
setspritedepth(h_sb_right,spritedepth)
setspritesize(h_sb_right,scrollbox_size,scrollbox_size)
setspriteposition(h_sb_right,px+sx-scrollbox_size,py+sy)
// horizontal slider
// ===============
// horizontal slider background
h_sliderbg=createsprite(si3)
setspritedepth(h_sliderbg,spritedepth)
setspritesize(h_sliderbg,sx-scrollbox_size*2,scrollbox_size)
setspriteposition(h_sliderbg,px+scrollbox_size,py+sy)
// horizontal slider
h_slider=createsprite(si2)
setspritedepth(h_slider,spritedepth)
setspritesize(h_slider,scrollbox_size*2,scrollbox_size)
setspriteposition(h_slider,px+scrollbox_size,py+sy)
// the small filler between the scrollboxes (can also be replaced by an icon or something)
// the image is the same as the scrollbox bg
filler=createsprite(si3)
setspritedepth(filler,spritedepth)
setspritesize(filler,scrollbox_size,scrollbox_size)
setspriteposition(filler,px+sx,py+sy)
endif
// set the array informations
// ==========================
textfields[textfieldstart].sx=sx
textfields[textfieldstart].sy=sy
textfields[textfieldstart].px=px
textfields[textfieldstart].py=py
textfields[textfieldstart].textsize=textsize
textfields[textfieldstart].scrollbox_size=scrollbox_size
textfields[textfieldstart].bgs1=bgs1
textfields[textfieldstart].bgs2=bgs2
textfields[textfieldstart].cursor=cursor
textfields[textfieldstart].text=text
textfields[textfieldstart].sb1=h_sb_left
textfields[textfieldstart].sb2=h_sb_right
textfields[textfieldstart].sb3=v_sb_up
textfields[textfieldstart].sb4=v_sb_down
textfields[textfieldstart].sbs0=filler
textfields[textfieldstart].sbs1=h_slider
textfields[textfieldstart].sbs2=v_slider
textfields[textfieldstart].sbs3=h_sliderbg
textfields[textfieldstart].sbs4=v_sliderbg
textfields[textfieldstart].maxwidth=max_text_chars(textfieldstart) // this has to be overworked
textfields[textfieldstart].maxheight=max_lines-1
textfields[textfieldstart].curx=0
textfields[textfieldstart].cury=0
// update_text(textfieldstart,fullstring$) // this has to be overworked
endfunction
function reset_textfield(num,px,py,sx,sy,textsize,scrollboxes,scrollbox_size)
bgs1=textfields[num].bgs1
setspriteposition(bgs1,px-2,py-2)
setspritesize(bgs1,sx+6,sy+6)
bgs2=textfields[num].bgs2
setspriteposition(bgs2,px,py)
setspritesize(bgs2,sx,sy)
remstart
text=textfields[num].text
settextsize(text,textsize)
settextposition(text,px,py)
SetTextScissor( text,px,py,px+sx,py+sy )
remend
cursor=textfields[num].cursor
setspriteposition(cursor,px,py)
setspritesize(cursor,2,textsize)
if scrollboxes=1
h_sb_left=textfields[num].sb1
setspritesize(h_sb_left,scrollbox_size,scrollbox_size)
setspriteposition(h_sb_left,px,py+sy)
h_sb_right=textfields[num].sb2
setspritesize(h_sb_right,scrollbox_size,scrollbox_size)
setspriteposition(h_sb_right,px+sx-scrollbox_size,py+sy)
v_sb_up=textfields[num].sb3
setspritesize(v_sb_up,scrollbox_size,scrollbox_size)
setspriteposition(v_sb_up,px+sx,py)
v_sb_down=textfields[num].sb4
setspritesize(v_sb_down,scrollbox_size,scrollbox_size)
setspriteposition(v_sb_down,px+sx,py+sy-scrollbox_size)
h_slider=textfields[num].sbs1
h_sliderbg=textfields[num].sbs3
v_sliderbg=textfields[num].sbs4
v_slider=textfields[num].sbs2
sxv#=GetValue(h_sliderbg,h_slider,1)
syv#=GetValue(v_sliderbg,v_slider,2)
setspritesize(h_sliderbg,sx-scrollbox_size*2,scrollbox_size)
setspriteposition(h_sliderbg,px+scrollbox_size,py+sy)
setspritesize(h_slider,scrollbox_size*2,scrollbox_size)
setspriteposition(h_slider,px+scrollbox_size,py+sy)
setspritesize(v_sliderbg,scrollbox_size,sy-scrollbox_size*2)
setspriteposition(v_sliderbg,px+sx,py+scrollbox_size)
setspritesize(v_slider,scrollbox_size,scrollbox_size*2)
setspriteposition(v_slider,px+sx,py+scrollbox_size)
filler=textfields[num].sbs0
setspritesize(filler,scrollbox_size,scrollbox_size)
setspriteposition(filler,px+sx,py+sy)
endif
textfields[num].sx=sx
textfields[num].sy=sy
textfields[num].px=px
textfields[num].py=py
textfields[num].textsize=textsize
textfields[num].scrollbox_size=scrollbox_size
SetValue(num,sxv#,1)
SetValue(num,syv#,2)
rem update_textfield(num)
endfunction
// control textfields
// this routine will control all active textfields. There can only be
// one active textfield at a time
function control_textfields()
// select all textfields to be able to handle all
for i=1 to textfieldstart
// handle only the active textfield
// because of the input, there can always be only one active textfield
if textfields[i].active=1
// input controls for windows, or extended android keyboard
// backspace key
// =============
If GetRawKeyreleased ( 8 )
if textfields[i].cury>0
lasttchar=last_text_char(i,textfields[i].cury)
endif
// this will look if an textarea is been marked, if so, then delete
// the whole marked area
if textfields[i].selst1>0 and textfields[i].selst2>0
// selst1 and selst2 will not work with arrays, I have to replace
// this system and use a better one for performance reasons
remstart
delete_text(i,textfields[i].selst2-textfields[i].selst1)
set_pointer_textpos(i,textfields[i].selst1)
textfields[i].selst1=0
textfields[i].selst2=0
update_text(i,textfields[i].fulltext$)
remend
else
delete_text(i,1) // this will delete the char after the cursor
// reposition the cursor
textfields[i].curx=textfields[i].curx-1
if textfields[i].curx<0 // if the x pos is negative, delete a line
textfields[i].cury=textfields[i].cury-1
if textfields[i].cury<0
textfields[i].cury=0
textfields[i].curx=0
else
textfields[i].curx=last_text_char(i,textfields[i].cury)
endif
rem lasttchar=last_text_char(i,textfields[i].cury)
rem textfields[i].curx=lasttchar-1
endif
if textfields[i].cury<0 then textfields[i].cury=0 // if cury<0 then set it to 0
endif
EndIf
// delete key
// =============
If GetRawKeyReleased ( 46 )
delete_text(i,0) // this will delete the char, after the cursor
EndIf
// return key
// =============
If GetRawKeyReleased ( 13 )
add_text_line(i) // add a new line to the text
textfields[i].curx=0 // curx=0
textfields[i].cury=textfields[i].cury+1 // jump to the next line
EndIf
// reposition the cursor
// Left key
// =============
If GetRawKeyReleased ( 37 )
textfields[i].curx=textfields[i].curx-1
rem if textfields[i].curx<0 then textfields[i].curx=0
EndIf
// Up key
// =============
If GetRawKeyReleased ( 38 )
textfields[i].cury=textfields[i].cury-1
lasttchar=last_text_char(i,textfields[i].cury)
if textfields[i].cury<0 then textfields[i].cury=0
// if you go up with the cursor and there is no written text, set
// the cursor to the last line char position
if textfields[i].curx>lasttchar
textfields[i].curx=lasttchar
endif
EndIf
// Right key
// =============
If GetRawKeyReleased( 39 )
textfields[i].curx=textfields[i].curx+1
lasttchar=last_text_char(i,textfields[i].cury)
// if we are at the end of a line, move the cursor to the next line
if textfields[i].curx>lasttchar
textfields[i].cury=textfields[i].cury+1
lasttchar=last_text_char(i,textfields[i].cury)
textfields[i].curx=0
endif
EndIf
// Down key
// =============
If GetRawKeyReleased ( 40 )
textfields[i].cury=textfields[i].cury+1
lasttchar=last_text_char(i,textfields[i].cury)
// equaly the same as the upkey, repos to last line char
if textfields[i].curx>lasttchar
textfields[i].curx=lasttchar
endif
EndIf
// check the cursor limits
// minimum
if textfields[i].curx<0 // x position
textfields[i].cury=textfields[i].cury-1
if textfields[i].cury<0
textfields[i].cury=0
textfields[i].curx=0
else
textfields[i].curx=last_text_char(i,textfields[i].cury)
endif
endif
if textfields[i].cury<0 then textfields[i].cury=0 // y position
// maximum
if textfields[i].curx>textfields[i].maxwidth then textfields[i].curx=textfields[i].maxwidth
if textfields[i].cury>textfields[i].maxheight then textfields[i].cury=textfields[i].maxheight
endif // active=1
next i
endfunction
// handle textfields
// this function is designed to handle all the textfields
// basically all aspects of the textbox will be managed in here
function handle_textfields()
for i=1 to textfieldstart
// handle the select text feature
remstart
if textfields[i].setlt>0 // setlt is the double click select feature
textfields[i].setlt=textfields[i].setlt-1
endif
if textfields[i].setlt=-1 // setlt will be set to -1 if doubleclick occurs
if getpointerreleased()=1 // check for last select point
textfields[i].setlt=0
mpx#=getpointerx()
mpy#=getpointery()
cx=val(str((textfields[i].px-mpx#)/-textfields[i].textsize/0.625)) // recalculate the right cursor x position
cy=val(str((textfields[i].py-mpy#)/-textfields[i].textsize)) // recalculate the right cursor y position
ox=textfields[i].tcoordx // tcoordx will be influenced by the horizontal scrollbox
oy=textfields[i].tcoordy // tcoordx will be influenced by the vertical scrollbox
textfields[i].curx=(cx-ox/textfields[i].textsize/0.625)+1 // also add the offset due to the screenposition
textfields[i].cury=cy-oy/textfields[i].textsize // also add the offset due to the screenposition
endif
endif
remend
// select text feature end
if getpointerpressed()=1 // the main pointer input
if getspritehit(getpointerx(),getpointery())=textfields[i].bgs2
if textfields[i].setlt=0
textfields[i].setlt=30
textfields[i].selst1=0
textfields[i].selst2=0
// update_text(i,textfields[i].fulltext$)
else
textfields[i].setlt=-1
// textfields[i].selst1=text_charpos(textfields[i].fulltext$,textfields[i].curx,textfields[i].cury)
endif
// deactivate all other textfields
for x=1 to textfieldstart
textfields[x].active=0
next x
textfields[i].active=1 // set current textfield active
mpx#=getpointerx()
mpy#=getpointery()
cx=val(str((textfields[i].px-mpx#)/-textfields[i].textsize/0.625)) // recalculate the right cursor x position
cy=val(str((textfields[i].py-mpy#)/-textfields[i].textsize)) // recalculate the right cursor y position
ox=textfields[i].tcoordx // tcoordx will be influenced by the horizontal scrollbox
oy=textfields[i].tcoordy // tcoordy will be influenced by the vertical scrollbox
textfields[i].curx=cx-ox/textfields[i].textsize/0.625 // also add the offset due to the screenposition
textfields[i].cury=cy-oy/textfields[i].textsize // also add the offset due to the screenposition
// if the limit is greater, set the cursor to last char of the line
lastchar=last_text_char(i,textfields[i].cury)
if textfields[i].curx>lastchar
textfields[i].curx=lastchar
endif
else
if getspritehit(getpointerx(),getpointery())=0 // if no textfield is selected
setEditBoxFocus(1,0)
if Device$="android"
set_textfield_writemode(1,0)
endif
textfields[i].active=0
endif
endif // end spritehit
endif // end pointerpressed
// textfield management
if textfields[i].active=0 // if the textfield is not active, disable the cursor blinking and set them on
setspritevisible(textfields[i].cursor,1)
endif
// if the textfield is active
if textfields[i].active=1
ox=textfields[i].tcoordx
oy=textfields[i].tcoordy
if geteditboxhasfocus(1)=0
if Device$="android"
set_textfield_writemode(1,1)
endif
setEditBoxFocus(1,1)
SetEditBoxText(1,"")
endif
text$ = GetEditBoxText(1)
if text$<>""
add_text(i,text$) // add the text to the file
textfields[i].curx=textfields[i].curx+1
SetEditBoxText(1,"")
endif
// char replacement get every input and set them to the right char
for x=1 to 255
if char_replacements[x]>0
if GetAnyKey()=x
text$=get_char_rep(x)
add_text(i,text$)
textfields[i].curx=textfields[i].curx+1
endif
endif
next x
// cursor
// update cursor position
setspriteposition(textfields[i].cursor,textfields[i].px+textfields[i].curx*textfields[i].textsize*0.625+ox,textfields[i].py+textfields[i].cury*textfields[i].textsize+oy)
// update cursor blinking
textfields[i].curblink=textfields[i].curblink+1
if textfields[i].curblink>20 then textfields[i].curblink=0
if textfields[i].curblink<10
setspritevisible(textfields[i].cursor,1)
else
setspritevisible(textfields[i].cursor,0)
endif
rem if we have the slidebar
if getpointerpressed()=1
// horizontal
if textfields[i].sb1>0
if getspritehit(getpointerx(),getpointery())=textfields[i].sb1
sprPush=textfields[i].sbs1
sprSL=textfields[i].sbs3
SetValue(i,GetValue(sprPush,sprSL,1)-0.1*0.625,1)
endif
if getspritehit(getpointerx(),getpointery())=textfields[i].sb2
sprPush=textfields[i].sbs1
sprSL=textfields[i].sbs3
SetValue(i,GetValue(sprPush,sprSL,1)+0.1*0.625,1)
endif
endif
// vertical
if textfields[i].sb3>0
if getspritehit(getpointerx(),getpointery())=textfields[i].sb3
sprPush=textfields[i].sbs2
sprSL=textfields[i].sbs4
SetValue(i,GetValue(sprPush,sprSL,2)-0.1,2)
endif
if getspritehit(getpointerx(),getpointery())=textfields[i].sb4
sprPush=textfields[i].sbs2
sprSL=textfields[i].sbs4
SetValue(i,GetValue(sprPush,sprSL,2)+0.1,2)
endif
endif
endif
endif
update_scrollbars(i)
next i
endfunction
// update scrollbars
// this function will manage all the scrollbars
function update_scrollbars(num)
if textfields[num].sbs1>0
sprPush=textfields[num].sbs1
sprSL=textfields[num].sbs3
mx#=getpointerx()
my#=getpointery()
spr=getspritehit(mx#,my#)
if getpointerstate()=1
if spr=sprPush or spr=sprSL
x#=mx#
if x#<getspritex(sprSL)+getspritewidth(sprPush)/2.0 then x#=getspritex(sprSL)+getspritewidth(sprPush)/2.0
if x#>getspritex(sprSL)+getspritewidth(sprSL)-getspritewidth(sprPush)/2.0 then x#=getspritex(sprSL)+getspritewidth(sprSL)-getspritewidth(sprPush)/2.0
setspritepositionbyoffset(sprPush,x#,getspriteybyoffset(sprPush))
endif
endif
textfields[num].t_curx#=GetValue(sprSL,sprPush,1)
endif
if textfields[num].sbs2>0
sprPush=textfields[num].sbs2
sprSL=textfields[num].sbs4
mx#=getpointerx()
my#=getpointery()
spr=getspritehit(mx#,my#)
if getpointerstate()=1
if spr=sprPush or spr=sprSL
y#=my#
if y#<getspritey(sprSL)+getspriteheight(sprPush)/2.0 then y#=getspritey(sprSL)+getspriteheight(sprPush)/2.0
if y#>getspritey(sprSL)+getspriteheight(sprSL)-getspriteheight(sprPush)/2.0 then y#=getspritey(sprSL)+getspriteheight(sprSL)-getspriteheight(sprPush)/2.0
setspritepositionbyoffset(sprPush,getspritexbyoffset(sprPush),y#)
endif
endif
textfields[num].t_cury#=GetValue(sprSL,sprPush,2)
textfields[num].tcoordx=val(str(textfields[num].t_curx#*(textfields[num].maxwidth-(textfields[num].sx/textfields[num].textsize))))*-textfields[num].textsize
textfields[num].tcoordy=val(str(textfields[num].t_cury#*(textfields[num].maxheight+1-(textfields[num].sy/textfields[num].textsize))))*-textfields[num].textsize
if textfields[num].tcoordy>0 then textfields[num].tcoordy=0
if textfields[num].tcoordx>0 then textfields[num].tcoordx=0
update_textfield(num)
endif
endfunction
// update text
// this command will add the syntax highlight
function update_text(num)
text$=gettextstring(textfields[num].text)
// first, the main text body color
// the entry with no string is the main text color
for char=1 to len(text$)
for i=1 to syntax_highlightstart
r=syntax_hightlight[i].r
g=syntax_hightlight[i].g
b=syntax_hightlight[i].b
if syntax_hightlight[i].keyword$=""
settextcharcolor(textfields[num].text,char-1,r,g,b,255)
endif
next i
next char
// all single attributes
for char=1 to len(text$)
for i=1 to syntax_highlightstart // mark all highlight words
if mid(text$,char,len(syntax_hightlight[i].keyword$))=syntax_hightlight[i].keyword$
r=syntax_hightlight[i].r
g=syntax_hightlight[i].g
b=syntax_hightlight[i].b
if syntax_hightlight[i].follow=0
for length=1 to len(syntax_hightlight[i].keyword$)
settextcharcolor(textfields[num].text,char-1+length-1,r,g,b,255)
next length
else
rem settextcharcolor(textfields[num].text,char-1,r,g,b,255)
endif
endif
next i
next char
// all following attributes like remtext
for char=1 to len(text$)
for i=1 to syntax_highlightstart // mark all highlight words
if syntax_hightlight[i].follow=1
if syntax_hightlight[i].keyword$<>""
if mid(text$,char,len(syntax_hightlight[i].keyword$))=syntax_hightlight[i].keyword$
r=syntax_hightlight[i].r
g=syntax_hightlight[i].g
b=syntax_hightlight[i].b
// find the new next line
nt$=right(text$,len(text$)-char)
for t=1 to len(nt$)
if mid(nt$,t,1)=chr(10)
maxl=t
exit
endif
next t
for length=1 to maxl
settextcharcolor(textfields[num].text,char-1+length-1,r,g,b,255)
next length
endif
endif
endif
next i
next char
endfunction
// update textfield
// this command is in control of the displayed text
// if a change occur and this function is called, the
// text will be repositioned
function update_textfield(num)
text=textfields[num].text
ox=textfields[num].tcoordx // x offset (yoffset is not nesserary due to redraw)
sx=textfields[num].sx
sy=textfields[num].sy
px=textfields[num].px
py=textfields[num].py
maxheight=textfields[num].maxheight
scrollbox_size=textfields[num].scrollbox_size
textoffset=-textfields[num].tcoordy/textfields[num].textsize
lc=0
// get the current linestring
for lines=1+textoffset to (sy/scrollbox_size)+textoffset
inc lc
line$=""
line$=textfiles[num,lines]
linestring$=linestring$+line$+chr(10)
if lc=maxheight+1 then exit
next lines
// update text
settextstring(text,linestring$)
settextposition(text,px+ox,py)
// update cursor
SetSpriteScissor( textfields[num].cursor,px,py,px+sx,py+sy )
update_text(num)
endfunction
// writemode. This function can redraw the textfield on android systems
// The main purpose of this function is to resize the textfield when the
// input keyboard appears. The textbox should be scaled down at about 50%
// to be able to see the horizontal scrollbox.
// this function is currently not available
// I will add this once the textarray is complete
function set_textfield_writemode(num,flag)
remstart
if flag=1
reset_textfield(1,0,40,1280-40-0,720-400,40,1,40)
else
reset_textfield(1,0,40,1280-40-0,720+20-100,40,1,40)
endif
remend
endfunction
// last text char
// this command will return the len (maxium amout of chars) of the input line (y)
function last_text_char(num,y)
if y<0 then y=0
maxi=len(textfiles[num,y+1])
endfunction maxi
function delete_text(num,amount)
x=textfields[num].curx
y=textfields[num].cury
maxline=last_text_char(num,y)
line$=textfiles[num,y+1]
if textfields[num].maxwidth>0
// this is like deletekey
if amount=0
// if we are in the text
if x<maxline
first$=left(line$,x)
last$=right(line$,len(line$)-x-1)
full$=first$+last$
textfiles[num,y+1]=full$
else
if x>0
if x=maxline and y<val(textfiles[num,0])
textfields[num].cury=textfields[num].cury+1
tl$=textfiles[num,y+2]
delete_text_line(num)
textfields[num].cury=textfields[num].cury-1
add_text(num,tl$)
endif
endif
endif
if x<1 and maxline=0
delete_text_line(num)
endif
endif
// this is like backspace
if amount=1
if x>0
first$=left(line$,x-1)
last$=right(line$,len(line$)-x)
full$=first$+last$
textfiles[num,y+1]=full$
else
if y<>0
tl$=textfiles[num,y+1]
textfields[num].cury=textfields[num].cury-1
textfields[num].curx=last_text_char(num,textfields[num].cury)
add_text(num,tl$)
textfields[num].cury=textfields[num].cury+1
delete_text_line(num)
textfields[num].cury=textfields[num].cury-1
textfields[num].curx=textfields[num].curx+1
endif
endif
endif
endif
textfields[num].maxwidth=max_text_chars(num)
endfunction
// this function should move all following entrys one slot at the bottom
function add_text_line(num)
y=textfields[num].cury
x=textfields[num].curx
maxline=last_text_char(num,y)
if x=0
for i=val(textfiles[num,0])+2 to (y+1) step -1
if i=y+1
textfiles[num,i]=""
else
textfiles[num,i]=textfiles[num,i-1]
endif
next i
else
if x=maxline
// add a new line at the end
for i=val(textfiles[num,0])+2 to (y+2) step -1
if i=y+2
textfiles[num,i]=""
else
textfiles[num,i]=textfiles[num,i-1]
endif
next i
else
// this is to cut a line and add the last part to the next line
line$=textfiles[num,y+1]
first$=left(line$,x)
last$=right(line$,len(line$)-x)
for i=val(textfiles[num,0])+2 to (y+2) step -1
if i=y+2
textfiles[num,i]=""
else
textfiles[num,i]=textfiles[num,i-1]
endif
next i
textfiles[num,y+1]=first$
textfiles[num,y+2]=last$
endif
endif
textfiles[num,0]=str(val(textfiles[num,0])+1)
textfields[num].maxheight=textfields[num].maxheight+1
endfunction
// this function should move all following entrys one slot at the top
function delete_text_line(num)
y=textfields[num].cury
for i=y+1 to val(textfiles[num,0])+2
rem textfiles[num,val(textfiles[num,0])-i]=""
textfiles[num,i]=textfiles[num,i+1]
next i
textfiles[num,0]=str(val(textfiles[num,0])-1)
textfields[num].maxheight=textfields[num].maxheight-1
endfunction
// add text function
// this function will add text to the current line
function add_text(num,middle$)
x=textfields[num].curx
y=textfields[num].cury
line$=textfiles[num,y+1]
first$=left(line$,x)
last$=right(line$,len(line$)-x)
full$=first$+middle$+last$
textfiles[num,y+1]=full$
textfields[num].maxwidth=max_text_chars(num) // this has to be overworked
rem textfields[num].maxheight=max_lines
endfunction
// save array function
function save_text(num,name$)
setfolder("/media")
file=opentowrite(name$)
for i=1 to val(textfiles[num,0])
writeline(file,textfiles[num,i])
next i
closefile(file)
endfunction
// max file lines
// this function will get the last line if the textfile
function max_file_lines(file$,maxc)
file= opentoread(file$)
for i=1 to maxc
line$=readline(file)
if line$<>""
inc count
count=count+tempcount
tempcount=0
else
inc tempcount
endif
next i
closefile(file)
endfunction count
// max_text_chars
function max_text_chars(num)
for i=1 to val(textfiles[num,0])+1
length=len(textfiles[num,i])
if length>maxlength
maxlength=length
endif
next i
endfunction maxlength
// those are already good to go for array text
// create a rgb image from memblock
function img_create_RGBA(www,hhh, klr_r,klr_g,klr_b, klr_a)
`creates an image of 'www' by 'hhh' pixels with defined color
size = 12 +www *hhh *4 `memblock 'size' is summary of image width (integer, 4 bytes), image height (integer, 4 bytes), image depth (integer, 4 bytes) - that is 12 bytes - and raw image data (the number of pixels multiplied by 4 bytes)
mmm = createMemblock(size)
setMemblockInt(mmm, 0, www) `writing starts with offset 0
setMemblockInt(mmm, 4, hhh) `variable 'www' occupies 4 bytes, so now offset 0 +4 = 4
setMemblockInt(mmm, 8, 32) `variable 'hhh' occupies 4 bytes, so now offset 4 +4 = 8
dec size `since writing starts with offset 0, it ends at one stage earlier than the memblock 'size'
for nnn = 12 to size
setMemblockByte(mmm, nnn, klr_r)
inc nnn
setMemblockByte(mmm, nnn, klr_g)
inc nnn
setMemblockByte(mmm, nnn, klr_b)
inc nnn
setMemblockByte(mmm, nnn, klr_a)
next nnn
nnn = createImageFromMemblock(mmm)
deleteMemblock(mmm)
endfunction nnn
// slider response commands
function GetValue(sprSL,sprPush,axis)
if axis=1
x#=(getspritexbyoffset(sprPush)-getspritewidth(sprPush)/2.0)-getspritex(sprSL)
w#=getspritewidth(sprSL)-getspritewidth(sprPush)*1.0
v#=x#/w#
else
y#=(getspriteybyoffset(sprPush)-getspriteheight(sprPush)/2.0)-getspritey(sprSL)
w#=getspriteheight(sprSL)-getspriteheight(sprPush)*1.0
v#=y#/w#
endif
endfunction v#
function SetValue(num,v#,axis)
if axis=1
sprPush=textfields[num].sbs1
sprSL=textfields[num].sbs3
x#=getspritex(sprSL)+(getspritewidth(sprSL)-getspritewidth(sprPush)/2.0)*v#
if x#<getspritex(sprSL)+getspritewidth(sprPush)/2.0 then x#=getspritex(sprSL)+getspritewidth(sprPush)/2.0
if x#>getspritex(sprSL)+getspritewidth(sprSL)-getspritewidth(sprPush)/2.0 then x#=getspritex(sprSL)+getspritewidth(sprSL)-getspritewidth(sprPush)/2.0
setspritepositionbyoffset(sprPush,x#,getspriteybyoffset(sprPush))
setspritepositionbyoffset(sprPush,x#,getspriteybyoffset(sprPush))
else
sprPush=textfields[num].sbs2
sprSL=textfields[num].sbs4
y#=getspritey(sprSL)+(getspriteheight(sprSL)-getspriteheight(sprPush)/2.0)*v#
if y#<getspritey(sprSL)+getspriteheight(sprPush)/2.0 then y#=getspritey(sprSL)+getspriteheight(sprPush)/2.0
if y#>getspritey(sprSL)+getspriteheight(sprSL)-getspriteheight(sprPush)/2.0 then y#=getspritey(sprSL)+getspriteheight(sprSL)-getspriteheight(sprPush)/2.0
setspritepositionbyoffset(sprPush,getspritexbyoffset(sprPush),y#)
endif
endfunction
// advanced input
function GetAnyKey()
// Declare local variables
v_Scancode as integer
v_Result as integer
// Initialize local variables
v_Result = 0 // 0 = Keypress has not been detected...
// Get last key pressed
v_Scancode = GetRawLastKey()
// If key has been released... Key DOWN + Key UP event has occurred.
if (GetRawKeyReleased(v_Scancode))
// Return this scancode!
v_Result = v_Scancode
endif
endfunction v_Result