Code archives/BlitzPlus Gui/WindowEx

This code has been declared by its author to be Public Domain code.

Download source code

WindowEx by JoshK2012
This class is designed to handle windows, toolbars, and menus, with toggling, enable/disable, and automatic icon loading. It makes working with complex programs much easier, and it handles multiple windows.

All MenuAction events will have an event source of the window from where the toolbar button or menu was pressed. Instead of enabling and toggling individual menus, you check and enable items. An item may have a menu, a toolbar, both, or neither, and it will work just fine.
SuperStrict

Import maxgui.proxygadgets
Import maxgui.drivers

Private

Type TIntWrapper
	
	Field i:Int
	
	Method Compare:Int(o:Object)
		Local intwrapper:TIntWrapper=TIntWrapper(o)
		If i>intwrapper.i Return 1
		If i<intwrapper.i Return -1
		Return 0
	EndMethod
	
	Function Create:TIntWrapper(i:Int)
		Local intwrapper:TIntWrapper=New TIntWrapper
		intwrapper.i=i
		Return intwrapper
	EndFunction
	
EndType

Function CopyRect(x0:Int,y0:Int,w:Int,h:Int,x1:Int,y1:Int,src:TPixmap,dst:TPixmap)
	Local x:Int,y:Int,c:Int'=RGBA(0,0,0,0)
	For x=0 To w-1
		For y=0 To h-1
			If src c=ReadPixelSafe(src,x0+x,y0+y)
			WritePixelSafe(dst,x1+x,y1+y,c)
		Next
	Next
EndFunction

Function ReadPixelSafe:Int(pixmap:TPixmap,x:Int,y:Int)
	If PixelIsValid(pixmap,x,y) Return pixmap.ReadPixel(x,y)
EndFunction

Function WritePixelSafe:Int(pixmap:TPixmap,x:Int,y:Int,color:Int)
	If PixelIsValid(pixmap,x,y) pixmap.WritePixel(x,y,color)
EndFunction

Function PixelIsValid:Int(pixmap:TPixmap,x:Int,y:Int)
	If x<0 Return False
	If x>pixmap.width-1 Return False
	If y<0 Return False
	If y>pixmap.height-1 Return False
	Return True
EndFunction

Local x:Int,y:Int
Local red:Int
MemCopy Varptr red,[0:Byte,0:Byte,255:Byte,255:Byte],4

For x=0 To TWindowEx.MissingIcon.width-1
	For y=0 To TWindowEx.MissingIcon.height-1
		TWindowEx.MissingIcon.WritePixel x,y,red
		If x=0 And y=0 TWindowEx.MissingIcon.WritePixel x,y,0
	Next
Next

For x=0 To TWindowEx.BlankIcon.width-1
	For y=0 To TWindowEx.BlankIcon.height-1
		TWindowEx.BlankIcon.WritePixel x,y,0
	Next
Next

Public

Type TWindowEx Extends TProxyGadget
	
	Const LoadPixmapPath:String=""
	Const ToolbarIconSize:Int=16
	
	Global menuiditerator:Int=0
	Global menuidmap:TMap=New TMap
	Global actionicon:TPixmap[]
	Global actionmenuicon:TPixmap[]
	Global MissingIcon:TPixmap=CreatePixmap(ToolbarIconSize,ToolbarIconSize,PF_RGBA8888)
	Global BlankIcon:TPixmap=CreatePixmap(ToolbarIconSize,ToolbarIconSize,PF_RGBA8888)
	
	Field window:TGadget
	Field toolbar:TGadget
	Field menuroot:TGadget
	Field currentmenu:TGadget
	Field toolbaritemid:Int[]
	Field menumap:TMap=New TMap
	Field toolbaritemmap:TMap=New TMap
	Field toolbartips:String[]
	Field existingtips:String[]
	Field existingtoolbarenablestate:Int[]
	
	Method Cleanup()
		RemoveHook EmitEventHook,EventHook,Self
		FreeGadget window
	EndMethod
	
	Method ToggleItem(action:Int)
		If ItemChecked(action)
			UncheckItem action
		Else
			CheckItem action
		EndIf
	EndMethod
	
	Method EnableItem(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu EnableGadget menu
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))
		If intwrapper
			EnableGadgetItem toolbar,intwrapper.i
			existingtoolbarenablestate[intwrapper.i]=True
		EndIf
	EndMethod
	
	Method DisableItem(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu DisableGadget menu
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))	
		If intwrapper
			DisableGadgetItem toolbar,intwrapper.i
			existingtoolbarenablestate[intwrapper.i]=False
		EndIf
	EndMethod
	
	Method CheckItem(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu CheckMenu menu
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))	
		If intwrapper SelectGadgetItem toolbar,intwrapper.i
	EndMethod
	
	Method UncheckItem(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu UncheckMenu menu
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))	
		If intwrapper DeselectGadgetItem toolbar,intwrapper.i
	EndMethod
	
	Method ItemEnabled:Int(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu Return Not GadgetDisabled(menu)
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))	
		If intwrapper Return existingtoolbarenablestate[intwrapper.i]
		Return False
	EndMethod
	
	Method ItemChecked:Int(action:Int)
		Local intwrapper:TIntWrapper=TIntWrapper.Create(action)
		Local menu:TGadget
		menu=TGadget(menumap.ValueForKey(intwrapper))
		If menu Return MenuChecked(menu)
		intwrapper = TIntWrapper(toolbaritemmap.valueforkey(intwrapper))	
		If intwrapper Return GadgetItemSelected(toolbar,intwrapper.i)
		Return False
	EndMethod
	
	Function GadgetItemSelected:Int(gadget:TGadget,i:Int)
		Local n:Int
		Local items:Int[]=SelectedGadgetItems(gadget)
		For n=0 To items.length-1
			If items[n]=i Return True
		Next
		Return False
	EndFunction
	
	Method ProcessEvent:Int(event:TEvent)	
		Local parent:TGadget
		
		Select event.id
		
		Case EVENT_MENUACTION
			If Not TWindowEx(event.source)
				parent=TGadget(event.source)
				While parent
					If parent=WindowMenu(window)
						event.source=Self
					EndIf
					parent=parent.parent
				Wend
			EndIf
			
		Case EVENT_GADGETACTION
			Select event.source
			
			Case toolbar
			
				If toolbar
					EmitEvent CreateEvent(EVENT_MENUACTION,Self,toolbaritemid[event.data])
					Return False
				EndIf
				
			EndSelect
			
		EndSelect
		
		Return True
	EndMethod
	
	Method AddMenuItem:TGadget(name:String,group:TGadget=Null,action:Int=0)
		Local menu:TGadget
		Local pixmap:TPixmap
		If Not group group=WindowMenu(window)
		menu = CreateMenu("  "+name,action,group)
		menumap.Insert TIntWrapper.Create(action),menu
		If action
			?win32
			If actionmenuicon[action]
				SetGadgetPixmap menu,actionmenuicon[action]
			EndIf
			?
		EndIf
		Return menu
	EndMethod
	
	Method AddMenuSeparator(group:TGadget)
		CreateMenu("",0,group)
	EndMethod
	
	Method AddToolbarSeparator()
		toolbaritemid = toolbaritemid[..toolbaritemid.length+1]
		toolbaritemid[toolbaritemid.length-1]=-1
		toolbartips=toolbartips[..toolbartips.length+1]
	EndMethod
	
	Method AddToolbarItem(tip:String,action:Int)
		toolbaritemid = toolbaritemid[..toolbaritemid.length+1]
		toolbaritemid[toolbaritemid.length-1]=action
		toolbaritemmap.Insert TIntWrapper.Create(action),TIntWrapper.Create(toolbaritemid.length-1)
		toolbartips=toolbartips[..toolbartips.length+1]
		toolbartips[toolbartips.length-1]=tip
	EndMethod
	
	Method Clear()
		Local menu:TGadget
		For menu=EachIn WindowMenu(window).kids
			FreeGadget menu
		Next
		If toolbar
			FreeGadget toolbar
			toolbar=Null
		EndIf
		menumap.Clear()
		toolbaritemmap.Clear()
		toolbartips=Null
		toolbaritemid=Null
		existingtips=Null
		existingtoolbarenablestate=Null
	EndMethod
	
	Method UpdateMenu()
		UpdateWindowMenu window
	EndMethod
	
	Method Build()
		Local pixmap:TPixmap
		Local icon:TPixmap
		Local i:Int
		Local action:Int
		
		UpdateWindowMenu window
		
		If toolbar
			FreeGadget toolbar
			toolbar=Null
		EndIf
		
		If toolbaritemid
			pixmap=CreatePixmap(ToolbarIconSize*toolbaritemid.length,ToolbarIconSize,PF_RGBA8888)
			For i=0 To toolbaritemid.length-1
				action=toolbaritemid[i]
				If action=-1
					icon=BlankIcon
				Else
					icon=actionicon[action]
				EndIf
				If Not icon
					icon=MissingIcon
				EndIf
				CopyRect 0,0,ToolbarIconSize,ToolbarIconSize,i*ToolbarIconSize,0,icon,pixmap
			Next
			toolbar = CreateToolbar(pixmap,0,0,0,0,window)
			SetToolbarTips toolbar,toolbartips
			existingtips = toolbartips
			existingtoolbarenablestate=existingtoolbarenablestate[..toolbaritemid.length]
			For i=0 To existingtoolbarenablestate.length-1
				existingtoolbarenablestate[i]=True
			Next
		EndIf
	EndMethod
	
	Function Create:TWindowEx(title:String,x:Int,y:Int,width:Int,height:Int,group:TGadget,style:Int=WINDOW_DEFAULT)
		Local windowex:TWindowEx=New TWindowEx
		windowex.window=CreateWindow(title,x,y,width,height,group,style)
		windowex.SetProxy windowex.window
		AddHook EmitEventHook,EventHook,windowex
		Return windowex
	EndFunction
	
	Function EventHook:Object(id:Int,data:Object,context:Object)
		Local event:TEvent
		Local windowex:TWindowEx
		
		windowex=TWindowEx(context)
		If windowex
			event=TEvent(data)
			If event
				If Not windowex.ProcessEvent(event) Return Null
			EndIf
		EndIf
		Return data
	EndFunction
	
	Function AllocMenuID:Int()
		menuiditerator:+1
		actionicon=actionicon[..menuiditerator+1]
		actionmenuicon=actionmenuicon[..menuiditerator+1]
		Return menuiditerator
	EndFunction
		
EndType

Function GetActionID:Int(action:String)
	Local intwrapper:TIntWrapper
	action = action.ToLower()		
	intwrapper = TIntWrapper(TWindowEx.menuidmap.valueforkey(action))
	If Not intwrapper
		intwrapper=New TIntWrapper
		intwrapper.i = TWindowEx.AllocMenuID()
		TWindowEx.menuidmap.Insert action,intwrapper
	EndIf
	TWindowEx.actionicon[intwrapper.i]=LoadPixmap(TWindowEx.LoadPixmapPath+action+".png")
	If TWindowEx.actionicon[intwrapper.i]
		If TWindowEx.actionicon[intwrapper.i].width<>TWindowEx.ToolbarIconSize Or TWindowEx.actionicon[intwrapper.i].height<>TWindowEx.ToolbarIconSize
			TWindowEx.actionicon[intwrapper.i] = ResizePixmap(TWindowEx.actionicon[intwrapper.i],TWindowEx.ToolbarIconSize,TWindowEx.ToolbarIconSize)
		EndIf
		TWindowEx.actionmenuicon[intwrapper.i] = ResizePixmap(TWindowEx.actionicon[intwrapper.i],13,13)
	EndIf
	Return intwrapper.i
EndFunction

Function CreateWindowEx:TWindowEx(title:String,x:Int,y:Int,width:Int,height:Int,group:TGadget,style:Int=WINDOW_DEFAULT)
	Return TWindowEx.Create(title,x,y,width,height,group,style)
EndFunction

'=========================================
'Example
'=========================================

AppTitle = "WindowEx Example"

Local window:TWindowEx = CreateWindowEx( AppTitle, 100, 100, 320, 240, Null)
Local menu:TGadget

Global action_file_new:Int = GetActionID("File_New")
Global action_file_open:Int = GetActionID("File_Open")
Global action_file_save:Int = GetActionID("File_Save")
Global action_app_exit:Int = GetActionID("App_Exit")
Global action_option_toggle:Int = GetActionID("Options_Toggle")
Global action_option_disable:Int = GetActionID("Options_Disable")
Global action_option_enable:Int = GetActionID("Options_Enable")

menu=window.AddMenuItem("File")
window.AddMenuItem "New",menu,action_file_new
window.AddMenuSeparator menu
window.AddMenuItem "Open",menu,action_file_open
window.AddMenuItem "Save",menu,action_file_save
window.AddMenuSeparator menu
window.AddMenuItem "Exit",menu,action_app_exit

menu=window.AddMenuItem("Options")
window.AddMenuItem "Toggle",menu,action_option_toggle
window.AddMenuItem "Disable",menu,action_option_disable
window.AddMenuItem "Enable",menu,action_option_enable

window.AddToolbarItem "New File",action_file_new
window.AddToolbarSeparator
window.AddToolbarItem "Open File",action_file_open
window.AddToolbarItem "Save File",action_file_save
window.AddToolbarSeparator
window.AddToolbarItem "Toggle",action_option_toggle
window.AddToolbarItem "Enable",action_option_enable
window.AddToolbarItem "Disable",action_option_disable

window.Build()

Repeat
	WaitEvent()
	Select EventID()
		
		Case EVENT_MENUACTION
			Select EventSource()
			
			Case window
				
				Select EventData()
				
				Case action_file_new
					Print "File_New"
				
				Case action_file_open
					Print "File_Open"
				
				Case action_file_save
					Print "File_Save"				
				
				Case action_app_exit
					Print "App_Exit"
					End
				
				Case action_option_toggle
					Print "Option_Toggle"
					If window.ItemChecked(action_option_toggle)
						window.UncheckItem action_option_toggle
					Else
						window.CheckItem action_option_toggle
					EndIf
					UpdateWindowMenu window
	
				Case action_option_disable
					Print "Option_Disable"
					If window.ItemEnabled(action_option_disable)
						window.DisableItem action_option_disable
					Else
						window.EnableItem action_option_disable
					EndIf
					UpdateWindowMenu window
				
				Case action_option_enable
					Print "Option_Enable"
					window.EnableItem action_option_disable
					UpdateWindowMenu window
					
				EndSelect
				
			EndSelect
			
		Case EVENT_APPTERMINATE, EVENT_WINDOWCLOSE
			End
			
	End Select
Forever

Comments

AdamRedwoods2012
i like it


Code Archives Forum