Self-contained About window

BlitzMax Forums/BlitzMax GUI Programming/Self-contained About window

The main program just needs to call CreateAboutWindow() and ShowAboutWindow(), and this routine will take care of the rest, including deactivating the parent and all siblings.

I find this sort of thing very interesting, because it is no longer linear programming. You can mix and match all kinds of gadgets and windows to make modular applications.

Menu action events now contain the menu as the event source. You can use that instead of the event id. That means you can created sub-windows with menus and their own menu actions in the hook. The main program doesn't need to care or know what the subwindow is doing.

Global GADGET_ABOUT_WINDOW:TGadget
Global GADGET_ABOUT_OK:TGadget
Global GADGET_ABOUT_ACTIVE:TGadget

Function CreateAboutWindow(text$,group:TGadget)
	Local w,h,x,y
	w=284
	h=192
	GADGET_ABOUT_WINDOW:TGadget=CreateWindow("About",(GadgetWidth(group)-w)/2,(GadgetHeight(group)-h)/2,w,h,group,WINDOW_TITLEBAR|WINDOW_HIDDEN|WINDOW_DIALOG)
	x=8
	y=4
	panel:TGadget=CreatePanel(x,y,GADGET_ABOUT_WINDOW.ClientWidth()-2*x,GADGET_ABOUT_WINDOW.ClientHeight()-y-8-23-8,GADGET_ABOUT_WINDOW,PANEL_GROUP)
	CreateLabel(text$,panel.ClientWidth()/2-60,panel.ClientHeight()/2-32,panel.ClientWidth(),panel.ClientHeight(),panel)
	w=80
	h=23
	GADGET_ABOUT_OK=CreateButton("OK",(GADGET_ABOUT_WINDOW.ClientWidth()-w)/2,GADGET_ABOUT_WINDOW.ClientHeight()-h-8,w,h,GADGET_ABOUT_WINDOW,BUTTON_OK)
	AddHook EmitEventHook,AboutWindowHook
	SetHotKeyEvent KEY_ESCAPE,0,CreateEvent(EVENT_WINDOWCLOSE,GADGET_ABOUT_WINDOW)
EndFunction

Function ShowAboutWindow()
	Local gadget:TGadget
	GADGET_ABOUT_ACTIVE=ActiveGadget()
	ShowGadget GADGET_ABOUT_WINDOW
	ActivateGadget GADGET_ABOUT_OK
	DisableGadget GadgetGroup(GADGET_ABOUT_WINDOW)
	For gadget=EachIn GadgetGroup(GADGET_ABOUT_WINDOW).kids
		If gadget<>GADGET_ABOUT_WINDOW
			DisableGadget gadget
		EndIf
	Next
EndFunction

Function AboutWindowHook:Object(id:Int,data:Object,context:Object)
	If data=Null Return Null
	Local event:TEvent=TEvent(data)
	Select event.id
		
		Case EVENT_GADGETACTION
			Select event.source
				
				Case GADGET_ABOUT_OK
					EmitEvent CreateEvent(EVENT_WINDOWCLOSE,GADGET_ABOUT_WINDOW)
					Return Null
					
			EndSelect

		Case EVENT_WINDOWCLOSE
			Select event.source
				
				Case GADGET_ABOUT_WINDOW
					Local gadget:TGadget
					For gadget=EachIn GadgetGroup(GADGET_ABOUT_WINDOW).kids
						If gadget<>GADGET_ABOUT_WINDOW
							EnableGadget gadget
						EndIf
					Next
					EnableGadget GadgetGroup(GADGET_ABOUT_WINDOW)
					ActivateGadget GADGET_ABOUT_ACTIVE
					HideGadget GADGET_ABOUT_WINDOW
					Return Null
					
			EndSelect
			
	EndSelect
	Return data
EndFunction


Here's an updated version. All you do is:

Import "About.bmx"
CreateAboutWindow(MainWindow:TGadget)
Create a menu like this:

GADGET_MENU_ABOUT=CreateMenu("About",0,menu)

The code will automate everything else for you, including activating the last active window and hiding/showing the about window.

Strict

Import brl.maxgui

Private

Global GADGET_ABOUT_WINDOW:TGadget
Global GADGET_ABOUT_OK:TGadget
Global GADGET_ABOUT_CANCEL:TGadget
Global GADGET_ABOUT_ACTIVE:TGadget

Public

Global GADGET_MENU_ABOUT:TGadget

Function CreateAboutWindow(text$,group:TGadget)
	Local w,h,x,y,flags
	Local panel:TGadget
	flags=WINDOW_TITLEBAR|WINDOW_HIDDEN'|WINDOW_DIALOG
	w=284
	h=192
	GADGET_ABOUT_WINDOW:TGadget=CreateWindow("About",(GadgetWidth(group)-w)/2,(GadgetHeight(group)-h)/2,w,h,group,flags)
	x=8
	y=4
	panel:TGadget=CreatePanel(x,y,GADGET_ABOUT_WINDOW.ClientWidth()-2*x,GADGET_ABOUT_WINDOW.ClientHeight()-y-8-23-8,GADGET_ABOUT_WINDOW,PANEL_GROUP)
	CreateLabel(text$,panel.ClientWidth()/2-60,panel.ClientHeight()/2-32,panel.ClientWidth(),panel.ClientHeight(),panel)
	w=80
	h=23
	GADGET_ABOUT_OK=CreateButton("OK",(GADGET_ABOUT_WINDOW.ClientWidth()-w)/2,GADGET_ABOUT_WINDOW.ClientHeight()-h-8,w,h,GADGET_ABOUT_WINDOW,BUTTON_OK)
	GADGET_ABOUT_CANCEL=CreateButton("",GADGET_ABOUT_WINDOW.ClientWidth(),0,0,0,GADGET_ABOUT_WINDOW,BUTTON_CANCEL)	
	AddHook EmitEventHook,AboutWindowHook
EndFunction

Private

Function ShowAboutWindow()
	Local gadget:TGadget
	GADGET_ABOUT_ACTIVE=ActiveGadget()
	ShowGadget GADGET_ABOUT_WINDOW
	ActivateGadget GADGET_ABOUT_OK
	DisableGadget GadgetGroup(GADGET_ABOUT_WINDOW)
	For gadget=EachIn GadgetGroup(GADGET_ABOUT_WINDOW).kids
		If gadget<>GADGET_ABOUT_WINDOW
			DisableGadget gadget
		EndIf
	Next
EndFunction

Function AboutWindowHook:Object(id:Int,data:Object,context:Object)
	If data=Null Return Null
	Local event:TEvent=TEvent(data)
	Select event.id
		
		Case EVENT_GADGETACTION
			Select event.source
				
				Case GADGET_ABOUT_OK,GADGET_ABOUT_CANCEL
					EmitEvent CreateEvent(EVENT_WINDOWCLOSE,GADGET_ABOUT_WINDOW)
					Return Null
				
			EndSelect

		Case EVENT_MENUACTION
			Select event.source
				Case GADGET_MENU_ABOUT
					ShowAboutWindow
					Return Null
					
			EndSelect

		Case EVENT_WINDOWCLOSE
			Select event.source
				
				Case GADGET_ABOUT_WINDOW
					Local gadget:TGadget
					For gadget=EachIn GadgetGroup(GADGET_ABOUT_WINDOW).kids
						If gadget<>GADGET_ABOUT_WINDOW
							EnableGadget gadget
						EndIf
					Next
					EnableGadget GadgetGroup(GADGET_ABOUT_WINDOW)
					ActivateGadget GADGET_ABOUT_ACTIVE
					HideGadget GADGET_ABOUT_WINDOW
					Return Null
					
			EndSelect
			
	EndSelect
	Return data
EndFunction

Public


Sorry to bring up an old post, but I just wanted to thank you for this. I've been trying to work out a good way to implement dialog boxes in my application, and this seems like it'll work perfectly. Thanks!