'##############################################################################
'##############################################################################
'Begin StringGadget.bas

declare function AddStringGadget (event as EventHandle ptr,x as integer,y as integer,glen as integer,slen as integer,txt as string="",se as integer=0, st as integer=0, f as integer=0) as Gadget ptr

declare function StringGadgetHit(hitgad as Gadget ptr,junk as Gadget ptr) as integer
declare function StringGadgetHold(hitgad as Gadget ptr,holdgad as Gadget ptr) as integer
declare function StringGadgetRelease(hitgad as Gadget ptr,relgad as Gadget ptr) as integer
declare function EditString(gad as Gadget ptr) as integer
declare function FindDot(s as string) as integer

declare function GetString (gad as Gadget ptr) as string
declare sub SetString (gad as Gadget ptr,txt as string)
declare sub HoldFocus (gad as Gadget ptr)
declare sub DrawStringGadget (gad as Gadget ptr)

'Steuerungsvariablen:
'Ca maximale Anzahl der darzustellenden Zeichen
'Cb maximale Stringlänge
'Cc Cursorposition
'Cd Offset für die Darstellung beim Scrollen,wenn String länger als Gadget(Ca) ist
'Ce immer zum Ende scrollen
'Cf Eingabetyp: 0=String,1=integer,2=Fließkomma,binär,hexadezimal
'Ch Focus Hold nach Return soll Control weiter aktiv bleiben
function AddStringGadget (event as EventHandle ptr,x as integer,y as integer,glen as integer,slen as integer,txt as string="",se as integer=0, st as integer=0, f as integer=0) as Gadget ptr
  if len(txt)>slen then txt=left(txt,slen)
  dim as Gadget ptr tmpgad,firstgad,lastgad
  function=0
  tmpgad=new Gadget
  if tmpgad then
    tmpgad->nextGadget=0
    tmpgad->sel=0
    tmpgad->act=0
    tmpgad->posx=x
    tmpgad->posy=y
    tmpgad->gadw=(glen)*8+6
    tmpgad->gadh=GetFontHeight+6
    tmpgad->text=txt

    tmpgad->event=event

    tmpgad->DoDraw     =@DrawStringGadget
    tmpgad->DoHit      =@StringGadgetHit
    tmpgad->DoHold     =@StringGadgetHold
    tmpgad->DoRelease  =@StringGadgetRelease
    tmpgad->DoKeyStream=@EditString

    tmpgad->Ca=glen
    tmpgad->Cb=slen

    if se=1 and len(txt) >= tmpgad->Ca then
      tmpgad->Cc=len(txt) + 1
      tmpgad->Cd=len(txt) - tmpgad->Ca + 1
    else
      tmpgad->Cc=1
      tmpgad->Cd=0
    end if
    
    if f then tmpgad->Ch=1 'HoldFocus einschalten

    tmpgad->Ce=se
    tmpgad->Cf=st

		SaveBackGround(tmpgad)
    event->ChainGadget (tmpgad)
    function=tmpgad
  end if
end function



function StringGadgetHit(hitgad as Gadget ptr,junk as Gadget ptr) as integer
  'uff... lange nicht mehr gelesen diesen Code :)
  'wenn ich mich recht erinnere, ist das StringGadget Maus-sensitiv
  'soll heissen beim Klicken mitten in den String wird der Cursor auch dort positioniert
	'und das soll wohl folgendes Konstrukt bewerkstelligen:
	hitgad->Cc=hitgad->Cd+((hitgad->event->MOUSEX)-hitgad->posx-3)\8+1
  if hitgad->Cc >hitgad->Cd+hitgad->Ca then _
    hitgad->Cc=hitgad->Cd+hitgad->Ca
  if hitgad->Cc > len(hitgad->text)+1 then _
    hitgad->Cc=len(hitgad->text)+1
  SetSelect (hitgad,1)
  function=-2  'statt 0 liefern wir -2 - GadgetControl erkennt daran ein Control das nen "Keystream" empfängt
end function



function StringGadgetHold(hitgad as Gadget ptr,holdgad as Gadget ptr) as integer
  function=0
end function



function StringGadgetRelease(hitgad as Gadget ptr,relgad as Gadget ptr) as integer
	function=0
  if hitgad=0 then
 
    if relgad->Ce=1 and len(relgad->text) >= relgad->Ca then
      relgad->Cc=len(relgad->text) + 1
      relgad->Cd=len(relgad->text) - relgad->Ca + 1
    else
      relgad->Cc=1
      relgad->Cd=0
    end if

    SetSelect (relgad,0)
    function=-1
  end if
end function



function EditString(gad as Gadget ptr) as integer
  function=0
  'da ein aktiviertes StringGadget (keystreamto - Record im Handle UTD) selbst dann die Tastatureingaben empfängt,
  'wenn das Gadget Sleep oder Off ist... und das n i c h t so sein sollte
  'kommt jetzt folgende Zeile ;)
  if gad->act<>1 then exit function

  dim as string lpart,rpart
  dim as integer scan,ascii,ext,enable
  ext=gad->event->EXTENDED
  ascii=gad->event->ASCCODE
  
  enable=0 'Zeichen hinzufügen

  if ext=0 and ascii=-1 then exit function

  if ascii<>13 then

'Cursorsteuerung mit Pfeiltasten***********************************************

    if ext then                                                   'wenn Erweiterungsbyte gesetzt
      if ascii=75 and gad->Cc > 1 then gad->Cc -=1                'scrolle nach links
      if ascii=77 and gad->Cc < len(gad->text)+1 then gad->Cc +=1 'scrolle nach rechts
    end if

'Backspace*********************************************************************

    if gad->Cc>1 then                                     'wenn Cursor grösser 1 dann können wir "backspacen"
      if ascii=8 then
        if gad->Cc=len(gad->text)+1 then                  'wenn Cursor hinterm Text
          gad->text=left(gad->text,len(gad->text)-1)		  'dann letztes Zeichen weg
        elseif gad->Cc=2 then                             'wenn Cursor an 2.Stelle
          gad->text=right(gad->text,len(gad->text)-1)     'dann erstes Zeichen Weg
        else                                              'wenn Cursor mittendrin
          lpart=left(gad->text,gad->Cc-2)                 'String splitten Zeichen vor Cursor weg
          rpart=right(gad->text,len(gad->text)-gad->Cc+1)
          gad->text=lpart+rpart                           'und wieder zusammenpappen
        end if
        if gad->Cd>0 then gad->Cd -=1                     'ScrollOffset verändern
        gad->Cc -=1                                       'Cusorposition verringern
      end if
    end if

'Delete************************************************************************
    
      'Linux chr(127)
      #ifdef __fb_linux__
        if gad->Cc<=len(gad->text) then                       'wenn Cursor im Text und nicht dahinter
          if ext=0 and ascii=127 then                         'wenn Erweiterungsbyte gesetzt
            if gad->Cc=len(gad->text) then                    'wenn Cursor auf letzem Zeichen
              gad->text=left(gad->text,len(gad->text)-1)      'letztes Zeichen weg
            elseif gad->Cc=1 then                             'wenn Cursor auf erstem Zeichen
              gad->text=right(gad->text,len(gad->text)-1)     'erstes Zeichen weg
            else                                              'ansonsten (wenn) Cursor mittendrin
              lpart=left(gad->text,gad->Cc-1)                 'String splitten CursorZeichen weg
              rpart=right(gad->text,len(gad->text)-gad->Cc)
              gad->text=lpart+rpart                           'und wieder zusammenpappen
            end if                                            'Cursorposition bleibt erhalten!!!
          end if
        end if        
      #endif
    
      'Windows chr(83)   
      #ifdef __fb_win32__
        if gad->Cc<=len(gad->text) then                       'wenn Cursor im Text und nicht dahinter
          if ext<>0 and ascii=83 then                         'wenn Erweiterungsbyte n i c h t  gesetzt
            if gad->Cc=len(gad->text) then                    'wenn Cursor auf letzem Zeichen
              gad->text=left(gad->text,len(gad->text)-1)      'letztes Zeichen weg
            elseif gad->Cc=1 then                             'wenn Cursor auf erstem Zeichen
              gad->text=right(gad->text,len(gad->text)-1)     'erstes Zeichen weg
            else                                              'ansonsten (wenn) Cursor mittendrin
              lpart=left(gad->text,gad->Cc-1)                 'String splitten CursorZeichen weg
              rpart=right(gad->text,len(gad->text)-gad->Cc)
              gad->text=lpart+rpart                           'und wieder zusammenpappen
            end if                                            'Cursorposition bleibt erhalten!!!
          end if
        end if
      #endif


'Add Char**********************************************************************

    if len(gad->text)<gad->Cb and ext=0 then   'nur wenn String kürzer als Cb(max. Stringlänge) und Erweiterungsbyte nicht gesetzt
      
      'Zeichenbeschränkungen
      enable=0
      select case gad->Cf
        case 0'String
          
          'Linux chr(127) (Delete) ausschließen
          #ifdef __fb_linux__
            if ascii>=32 and ascii<>127 then enable=1
          #endif    
          
          'Windows    
          #ifdef __fb_win32__
            if ascii>=32 then enable=1
          #endif 
        
        case 1'Ganze Zahlen
          if ascii>47 and ascii<58 then enable=1
        
        case 2'Fließkomma
          if ascii>47 and ascii<58 then enable=1
          if ascii=46 and FindDot(gad->text)=0 then enable=1 'wenn Punkt gedrückt und noch kein Punkt im String ist
        
        case 3'binär
          if ascii>47 and ascii<50 then enable=1
          
        case 4'hexadezimal
          if ascii>47 and ascii<58 then enable=1
          if ascii>64 and ascii<71 then enable=1
          if ascii>96 and ascii<103 then enable=1
        
        case 5'IPAdressen  ;)
          if ascii>47 and ascii<58 then enable=1
          if ascii>64 and ascii<71 then enable=1
          if ascii>96 and ascii<103 then enable=1
          if ascii=46 then enable=1
      end select
      
      if enable then 'wenn Zeichen erlaubt dann hinzufügen
        if len(gad->text)>0 then                            'wenn kein Leerstring
          if gad->Cc=1 then                                 'wenn Cursor an erster Stelle
            gad->text=chr(ascii)+gad->text                  'Zeichen vorn einfügen
          elseif gad->Cc=len(gad->text)+1 then            	'wenn Cursor hinter Text
            gad->text=gad->text+chr(ascii)                  'Zeichen hinten anhängen
          else                                              'ansonsten (wenn) Cursor mittendrin
            lpart=left(gad->text,gad->Cc-1)                 'String splitten
            rpart=right(gad->text,len(gad->text)-gad->Cc+1)
            gad->text=lpart+chr(ascii)+rpart                'alle 3 Teile zusammenpappen
          end if
        else                                                'wenn Leerstring dann
          gad->text=chr(ascii)                              'erstes Zeichen setzen
        end if
        gad->Cc +=1                                         'Cursorposition erhöhen
      end if

    end if

'Scrolling(Display)************************************************************

    if gad->Cc<gad->Cd+1 then 'Offset Steuerung
      gad->Cd=gad->Cc-1
    end if
    if gad->Cc>gad->Cd+gad->Ca then
      gad->Cd=gad->Cc-gad->Ca
    end if

    gad->DoDraw(gad)
  else
    if gad->Ch then
      function=-2  'Focus halten
    else
      function=-1  'Focus verlieren
    end if
  end if
end function



function FindDot(s as string) as integer
  function=0
  if len(s)>0 then
    for i as integer=len(s) to 1 step -1
      if mid(s,i,1)="." then function=len(s)-i+1
    next i
  end if
end function



function GetString (gad as Gadget ptr) as string
  function=gad->text
end function



sub SetString (gad as Gadget ptr,txt as string)
  if len(txt)>gad->Cb then txt=left(txt,gad->Cb)

  if gad->Ce=1 and len(txt) >= gad->Ca then
    gad->Cc=len(txt) + 1
    gad->Cd=len(txt) - gad->Ca + 1
  else
    gad->Cc=1
    gad->Cd=0
  end if

  'gad->Cc=1
  'gad->Cd=0
  gad->text=txt
  DrawGadget (gad)
end sub



sub HoldFocus (gad as Gadget ptr)
  gad->Ch=1
end sub



sub DrawStringGadget (gad as Gadget ptr)
	dim as integer x,y,w,h,i,c,o,os
	dim as string char
  x   =gad->posx
	y   =gad->posy
	w		=gad->gadw
	h		=gad->gadh
  c   =gad->Cc
  o   =gad->Cd
  os  =3

  screenlock
  if gad->act=0 then put(x,y),gad->BackGroundImage,pset

  if gad->act=1 then
		if gad->sel=0 then
		  FrameB x,y,w,h,1
		  FrameA x+1,y+1,w-2,h-2,white
			FrameA x+2,y+2,w-4,h-4,white
			for i=1 to gad->Ca
        if i+o<=len(gad->text) then char=mid(gad->text,i+o,1) else char=" "
        line( x+os+8*(i-1),y+os)-(x+os+8*(i)-1,y+os+fontheight-1),white,bf
        draw string ( x+os+8*(i-1), y+os ),char,TextColor
      next i
    else
		  FrameB x,y,w,h,1
		  FrameD x+1,y+1,w-2,h-2,ShiftRGB(GadgetColor,contrast*1.5),1
			FrameA x+2,y+2,w-4,h-4,ShiftRGB(GadgetColor,contrast*2)
			for i=1 to gad->Ca
        if i+o<=len(gad->text) then char=mid(gad->text,i+o,1) else char=" "
        if i+o=c then
          line( x+os+8*(i-1),y+os)-(x+os+8*(i)-1,y+os+fontheight-1),CursorColor,bf
          draw string ( x+os+8*(i-1), y+os ),char,white
        else
          line( x+os+8*(i-1),y+os)-(x+os+8*(i)-1,y+os+fontheight-1),ShiftRGB(GadgetColor,contrast*2),bf
          draw string ( x+os+8*(i-1), y+os ),char,TextColor
        end if
      next i
    end if
  end if

  if gad->act=2 then
    FrameB x,y,w,h,1
    FrameA x+1,y+1,w-2,h-2,BackGroundColor
    FrameA x+2,y+2,w-4,h-4,BackGroundColor
    for i=1 to gad->Ca
      if i+o<=len(gad->text) then char=mid(gad->text,i+o,1) else char=" "
      line( x+os+8*(i-1),y+os)-(x+os+8*(i)-1,y+os+fontheight-1),BackGroundColor,bf
      draw string ( x+os+8*(i-1), y+os ),char,ShiftRGB(BackGroundColor,-contrast)
    next i
  end if
  screenunlock
end sub



'End StringGadget.bas
'##############################################################################
'##############################################################################
