Self-contained find dialog

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

This is an updated version that will search up & down. I also added a GADGET_MENU_FINDNEXT menu item. Just create it and the application will handle everything, including enabling and disabling the menu. You should disable the GADGET_MENU_FINDNEXT menu item when it is created.

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_MENU_FINDNEXT: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

Private

Function Find()
	Local text$,p,searchstring$
	text=TextAreaText(GADGET_FIND_TEXTAREA)
	If text="" Return
	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
	Else
		Notify "Cannot find ~q"+TextFieldText(GADGET_FIND_TEXT)+"~q"
	EndIf
	
	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
	
EndFunction

Function FindWindowHook:Object(id:Int,data:Object,context:Object)
	Global LastActiveGadget:TGadget
	If data=Null Return Null
	Local event:TEvent=TEvent(data)
	Select event.id
		
		Case EVENT_GADGETACTION
			Select event.source

				Case GADGET_FIND_OK
					Find()
					ActivateGadget GADGET_FIND_OK
					
				Case GADGET_FIND_TEXT
					If TextFieldText(GADGET_FIND_TEXT)=""
						DisableGadget GADGET_FIND_OK
						If GADGET_MENU_FINDNEXT
							DisableGadget GADGET_MENU_FINDNEXT
							UpdateWindowMenu GadgetGroup(FindWindow)
						EndIf
					Else
						EnableGadget GADGET_FIND_OK
						If GADGET_MENU_FINDNEXT
							EnableGadget GADGET_MENU_FINDNEXT
							UpdateWindowMenu GadgetGroup(FindWindow)
						EndIf
					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
				Case GADGET_MENU_FINDNEXT
					Find()
				
			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

Public