Self-contained find dialog

BlitzMax Forums/BlitzMax GUI Programming/Self-contained find dialog

This code will enable a Windows Notepad-like Find dialog on any textarea gadget.

Usage:

Import "Find.bmx"
GADGET_MENU_FIND=CreateMenu("Find",0,menu)
CreateFindWindow(MainWindow:TGadget,TextArea:TGadget)

That's it!

Strict

Import brl.maxgui

Private

Global FindWindow:TGadget
Global GADGET_FIND_TEXT:TGadget
Global GADGET_FIND_OK:TGadget
Global GADGET_FIND_CANCEL:TGadget
Global GADGET_FIND_UP:TGadget
Global GADGET_FIND_DOWN:TGadget
Global GADGET_FIND_MATCHCASE:TGadget

Public

Global GADGET_MENU_FIND:TGadget
Global GADGET_FIND_TEXTAREA:TGadget

Function CreateFindWindow(group:TGadget,textarea:TGadget)
	Local panel:TGadget
	Local flags
	flags=WINDOW_TITLEBAR|WINDOW_HIDDEN'|WINDOW_CENTER|WINDOW_DIALOG
	FindWindow=CreateWindow("Find",200,200,360,133,group,flags)
	CreateLabel("Find what:",10,11,60,16,FindWindow)
	GADGET_FIND_TEXT=CreateTextField(71,11,192,20,FindWindow)
	GADGET_FIND_OK=CreateButton("Find Next",274-1,10,73+2,21+2,FindWindow,BUTTON_OK)
	GADGET_FIND_CANCEL=CreateButton("Cancel",274-1,33+2,73+2,21+2,FindWindow,BUTTON_CANCEL)
	GADGET_FIND_MATCHCASE=CreateButton("Match case",7,71,80,16,FindWindow,BUTTON_CHECKBOX)
	DisableGadget GADGET_FIND_OK
	panel=CreatePanel(160,48,102,44,FindWindow,PANEL_GROUP,"Direction")
	GADGET_FIND_UP=CreateButton("Up",5,7,35,16,panel,BUTTON_RADIO)
	GADGET_FIND_DOWN=CreateButton("Down",46,7,46,16,panel,BUTTON_RADIO)
	SetButtonState GADGET_FIND_DOWN,1
	GADGET_FIND_TEXTAREA=textarea
	AddHook EmitEventHook,FindWindowHook
EndFunction

Function ReverseString$(s$)
	Local n
	Local rs$
	For n=0 To s.length-1
		rs:+Chr(s[s.length-1-n])
	Next
	Return rs
EndFunction

Function FindWindowHook:Object(id:Int,data:Object,context:Object)
	Global LastActiveGadget:TGadget
	Local text$,p,searchstring$
	
	If data=Null Return Null
	Local event:TEvent=TEvent(data)
	Select event.id
		
		Case EVENT_GADGETACTION
			Select event.source
			
				Case GADGET_FIND_OK
					text=TextAreaText(GADGET_FIND_TEXTAREA)
					If Not ButtonState(GADGET_FIND_MATCHCASE) text=Lower(text)
					p=TextAreaCursor(GADGET_FIND_TEXTAREA)
					searchstring=TextFieldText(GADGET_FIND_TEXT)
					If Not ButtonState(GADGET_FIND_MATCHCASE) searchstring=Lower(searchstring)
					If ButtonState(GADGET_FIND_UP)
						text=ReverseString(text)
						searchstring=reversestring(searchstring)
						p=text.length-p
					EndIf
					p=text.find(searchstring,p+1)
					If p>-1
						If ButtonState(GADGET_FIND_UP)
							p=text.length-p
							p=p-searchstring.length
						EndIf
						SelectTextAreaText GADGET_FIND_TEXTAREA,p,searchstring.length
						ActivateGadget GADGET_FIND_OK
					Else
						Notify "Cannot find ~q"+TextFieldText(GADGET_FIND_TEXT)+"~q"
					EndIf
					
				Case GADGET_FIND_TEXT
					If TextFieldText(GADGET_FIND_TEXT)=""
						DisableGadget GADGET_FIND_OK
					Else
						EnableGadget GADGET_FIND_OK
					EndIf
					
				Case GADGET_FIND_CANCEL
					EmitEvent CreateEvent(EVENT_WINDOWCLOSE,FindWindow)
			
			EndSelect
		
		Case EVENT_MENUACTION
			Select event.source
				Case GADGET_MENU_FIND
					LastActiveGadget=ActiveGadget()
					ShowGadget FindWindow
					ActivateGadget GADGET_FIND_OK
					ActivateGadget GADGET_FIND_TEXT
					
			EndSelect

		Case EVENT_WINDOWCLOSE
			Select event.source
				
				Case FindWindow
					If LastActiveGadget
						ActivateGadget LastActiveGadget
					Else
						ActivateGadget GadgetGroup(FindWindow)
					EndIf
					HideGadget FindWindow
					
			EndSelect
	EndSelect
	Return data
EndFunction