Resizable Tab Menu / POS Overlay

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Resizable Tab Menu / POS Overlay

Post by Hellbent » 23 Oct 2022, 06:59

.


*****Version 2 available here*****
viewtopic.php?f=6&t=109733&p=494966#p494966

.
menu 9.gif
menu 9.gif (963.01 KiB) Viewed 3201 times
.


Version 1 Window 7+
I made this overlay for a POS system that someone else might find useful.
tab menu 1.gif
tab menu 1.gif (804.68 KiB) Viewed 4133 times
The way you use this is much the way you would use other ahk gui controls ( listbox, listview, DDL, ComboBox, etc.)
This is the control, you do the coding.

To use this script you will need a copy of the GDI+ lib for ahk found here on the forum.

Once you have the GDI+ lib you can create a new script and paste this into it ( menu code ).

Code: Select all

;************
;POS_Control Class v1.2
;Written By: Hellbent
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
class POS_Control	{
	static init := POS_Control.SetUp()
	TabMoveButton_Y[]{
		Get{
			return This.TabMoveAllButton_Y + This.TabMoveAllButton_H + This.TabMargin
		}
	}
	TabMoveButton_H[]{
		Get{
			return This.TabWindow.H - This.TabMoveAllButton_H - 3 * This.TabMargin
		}
	}
	TabDisplayArea_W[]{
		Get{
			return This.TabWindow.W - This.TabMoveButton_W - 3 * This.TabMargin - This.TabMoveButton_W - This.TabMargin
		}
	}
	TabDisplayArea_H[]{
		Get{
			return This.TabWindow.H - 2 * This.TabMargin
		}
	}
	TabUPButton_X[]{
		Get{
			return This.TabMoveButton_W + This.TabDisplayArea_W + 3 * This.TabMargin
		}
	}
	TabDownButton_X[]{
		Get{
			return This.TabUPButton_X
		}
	}
	TabResizeButton_X[]{
		Get{
			return This.TabWindow.W - 28
		}
	}
	TabResizeButton_Y[]{
		Get{
			return This.TabWindow.H - 28
		}
	}
	ButtonMoveButton_Y[]{
		Get{
			return This.ButtonMoveAllButton_Y + This.ButtonMoveAllButton_H + This.ButtonMargin
		}
	}
	ButtonMoveButton_H[]{
		Get{
			return This.ButtonWindow.H - This.ButtonMoveAllButton_H - 3 * This.ButtonMargin
		}
	}
	ButtonDisplayArea_W[]{
		Get{
			return This.ButtonWindow.W - This.ButtonMoveButton_W - 3 * This.ButtonMargin - This.ButtonMoveButton_W - This.ButtonMargin
		}
	}
	ButtonDisplayArea_H[]{
		Get{
			return This.ButtonWindow.H - 2 * This.ButtonMargin
		}
	}
	ButtonUPButton_X[]{
		Get{
			return This.ButtonMoveButton_W + This.ButtonDisplayArea_W + 3 * This.ButtonMargin
		}
	}
	ButtonDownButton_X[]{
		Get{
			return This.ButtonUPButton_X
		}
	}
	ButtonResizeButton_X[]{
		Get{
			return This.ButtonWindow.W - 28
		}
	}
	ButtonResizeButton_Y[]{
		Get{
			return This.ButtonWindow.H - 28
		}
	}
	TabUnit_Width[]{
		Get{
			return ( out := Floor( This.TabDisplayArea_W - This.TabMargin ) / ( This.TabWidth + This.TabMargin ) ) ? ( floor( out ) ) : ( 1 )
		}
	}
	TabUnit_Height[]{
		Get{
			return ( out := Floor( This.TabDisplayArea_H - This.TabMargin ) / ( This.TabHeight + This.TabMargin ) ) ? ( Floor( out ) ) : ( 1 )
		}
	}
	TabUnit_Area[]{
		Get{
			return ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) + This.TabUnit_Width * This.TabUnit_Height ) 
		}
	}
	ButtonUnit_Width[]{
		Get{
			return ( out := Floor( This.ButtonDisplayArea_W - This.ButtonMargin ) / ( This.ButtonWidth + This.ButtonMargin ) ) ? ( floor( out ) ) : ( 1 )
		}
	}
	ButtonUnit_Height[]{
		Get{
			return ( out := Floor( This.ButtonDisplayArea_H - This.ButtonMargin ) / ( This.ButtonHeight + This.ButtonMargin ) ) ? ( Floor( out ) ) : ( 1 )
		}
	}
	ButtonUnit_Area[]{
		Get{
			return ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) + This.ButtonUnit_Width * This.ButtonUnit_Height ) 
		}
	}
	ButtonMinWidth[]{
		Get{
			return This.ButtonWidth + This.ButtonMoveAllButton_W + This.ButtonUPButton_W + 6 * This.ButtonMargin
		}
	}
	ButtonMinHeight[]{
		Get{
			if( This.ButtonHeight + 4 * This.ButtonMargin < 120 )
				return 120
			else 
				return This.ButtonHeight + 4 * This.ButtonMargin
		}
	}	
	TabMinWidth[]{
		Get{
			return This.TabWidth + This.TabMoveAllButton_W + This.TabUPButton_W + 6 * This.TabMargin
		}
	}
	TabMinHeight[]{
		Get{
			if( ( This.TabHeight + 4 * This.TabMargin ) < 120 )
				return 120
			else
				return This.TabHeight + 4 * This.TabMargin
		}
	}
	SetUp(){
		
		Gdip_Startup()
		
		This.Tabs := []
		
		;*****************************
		;*****************************
		;*****************************
		
		This.TabWindow := New PopUpWindow( { AutoShow: 1 , X: "Center" , Y: 200 , W: 500 , H: 300 , Options: " -DPIScale +AlwaysOnTop +ToolWindow" } )
		
		This.TabWidth := 180
		This.TabHeight := 80
		
		This.TabMargin := 10
		
		This.TabBackgroundColor := "0xFF62666a"
		This.TabMoveAllButton_Color := "0xFF3399cc"
		This.TabMoveButton_Color := This.TabMoveAllButton_Color
		This.TabDisplayArea_Color := "0xfff0f0f0"
		This.TabUPButton_Color := This.TabMoveAllButton_Color
		This.TabDownButton_Color := This.TabMoveAllButton_Color
		This.TabResizeButton_Color := "0xFFFFFF00"
		This.TabControlBackgroundColor := "0xFF22262a"
		
		This.TabMoveAllButton_X := This.TabMargin
		This.TabMoveAllButton_Y := This.TabMargin
		This.TabMoveAllButton_W := 20
		This.TabMoveAllButton_H := 30
		
		This.TabMoveButton_X := This.TabMargin
		This.TabMoveButton_W := 20
		
		This.TabDisplayArea_X := This.TabMoveButton_W + 2 * This.TabMargin
		This.TabDisplayArea_Y := This.TabMargin
		
		This.TabUPButton_Y := This.TabMargin
		This.TabUPButton_W := 20
		This.TabUPButton_H := 30
		
		This.TabDownButton_Y := This.TabUPButton_H + 2 * This.TabMargin
		This.TabDownButton_W := 20
		This.TabDownButton_H := 30
		
		This.TabResizeButton_W := 20
		This.TabResizeButton_H := 20
		
		This.TabSelectedTab := 1
		This.TabSelectedRow := 1
		
		;*****************************
		;*****************************
		;*****************************
		
		This.ButtonWindow := New PopUpWindow( { AutoShow: 1 , X: This.TabWindow.X + This.TabWindow.W , Y: 200 , W: 300 , H: 300 , Options: " -DPIScale +AlwaysOnTop +ToolWindow" } )
		
		This.ButtonWidth := 80
		This.ButtonHeight := 80
		
		This.ButtonMargin := 10
		
		This.ButtonMoveAllButton_Color := "0xFF3377aa"
		This.ButtonMoveButton_Color := This.ButtonMoveAllButton_Color
		This.ButtonDisplayArea_Color := "0xFF22262a"
		This.ButtonUPButton_Color := This.ButtonMoveAllButton_Color
		This.ButtonDownButton_Color := This.ButtonMoveAllButton_Color
		This.ButtonResizeButton_Color := "0xFFFFFF00"
		This.ButtonControlBackgroundColor := "0xFF22262a"
		
		This.ButtonMoveAllButton_X := This.ButtonMargin
		This.ButtonMoveAllButton_Y := This.ButtonMargin
		This.ButtonMoveAllButton_W := 20
		This.ButtonMoveAllButton_H := 30
		
		This.ButtonMoveButton_X := This.ButtonMargin
		This.ButtonMoveButton_W := 20
	
		This.ButtonDisplayArea_X := This.ButtonMoveButton_W + 2 * This.ButtonMargin
		This.ButtonDisplayArea_Y := This.ButtonMargin
				
		This.ButtonUPButton_Y := This.ButtonMargin
		This.ButtonUPButton_W := 20
		This.ButtonUPButton_H := 30
				
		This.ButtonDownButton_Y := This.ButtonUPButton_H + 2 * This.ButtonMargin
		This.ButtonDownButton_W := 20
		This.ButtonDownButton_H := 30
		
		This.ButtonResizeButton_W := 20
		This.ButtonResizeButton_H := 20
				
		This.ButtonSelectedTab := 0
		This.ButtonSelectedRow := 1
		
		This.ButtonActiveTab := 0
		
		;*****************************
		;*****************************
		;*****************************
		
		OnMessage( 0x201 , This.OnClick.Bind( This ) )
		
		OnMessage( 0x020A , This.OnWheelChange.Bind( This ) )
		
	}
	AddNewTab( position := "" , obj := "" ){
		
		local TabObj := {} , k , v
		
		if( !position )
			position := This.Tabs.MaxIndex() + 1

		TabObj.Text := ""
		TabObj.Color := "0xFFFF0000"
		TabObj.FontType := "Segoe UI"
		TabObj.FontSize := 12
		TabObj.FontOptions := " Center vCenter Bold "
		TabObj.FontColor := "0xFF000000"
		
		if( IsObject( obj ) ){
			for k , v in obj 	{
				if( TabObj.HasKey( k ) )
					TabObj[ k ] := obj[ k ]
			}
		}
		
		This.Tabs[ Position ] := TabObj
		This.Tabs[ Position ].Buttons := []
		
		if( obj.Haskey( "B64" ) ){
			This.Tabs[ Position ].Icon := This.B64ToPBitmap( obj.B64 )
		}else if( obj.Haskey( "pBitmap" ) ){
			This.Tabs[ Position ].Icon := obj.pBitmap
		
		}
		
	}
	AddNewButton( Tab := "" , position := "" , obj := "" ){
		
		local ButtonObj := {} , k , v 
		
		if( !Tab )
			Tab := This.Tabs.MaxIndex() 
		
		
		if( !position ){
			
			position := This.Tabs[ Tab ].Buttons.MaxIndex() + 1
			
			if( !position )
				position := 1
		}
		
		ButtonObj.Text := ""
		ButtonObj.Color := "0xFFFF0000"
		ButtonObj.FontType := "Segoe UI"
		ButtonObj.FontSize := 12
		ButtonObj.FontOptions := " Center vCenter Bold "
		ButtonObj.FontColor := "0xFF000000"
		
		
		if( IsObject( obj ) ){
			for k , v in obj 	{
				if( ButtonObj.HasKey( k ) )
					ButtonObj[ k ] := obj[ k ]
			}
		}
		
		This.Tabs[ Tab ].Buttons[ position ] := ButtonObj
		
		if( obj.HasKey( "Label" ) )
			This.Tabs[ Tab ].Buttons[ position ].Label := obj.Label
		
		if( obj.Haskey( "B64" ) ){
			
			This.Tabs[ Tab ].Buttons[ position ].Icon := This.B64ToPBitmap( obj.B64 )
			
		}else if( obj.Haskey( "pBitmap" ) ){
			
			This.Tabs[ Tab ].Buttons[ position ].Icon := obj.pBitmap
		}
		
	}
	MoveWindow( Window := "Tab" , all := 0 ){
		
		local x , y 
		
		if( all ){
			
			if( window = "tab" ){
				
				This.WinVector := New Vector( This.ButtonWindow.X , This.ButtonWindow.Y )
				This.WinVector.Sub( This.TabWindow.X , This.TabWindow.Y )
				
				PostMessage, 0xA1, 2 
				
				While( GetKeyState( "LButton" , "P" ) )
					Sleep 30
				
				WinGetPos, x, y,,, % "ahk_id " This.TabWindow.Hwnd
				This.TabWindow.UpdateSettings( { X: x , Y: y } )
				
				This.ButtonWindow.UpdateSettings( { X: x + This.WinVector.X , Y: y + This.WinVector.Y } )
				This.DrawButtonWindow()
				
			}else{
				
				This.WinVector := New Vector( This.TabWindow.X , This.TabWindow.Y )
				This.WinVector.Sub( This.ButtonWindow.X , This.ButtonWindow.Y )
				
				PostMessage, 0xA1, 2 
				
				While( GetKeyState( "LButton" , "P" ) )
					Sleep 30
				
				WinGetPos, x, y,,, % "ahk_id " This.ButtonWindow.Hwnd
				This.ButtonWindow.UpdateSettings( { X: x , Y: y } )
				
				This.TabWindow.UpdateSettings( { X: x + This.WinVector.X , Y: y + This.WinVector.Y } )
				This.DrawTabWindow()
				
			}
			
		}else{
			
			PostMessage, 0xA1, 2 
			
			While( GetKeyState( "LButton" , "P" ) )
				Sleep 30
			
			WinGetPos, x, y,,, % "ahk_id " This[ window "Window" ].Hwnd
			This[ window "Window" ].UpdateSettings( { X: x , Y: y } )
			
		}
		
	}
	ResizeWindow( window := "Tab" ){
		
		local lx , ly , x , y 
		
		CoordMode, Mouse, Screen
		
		This[ window "SelectedRow" ] := 1
		
		While( GetKeyState( "LButton" , "P" ) ){
			
			MouseGetPos, x , y
			
			if( x != lx || y != ly ){
				lx := x , ly := y
				
				if( ( This[ window "Window" ].W := x - This[ window "Window" ].X ) < This[ window "MinWidth" ] )
					This[ window "Window" ].W := This[ window "MinWidth" ]
				
				if( ( This[ window "Window" ].H := y - This[ window "Window" ].Y ) < This[ window "MinHeight" ] )
					This[ window "Window" ].H := This[ window "MinHeight" ]
				
				This[ window "Window" ].UpdateSettings( "" , 1 )
				This[ "Draw" Window "Window" ]()
				
			}
			
		}
		
	}
	CheckWindowTriggers( Window := "Tab" ){
		
		local x , y , k , v
		
		CoordMode, Mouse, Client
		
		MouseGetPos, x , y 
		
		for k , v in [ Window "MoveAllButton_" , Window "MoveButton_" , Window "DisplayArea_" , Window "UPButton_" , Window "DownButton_" , Window "ResizeButton_" ]{
			
			if( x >= This[ v "X" ] && x <= This[ v "X" ] + This[ v "W" ] && y >= This[ v "Y" ] && y <= This[ v "Y" ] + This[ v "H" ]){
				
				return A_Index
			
			}
		
		}
	
	}
	CheckTabControls(){
		
		local x , y , k , v , index , mx , my
		
		CoordMode, Mouse, Client
		
		MouseGetPos, mx , my 
		
		index := 1 + ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) )
		y := This.TabDisplayArea_Y + This.TabMargin
		
		Loop, % This.TabUnit_Height	{
			
			x := This.TabDisplayArea_X + This.TabMargin
			
			Loop, % This.TabUnit_Width	{
				
				if( IsObject( This.Tabs[ index ] ) ){
					
					if( mx >= x && mx <= x + This.TabWidth && my >= y && my <= y + This.TabHeight ){
						
						return index
					
					}
				
				}
				
				x += This.TabWidth + This.TabMargin
				index++
			
			}
			
			y += This.TabHeight + This.TabMargin
		
		}
		
	}
	CheckButtonControls(){
		
		local x , y , mx , my , index
		
		CoordMode, Mouse, Client
		
		MouseGetPos, mx , my 
		
		index := 1 + ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) )
		y := This.ButtonDisplayArea_Y + This.ButtonMargin
		
		Loop, % This.ButtonUnit_Height	{
			
			x := This.ButtonDisplayArea_X + This.ButtonMargin
			
			Loop, % This.ButtonUnit_Width	{
				
				if( IsObject( This.Tabs[ This.TabSelectedTab ].Buttons[ index ] ) ){
					
					if( mx >= x && mx <= x + This.ButtonWidth && my >= y && my <= y + This.ButtonHeight ){
						
						return index
					
					}
				
				}
				
				x += This.ButtonWidth + This.ButtonMargin
				index++
			
			}
			
			y += This.ButtonHeight + This.ButtonMargin
		
		}
	}
	OnWheelChange( input , w , m , hwnd ){
		
		local dir , sel , test
		
		if( This.Active )
			return
		
		This.Active := 1
		
		if( hwnd = This.TabWindow.Hwnd )
			sel := "Tab"
		else
			sel := "Button"
		
		dir := ( ( input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
		
		if( !dir ){
			
			if( This[ sel "SelectedRow" ] > 1 ){
				
				--This[ sel "SelectedRow" ]
				This[ "Draw" sel "Window" ]()
			
			}
		}else{
			
			if( sel = "Tab" ){
				
				if( This.TabUnit_Area < This.Tabs.MaxIndex() ){
					
					This.TabSelectedRow++
					This.DrawTabWindow()
				
				}
				
			}else{
				
				if( This.ButtonUnit_Area < This.Tabs[ This.TabSelectedTab ].Buttons.MaxIndex() ){
					
					This.ButtonSelectedRow++
					This.DrawButtonWindow()
				
				}
			
			}
		
		}
		
		Sleep, 30
		This.Active := 0
		
	}
	OnClick( l , w , m , hwnd ){
		
		local sel
		
		if( hwnd = This.TabWindow.Hwnd ){
			
			if( control := This.CheckWindowTriggers( "Tab" ) ){
				
				if( control = 1 ){
					
					This.MoveWindow( "Tab" , 1 )
				
				}else if( control = 2 ){
					
					This.MoveWindow( "Tab" )
				
				}else if( control = 3 ){
					
					if( sel := This.CheckTabControls()  ){
						
						This.TabSelectedTab := sel
						This.ButtonSelectedRow := 1
						
						This.DrawTabWindow()
						This.DrawButtonWindow()
					
					}
					
				}else if( control = 4 ){
			
					if( This.TabSelectedRow > 1 ){
						
						--This.TabSelectedRow
						This.DrawTabWindow()
					
					}
					
				}else if( control = 5 ){
					
					if( This.TabUnit_Area < This.Tabs.MaxIndex() ){
						
						This.TabSelectedRow++
						This.DrawTabWindow()
					
					}
					
				}else if( control = 6 ){
					
					This.ResizeWindow( "Tab" )
				
				}
			
			}
			
			return 1
			
		}else if( hwnd = This.ButtonWindow.Hwnd ){
			
			if( control := This.CheckWindowTriggers( "Button" ) ){
				
				if( control = 1 ){
					
					This.MoveWindow( "Button" , 1 )
					
				}else if( control = 2 ){
					
					This.MoveWindow( "Button" )
					
				}else if( control = 3 ){
					
					if( sel := This.CheckButtonControls()  ){
						
						This.ButtonSelectedTab := sel
						This.DrawButtonWindow()
						
						While( GetKeyState( "LButton" , "P" ) )
							Sleep, 30
						
						if( This.Tabs[ This.TabSelectedTab ].Buttons[ This.ButtonSelectedTab ].Label ){
							
							This.ButtonActiveTab := This.ButtonSelectedTab
							SetTimer, % This.Tabs[ This.TabSelectedTab ].Buttons[ This.ButtonSelectedTab ].Label , -30
							;~ gosub, % This.Tabs[ This.TabSelectedTab ].Buttons[ This.ButtonSelectedTab ].Label
						}
						
						This.ButtonSelectedTab := 0
						This.DrawButtonWindow()
					
					}
					
				}else if( control = 4 ){
					
					if( This.ButtonSelectedRow > 1 ){
						
						--This.ButtonSelectedRow
						This.DrawButtonWindow()
						
					}
					
				}else if( control = 5 ){
					
					if( This.ButtonUnit_Area < This.Tabs[ This.TabSelectedTab ].Buttons.MaxIndex() ){
						
						This.ButtonSelectedRow++
						This.DrawButtonWindow()
						
					}
					
					
				}else if( control = 6 ){
					
					This.ResizeWindow( "Button" )
					
				}
				
			}
			
			return 1
			
		}
		
		return 0
		
	}
	DrawTabWindow(){
		
		This.TabWindow.ClearWindow()
		
		;Paint Background
		This.TabWindow.PaintBackground( { Color: This.TabBackgroundColor , X: 2 , Y: 2 , W: This.TabWindow.W - 4 , H: This.TabWindow.H - 4 , Round: 5 } )  
		
		;Paint Move all button
		This.TabWindow.PaintBackground( { Color: This.TabMoveAllButton_Color , X: This.TabMoveAllButton_X , Y: This.TabMoveAllButton_Y , W: This.TabMoveAllButton_W , H: This.TabMoveAllButton_H , Round: 5 } )  
		
		;Paint Move Button
		This.TabWindow.PaintBackground( { Color: This.TabMoveButton_Color , X: This.TabMoveButton_X , Y: This.TabMoveButton_Y , W: This.TabMoveButton_W , H: This.TabMoveButton_H , Round: 5 } )  
		
		;Paint Resize Button
		This.TabWindow.PaintBackground( { Color: This.TabResizeButton_Color , X: This.TabResizeButton_X , Y: This.TabResizeButton_Y , W: This.TabResizeButton_W , H: This.TabResizeButton_H , Round: 5 } )  
		
		;Paint display area
		This.TabWindow.PaintBackground( { Color: This.TabDisplayArea_Color , X: This.TabDisplayArea_X , Y: This.TabDisplayArea_Y , W: This.TabDisplayArea_W , H: This.TabDisplayArea_H , Round: 5 } )  
		
		;Paint Up Button
		This.TabWindow.PaintBackground( { Color: This.TabUPButton_Color , X: This.TabUPButton_X , Y: This.TabUPButton_Y , W: This.TabUPButton_W , H: This.TabUPButton_H , Round: 5 } )  
		
		;Paint Down Button
		This.TabWindow.PaintBackground( { Color: This.TabDownButton_Color , X: This.TabDownButton_X , Y: This.TabDownButton_Y , W: This.TabDownButton_W , H: This.TabDownButton_H , Round: 5 } )  
		
		index := 1 + ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) )
		y := This.TabDisplayArea_Y + This.TabMargin
		
		Loop, % This.TabUnit_Height	{
			
			x := This.TabDisplayArea_X + This.TabMargin
			
			Loop, % This.TabUnit_Width	{
				
				if( IsObject( This.Tabs[ index ] ) ){
					
					if( This.Tabs[ index ].Haskey( "Icon" ) ){
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						This.TabWindow.DrawBitmap( This.Tabs[ index ].Icon , { X: x , Y: y , W: ( This.TabWidth <= This.TabHeight ) ? ( w := This.TabWidth ) : ( w := This.TabHeight ) , H: w } , 0 )
						DrawText( This.TabWindow.G , x , y , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColor , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}else{
					
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						DrawText( This.TabWindow.G , x , y , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColor , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}
				}
				
				x += This.TabWidth + This.TabMargin
				index++
			
			}
			
			y += This.TabHeight + This.TabMargin
		
		}
		
		This.TabWindow.UpdateWindow()
		
	}
	DrawButtonWindow(){
		
		This.ButtonWindow.ClearWindow()
		
		;Paint Background
		This.ButtonWindow.PaintBackground( { Color: "0x66000000" , X: 2 , Y: 2 , W: This.ButtonWindow.W - 4 , H: This.ButtonWindow.H - 4 , Round: 5 } )  
		
		;Paint Move all button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonMoveAllButton_Color , X: This.ButtonMoveAllButton_X , Y: This.ButtonMoveAllButton_Y , W: This.ButtonMoveAllButton_W , H: This.ButtonMoveAllButton_H , Round: 5 } )  
		
		;Paint Move Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonMoveButton_Color , X: This.ButtonMoveButton_X , Y: This.ButtonMoveButton_Y , W: This.ButtonMoveButton_W , H: This.ButtonMoveButton_H , Round: 5 } )  
		
		;Paint Resize Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonResizeButton_Color , X: This.ButtonResizeButton_X , Y: This.ButtonResizeButton_Y , W: This.ButtonResizeButton_W , H: This.ButtonResizeButton_H , Round: 5 } )  
		
		;Paint display area
		This.ButtonWindow.PaintBackground( { Color: This.ButtonDisplayArea_Color , X: This.ButtonDisplayArea_X , Y: This.ButtonDisplayArea_Y , W: This.ButtonDisplayArea_W , H: This.ButtonDisplayArea_H , Round: 5 } )  
		
		;Paint Up Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonUPButton_Color , X: This.ButtonUPButton_X , Y: This.ButtonUPButton_Y , W: This.ButtonUPButton_W , H: This.ButtonUPButton_H , Round: 5 } )  
		
		;Paint Down Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonDownButton_Color , X: This.ButtonDownButton_X , Y: This.ButtonDownButton_Y , W: This.ButtonDownButton_W , H: This.ButtonDownButton_H , Round: 5 } )  
		
		index := 1 + ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) )
		y := This.ButtonDisplayArea_Y + This.ButtonMargin
		
		Loop, % This.ButtonUnit_Height	{
			
			x := This.ButtonDisplayArea_X + This.ButtonMargin
			
			Loop, % This.ButtonUnit_Width	{
				
				if( IsObject( This.Tabs[ This.TabSelectedTab ].Buttons[ index ] ) ){
					if( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Haskey( "Icon" ) ){
						This.ButtonWindow.PaintBackground( { Color: ( This.ButtonSelectedTab = index ) ? ( "0xFFFF0000" ) : ( This.ButtonControlBackgroundColor ) , X: x - 4 , Y: y - 4 , W: This.ButtonWidth + 8 , H: This.ButtonHeight + 8 , Round: 5 } )  
						This.ButtonWindow.PaintBackground( { Color: This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , X: x , Y: y , W: This.ButtonWidth , H: This.ButtonHeight , Round: 5 } )  
						This.ButtonWindow.DrawBitmap( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Icon , { X: x , Y: y , W: ( This.ButtonWidth <= This.ButtonHeight ) ? ( w := This.ButtonWidth ) : ( w := This.ButtonHeight ) , H: w } , 0 )
						DrawText( This.ButtonWindow.G , x , y , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColor , This.ButtonWidth , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
					}else{
						This.ButtonWindow.PaintBackground( { Color: ( This.ButtonSelectedTab = index ) ? ( "0xFFFF0000" ) : ( This.ButtonControlBackgroundColor ) , X: x - 4 , Y: y - 4 , W: This.ButtonWidth + 8 , H: This.ButtonHeight + 8 , Round: 5 } )  
						This.ButtonWindow.PaintBackground( { Color: This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , X: x , Y: y , W: This.ButtonWidth , H: This.ButtonHeight , Round: 5 } )  
						DrawText( This.ButtonWindow.G , x , y , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColor , This.ButtonWidth , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
					}
				}
				
				x += This.ButtonWidth + This.ButtonMargin
				index++
			
			}
			
			y += This.ButtonHeight + This.ButtonMargin
		
		}
		
		This.ButtonWindow.UpdateWindow()
	
	}
	
	B64ToPBitmap( Input ){
		local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
		VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
		B64 := Input
		If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
			Return False
		VarSetCapacity( Dec , DecLen , 0 )
		If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
			Return False
		DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
		DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
		DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
		DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
		return pBitmap
	}
}
;************
;Vector Class
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
Class Vector	{
	;Written By: HB
	;Date: Sept 23rd, 2022
	;Last Edit: Sept 24th, 2022
	;Purpose: Vector math class 
	;Credit: Rohwedder 
	;Resources: 
		;Line intercept concepts and code: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=37175
		;Create an Arrow: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=92039&p=479129#p478944
		;Getting an angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483661#p483678
		;Setting an Angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483786#p483811
		;
		
	static RadToDeg := 45 / ATan( 1 ) 
		, DegToRad := ATan( 1 ) / 45 
		
	__New( x := 0 , y := 0 , rotate := 0 ){ 
		if( IsObject( x ) ){
			if( rotate = 3 ){
				This.X := x.X * -1
				,This.Y := x.Y * -1
			}else if( rotate = 2 ){
				This.X := x.Y 
				,This.Y := x.X * -1
			}else if( rotate = 1 ){
				This.X := x.Y * -1
				,This.Y := x.X 
			}else{
				This.X := x.X
				,This.Y := x.Y
			}
		}else{
			if( rotate = 3 ){
				This.X := X * -1
				,This.Y := Y * -1
			}else if( rotate = 2 ){
				This.X := Y 
				,This.Y := X * -1
			}else if( rotate = 1 ){
				This.X := Y * -1
				,This.Y := X 
			}else{
				This.X := X
				,This.Y := Y
			}
		}
	}
	Add( x , y := "" ){
		if( IsObject( x ) ){
			This.X += x.X
			,This.Y += x.Y
		}else if( y = "" ){
			This.X += x 
			,This.Y += x
		}else{
			This.X += x 
			,This.Y += y 
		}
	}
	Sub( x , y := "" ){
		if( IsObject( x ) ){
			This.X -= x.X
			,This.Y -= x.Y
		}else if( y = "" ){
			This.X -= X
			,This.Y -= X
		}else{
			This.X -= X
			,This.Y -= Y
		}
	}
	Div( x , y := "" ){
		if( IsObject( x ) ){
			This.X /= x.X
			,This.Y /= x.Y
		}else if( x && y = "" ){
			This.X /= x 
			,This.Y /= x 
		}else{
			This.X /= X
			,This.Y /= Y
		}
	}
	Mult( x , y := "" ){
		if( IsObject( x ) ){
			This.X *= x.X
			,This.Y *= x.Y
		}else if( x && y = "" ){
			This.X *= x 
			,This.Y *= x 
		}else{
			This.X *= X
			,This.Y *= Y
		}
	}
	Dist( x , y := "" ){
		if( IsObject( x ) )
			return Sqrt( ( ( This.X - x.X ) **2 ) + ( ( This.Y - x.Y ) **2 ) )
		else 
			return Sqrt( ( ( This.X - X ) **2 ) + ( ( This.Y - Y ) **2 ) )
	}
	GetMag(){
		return Sqrt( This.X * This.X + This.Y * This.Y )
	}
	SetMag( magnitude ){
		local m := This.GetMag()
		This.X := This.X * magnitude / m
		,This.Y := This.Y * magnitude / m
	}
	MagSq(){
		return This.GetMag()**2
	}	
	Dot( x , y := "" ){
		if( IsObject( x ) )
			return ( This.X * x.X ) + ( This.Y * x.Y )
		else
			return ( This.X * X ) + ( This.Y * Y )
	}
	Cross( x , y := "" ){
		if( IsObject( x ) )
			return This.X * x.Y - This.Y * x.X
		else
			return This.X * Y - This.Y * X
		
	}
	Norm(){
		local m := This.GetMag()
		This.X /= m
		This.Y /= m
	}
	GetAngle(){ 
		local angle 
		( (  angle := Vector.RadToDeg * DllCall( "msvcrt\atan2" , "Double" , This.Y , "Double" , This.X , "CDECL Double" ) ) < 0 ) ? ( angle += 360 )
		return angle
	}
	SetAngle( newAngle := 0 , NewVector := 0 ){
		local Angle := This.GetAngle()
		, ChangeAngle := newAngle - Angle 
		, Co := Cos( Vector.DegToRad * ChangeAngle )
		, Si := Sin( Vector.DegToRad * ChangeAngle )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	RotateAngle( rotationAmount := 90 , NewVector := 0 ){
		local Co := Cos( Vector.DegToRad * rotationAmount )
		, Si := Sin( Vector.DegToRad * rotationAmount )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	;********************************************
	;class methods
	TestLineInterceptPoint( interceptPoint , Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } } , interceptPoint = { X: , Y: }
		local
		for k , v in [ "X" , "Y" ]	
			M%v%_Min := min( Line1.Start[ v ] , Line1.End[ v ] )
			,M%v%_Max := max( Line1.Start[ v ] , Line1.End[ v ] )
			,L%v%_Min := min( Line2.Start[ v ] , Line2.End[ v ] )
			,L%v%_Max := max( Line2.Start[ v ] , Line2.End[ v ] )
		if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
			return 1
		return 0
	}
	GetLineInterceptPoint( Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } }
		local A1 := Line1.End.Y - Line1.Start.Y
		,B1 := Line1.Start.X - Line1.End.X
		,C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
		,A2 := Line2.End.Y - Line2.Start.Y
		,B2 := Line2.Start.X - Line2.End.X
		,C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
		,Denominator := A1 * B2 - A2 * B1 
		return New Vector( { X: ( ( B2 * C1 - B1 * C2 ) / Denominator )  , Y: ( ( A1 * C2 - A2 * C1 ) / Denominator ) } )
	}
	;********************************************
}
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2.2
;Date Written: Oct 28th, 2021
;Last Edit: Feb 7th, 2022 :Changed the trigger method.
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.G )
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow( alpha := 255 ){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H , alpha )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
}
;**************************************************************************************************
;**************************************************************************************************
;**************************************************************************************************
DrawText( G , x , y , text ,  color , width , height , options := " Center vCenter Bold s12 " , type := "comic Sans MS" ){
	Brush := Gdip_BrushCreateSolid( color ) , Gdip_TextToGraphics( G , text , options " c" brush " x" x " y" y  , type , width , height ) , Gdip_DeleteBrush( Brush )
}	
FillCircle( G , x , y  , color := "0xFFFF0000" , width := 30 , height := "" ){
	local Brush
	if( !height )
		Brush := Gdip_BrushCreateSolid( color ) , Gdip_FillEllipse( G , Brush , x , y , width , width ) , Gdip_DeleteBrush( Brush )
	else
		Brush := Gdip_BrushCreateSolid( color ) , Gdip_FillEllipse( G , Brush , x , y , width , height ) , Gdip_DeleteBrush( Brush )
}
Random( Min := 0 , Max := 100 ){
	local out
	Random, out , Min , Max
	return out
}

Next you can either write your code direct to the same script or as I'd suggest, create a new script and #Include the menu script ( as seen in the upcoming example ).

How to add new tabs

Each tab has a number of properties that are customizable by you.
You can set these properties and add a new tab like this, but you can also set the defaults for a number of the values directly in the menu code.

Code: Select all

obj := {}
obj.Position := 1
obj.Color := "0xFF00FF00" 
obj.Text := "Tab 1"
obj.FontType := "Segoe UI"
obj.FontSize := 16
obj.FontOptions := "Center vCenter Bold NoWrap Underline"
obj.FontColor := "0xFF000000"

POS_Control.AddNewTab( obj.Position , obj  )

You could also write the above shorthand and use the defaults like so

Code: Select all


POS_Control.AddNewTab( 1 , { Color: "0xFF00FF00" , Text: "Tab`n1"  } ) ;The 1 is the position to put the tab in the grid ( i.e. you can have gaps between tab buttons )

How to add new buttons

Adding new buttons is pretty much the same as adding a new tab, but when you add a new button you assign it a label to call when it is pressed and tell it which tab you want the new button to be related to.

Here is the longhand way to add a new button.

Code: Select all


obj := {}
obj.Tab := 1 										;The tab to assign this button to
obj.Position := 5									;The position to place this button in 
obj.Label := "TestLabel"								;The label to call when the button is pressed
obj.Color := "0xFF22262a" 								;The color of the button in hex ( alpha-red-green-blue / FF-FF-FF-FF )
obj.Text := "Button 5"								;The text to display on the button
obj.FontType := "Segoe UI" 							;The font type to use.
obj.FontColor := "0xFFFFFF"							;The color for the text
obj.FontSize := 18									;The size of the text
obj.FontOptions := "Center vCenter Bold NoWrap Underline"  	;The font options to use

POS_Control.AddNewButton( obj.Tab , obj.Position , obj )

and here is the shorthand.

Code: Select all


POS_Control.AddNewButton( 1 , 5 , { Color: "0xFF00FF00" , Text: "Tab`n1"  , Label: "TestLabel" })

How to show / hide the window

To show the menu you simply call the draw functions for the two windows like this.

Code: Select all

POS_Control.DrawTabWindow()		;Draw the tabs window
POS_Control.DrawButtonWindow()	;Draw the buttons window
To hide the menu you call the clearwindow function on the two windows like this.

Code: Select all

POS_Control.TabWindow.ClearWindow( 1 )		;Clear the tab window ( hide it )
POS_Control.ButtonWindow.ClearWindow( 1 )	;Clear the button window ( hide it )
How to toggle the menu

You can set up a simple hotkey to toggle the menu when you want.
Here it is with Shift + RButton to toggle.

Code: Select all

+RButton::
	if( !Tog := !Tog ){
		POS_Control.DrawTabWindow()
		POS_Control.DrawButtonWindow()
	}else{
		POS_Control.TabWindow.ClearWindow( 1 )
		POS_Control.ButtonWindow.ClearWindow( 1 )
	}
	return
This here is the code I used to create the menu in the first gif.

Code: Select all

;****************************************************************************************************************************************************************************
#Include gdip.ahk
#Include Menu Script.ahk
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
;**************************************************************************************************
;**************************************************************************************************

MyTabs := []
colors  := [ "A333AB" , "CF5410" , "96AEFE" , "A8497F" , "3FF668" , "2A1DE1" , "139190" , "DBCE1A" , "673B50" , "B47892" , "6381C2" , "1BDB6F" , "EFA30D" , "796CF5" , "48B1F3" , "D4B410" , "689E55" , "922032" , "A742F0" , "75F944" ]

Loop, 15	{
	MyTabs[ A_Index ] := {}
	MyTabs[ A_Index ].Position := A_Index
	MyTabs[ A_Index ].Color := "0xFF" colors[ Random( 1 , colors.Length() ) ]
	MyTabs[ A_Index ].Text := "Tab`n" A_Index
	MyTabs[ A_Index ].Fontsize := 18
	MyTabs[ A_Index ].Buttons := []
	index := A_Index 
	
	Loop, 50	{
		
		MyTabs[ index ].Buttons[ A_Index ] := {}
		MyTabs[ index ].Buttons[ A_Index ].Position := A_Index
		MyTabs[ index ].Buttons[ A_Index ].Color := "0xFF" colors[ Random( 1 , colors.Length() ) ]
		MyTabs[ index ].Buttons[ A_Index ].Text := "Tab: " index "`nButton: " A_Index
	}
}

;**************************************************************************************************
;**************************************************************************************************
Loop, % MyTabs.Length()	{
	POS_Control.AddNewTab( MyTabs[ A_Index ].Position , MyTabs[ A_Index ] )
	index := A_Index
	Loop, % MyTabs[ A_Index ].Buttons.Length(){
		POS_Control.AddNewButton( MyTabs[ index ].Position , MyTabs[ index ].Buttons[ A_Index ].Position , MyTabs[ index ].Buttons[ A_Index ] ) 
	}
}
;**************************************************************************************************
;**************************************************************************************************
POS_Control.DrawTabWindow()
POS_Control.DrawButtonWindow()
return
*Esc::ExitApp


+RButton::
	if( !Tog := !Tog ){
		POS_Control.DrawTabWindow()
		POS_Control.DrawButtonWindow()
	}else{
		POS_Control.TabWindow.ClearWindow( 1 )
		POS_Control.ButtonWindow.ClearWindow( 1 )
	}
	return

How to code your labels

When you press your buttons you are going to want something to happen. To make this so you will need to tell your button which label to call
for example: "TextLabel".
You can either have all buttons call the same label and then sort things out by using the tab and button info to direct the output, or you can have each button call up its own label.

This label when called shows the current tab and the button that was pressed.

Code: Select all

TestLabel:
	ToolTip, % "Tab: " POS_Control.TabSelectedTab "`nButton: "  POS_Control.ButtonActiveTab
	return
How to change the color of the menu

All the the colors used in the menu are customizable. To edit the colors you will need to go into the POS_Control class and find the Setup() function and find / change these values.

Code: Select all

;Tab window colors.
This.TabBackgroundColor := "0xFF62666a"
This.TabMoveAllButton_Color := "0xFF3399cc"
This.TabMoveButton_Color := This.TabMoveAllButton_Color
This.TabDisplayArea_Color := "0xfff0f0f0"
This.TabUPButton_Color := This.TabMoveAllButton_Color
This.TabDownButton_Color := This.TabMoveAllButton_Color
This.TabResizeButton_Color := "0xFFFFFF00"
This.TabControlBackgroundColor := "0xFF22262a"

;Button window colors
This.ButtonMoveAllButton_Color := "0xFF3377aa"
This.ButtonMoveButton_Color := This.ButtonMoveAllButton_Color
This.ButtonDisplayArea_Color := "0xFF22262a"
This.ButtonUPButton_Color := This.ButtonMoveAllButton_Color
This.ButtonDownButton_Color := This.ButtonMoveAllButton_Color
This.ButtonResizeButton_Color := "0xFFFFFF00"
This.ButtonControlBackgroundColor := "0xFF22262a"

How to change the tab and button size
You can change the size of the tabs and the buttons by using this code before you draw the window.

Code: Select all

POS_Control.TabWidth := 180
POS_Control.TabHeight := 60

POS_Control.ButtonWidth := 40
POS_Control.ButtonHeight := 40
You can make your tabs and buttons as big or as small as you want.


.

How to add icons

[/code]
tab menu 3.gif
tab menu 3.gif (895.34 KiB) Viewed 4133 times

.
You can add icons to the tabs and buttons by either passing a B64 string or a pBitmap when you add the control.

B64 example.

Code: Select all

QuickIcon60x60 := "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"

obj := {}
obj.Color := "0xFFFFFF00"
obj.Text := "1"
obj.B64 := QuickIcon60x60 

POS_Control.AddNewTab( 1 , obj  )


pBitmap example.

Code: Select all


obj := {}
obj.Color := "0xFFFFFF00"
obj.Text := "1"
obj.pBitmap := GDIP_CreateBitmapFromFile( pathToFile )

POS_Control.AddNewTab( 1 , obj  )

Last edited by Hellbent on 07 Dec 2022, 10:51, edited 2 times in total.

ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: Resizable Tab Menu / POS Overlay

Post by ozzii » 24 Oct 2022, 03:28

This is really impressive (at least for me ;) )

Kisang Kim
Posts: 12
Joined: 31 Jul 2019, 02:37

Re: Resizable Tab Menu / POS Overlay

Post by Kisang Kim » 25 Oct 2022, 00:00

Wanterful !!!!!
how I get button focused control?

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 25 Oct 2022, 03:21

Thanks @ozzii :beer:
Kisang Kim wrote:
25 Oct 2022, 00:00
Wanterful !!!!!
how I get button focused control?
You can get the selected tab and the selected button by looking at the value of the keys [ POS_Control.TabSelectedTab and POS_Control.ButtonActiveTab ]

In this example I have set the value of the Label to "TestLabel". When I click on the button with that label it will call up this code.
All this code does is show you in a tooltip which tab you are currently in and which button you pressed in that tab.

Code: Select all

TestLabel:
	ToolTip, % "Tab: " POS_Control.TabSelectedTab "`nButton: "  POS_Control.ButtonActiveTab
	return
I am also currently working on an editor version for this. It will require windows 8+ to run.

It also will require a function to convert any tabs and buttons added before the editor version to the new methods. Basically your old controls need to be saved to an .ini file.

I have only modified the script to allow editing of the tabs, but it is looking good so far.
tab menu 4.gif
tab menu 4.gif (853.58 KiB) Viewed 3989 times

User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Resizable Tab Menu / POS Overlay

Post by HiSoKa » 25 Oct 2022, 03:43

I am also currently working on an editor version for this. It will require windows 8+ to run.
wow good news, The GIF looks really cool,
waiting for new version :)

burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

Re: Resizable Tab Menu / POS Overlay

Post by burque505 » 25 Oct 2022, 08:02

@Hellbent, more work of genius. Amazing.
Regards,
burque505

User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Resizable Tab Menu / POS Overlay

Post by HiSoKa » 08 Nov 2022, 01:36

Does anyone know how I can add a button with gradient using HTML and CSS Instead of these buttons style in this code..
Please take a look at the link below,
Here is an example from a @teadrinker show me how to create buttons with gradient using html and css...
viewtopic.php?f=76&t=110230

Is it possible, or it require a modification to the entire code And it will be difficult?

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 09 Nov 2022, 06:28

HiSoKa wrote:
08 Nov 2022, 01:36
Does anyone know how I can add a button with gradient using HTML and CSS Instead of these buttons style in this code..
Please take a look at the link below,
Here is an example from a @teadrinker show me how to create buttons with gradient using html and css...
viewtopic.php?f=76&t=110230

Is it possible, or it require a modification to the entire code And it will be difficult?
You can just replace the brush used for the buttons.
20221109060351.png
20221109060351.png (9.66 KiB) Viewed 3718 times
You can also add more shapes and lines to add some detail.
20221109061120.png
20221109061120.png (10.3 KiB) Viewed 3718 times
Here are two different brushes you can try.

Code: Select all

;Brush type 1
Brush := Gdip_CreateLineBrush( x1 , y1 , x2 , y2 , "0x33F0F0F0" , "0x66000000" , 1 ) 
;Brush type 2
Brush := Gdip_CreateLineBrushFromRect( x , y , w , h , "0x33F0F0F0" , "0x66000000" , 1 , 1 ) 
To change the existing code you will need to replace the current drawing code for the buttons ( which looks like this )

Code: Select all

	Loop, % This.TabUnit_Height	{
			
			x := This.TabDisplayArea_X + This.TabMargin
			
			Loop, % This.TabUnit_Width	{
				
				if( IsObject( This.Tabs[ index ] ) ){
					
					if( This.Tabs[ index ].Haskey( "Icon" ) ){
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						This.TabWindow.DrawBitmap( This.Tabs[ index ].Icon , { X: x , Y: y , W: ( This.TabWidth <= This.TabHeight ) ? ( w := This.TabWidth ) : ( w := This.TabHeight ) , H: w } , 0 )
						DrawText( This.TabWindow.G , x + w - 1 , y - 2 , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColorBackground , This.TabWidth - w , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
						DrawText( This.TabWindow.G , x + w , y , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColor , This.TabWidth - w , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}else{
					
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						DrawText( This.TabWindow.G , x - 1 , y - 2  , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColorBackground , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
						DrawText( This.TabWindow.G , x , y , This.Tabs[ index ].text ,  This.Tabs[ index ].FontColor , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}
				}
				
				x += This.TabWidth + This.TabMargin
				index++
			
			}
			
			y += This.TabHeight + This.TabMargin
		
		}
All you need to do is replace the This.TabWindow.PaintBackground( lines with something like this.

Code: Select all

Brush := Gdip_CreateLineBrushFromRect( x , y , w , h , "0x33F0F0F0" , "0x66000000" , 1 , 1 ) 
, Gdip_FillRoundedRectangle( G , Brush , x , y , w , h , Roundness ) 
, Gdip_DeleteBrush( Brush )

User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Resizable Tab Menu / POS Overlay

Post by HiSoKa » 09 Nov 2022, 11:08

@Hellbent Beautiful style, I didn't know that GDIP included such things,, Thank you :)

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 09 Nov 2022, 14:08

HiSoKa wrote:
09 Nov 2022, 11:08
@Hellbent Beautiful style, I didn't know that GDIP included such things,, Thank you :)
You can use my bitmap maker to play around with the drawing functions. It is what I use for almost all of my prototyping.
Anything drawn in the editor can be saved as a .png image or as a function containing the code to recreate the drawing in a script.


You can do simple stuff like in this video




or more complex designs like this.
20220126034746.png
20220126034746.png (83.98 KiB) Viewed 3648 times

You can find a copy of the script somewhere here in the scripts and functions sub-forum.


This is an example of the code it generates.

This...

Code: Select all

HB_BITMAP_MAKER( ScaleFactor := 1 ){
	;Bitmap Created Using: HB Bitmap Maker
	pBitmap := Gdip_CreateBitmap( 300 * ScaleFactor , 300 * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , -3 * ScaleFactor , -4 * ScaleFactor , 380 * ScaleFactor , 390 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) , Gdip_FillRoundedRectangle( G , Brush , 2 * ScaleFactor , 7 * ScaleFactor , 295 * ScaleFactor , 288 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) , Gdip_FillPolygon( G , Brush , "150,0|250,100|50,100|" ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFDCDCDC" ) , Gdip_FillRoundedRectangle( G , Brush , 266 * ScaleFactor , 9 * ScaleFactor , 30 * ScaleFactor , 284 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFFFFFFF" ) , Gdip_FillRoundedRectangle( G , Brush , 268 * ScaleFactor , 11 * ScaleFactor , 26 * ScaleFactor , 71 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Pen := Gdip_CreatePen( "0xFF999999" , 3 ) , Gdip_DrawLine( G , Pen , 271 * ScaleFactor , 41 * ScaleFactor , 291 * ScaleFactor , 41 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Pen := Gdip_CreatePen( "0xFF999999" , 3 ) , Gdip_DrawLine( G , Pen , 271 * ScaleFactor , 46 * ScaleFactor , 291 * ScaleFactor , 46 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Pen := Gdip_CreatePen( "0xFF999999" , 3 ) , Gdip_DrawLine( G , Pen , 271 * ScaleFactor , 51 * ScaleFactor , 291 * ScaleFactor , 51 * ScaleFactor ) , Gdip_DeletePen( Pen )
	Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_FillRoundedRectangle( G , Brush , 4 * ScaleFactor , 9 * ScaleFactor , 260 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Comic Sans MS" , "s" 12 * ScaleFactor " Center vCenter  c" Brush " x" 4 * ScaleFactor " y" 10 * ScaleFactor  , "Segoe ui" , 260 * ScaleFactor , 20 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFE3E3E3" ) , Gdip_FillRoundedRectangle( G , Brush , 4 * ScaleFactor , 31 * ScaleFactor , 260 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Comic Sans MS" , "s" 12 * ScaleFactor " Center vCenter  c" Brush " x" 4 * ScaleFactor " y" 32 * ScaleFactor  , "Segoe ui" , 260 * ScaleFactor , 20 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFF0F0F0" ) , Gdip_FillRoundedRectangle( G , Brush , 4 * ScaleFactor , 53 * ScaleFactor , 260 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFFE3E3E3" ) , Gdip_FillRoundedRectangle( G , Brush , 4 * ScaleFactor , 75 * ScaleFactor , 260 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Comic Sans MS" , "s" 12 * ScaleFactor " Center vCenter  c" Brush " x" 4 * ScaleFactor " y" 54 * ScaleFactor  , "Segoe ui" , 260 * ScaleFactor , 20 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Comic Sans MS" , "s" 12 * ScaleFactor " Center vCenter  c" Brush " x" 4 * ScaleFactor " y" 76 * ScaleFactor  , "Segoe ui" , 260 * ScaleFactor , 20 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
	Gdip_DeleteGraphics( G )
	return pBitmap
}
Draws this...
20221109140742.png
20221109140742.png (8.75 KiB) Viewed 3648 times

doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Resizable Tab Menu / POS Overlay

Post by doubledave22 » 09 Nov 2022, 15:14

@Hellbent looks awesome!

Curious about how the resizing works. I wanted to experiment at some point with having a resizable layered window but didn't know the best way to handle re-painting. Looks like you are just tracking mouse position with a while loop. Could we also listen to something like WM_EXITSIZEMOVE and repaint after?

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 09 Nov 2022, 18:12

doubledave22 wrote:
09 Nov 2022, 15:14
@Hellbent looks awesome!

Curious about how the resizing works. I wanted to experiment at some point with having a resizable layered window but didn't know the best way to handle re-painting. Looks like you are just tracking mouse position with a while loop. Could we also listen to something like WM_EXITSIZEMOVE and repaint after?
I have only worked on two projects that use a resizable layered window so far so I'm still pretty novice at the whole subject, but I do have a few basic strategies worked out.

One strategy is to use 2-3 ( I like 3 ) layered windows in a parent - child - grandchild relationship. The parent window represents the title bar and border of the window, the child represents the visible client area of the window, and the grandchild is the actual client area of the window.
As you resize this window, you draw the few title bar elements and resize the child ( visible client area ) based on some margin and you leave the grandchild as is. This gives you the same effect as adding +Resize to a normal gui. *** Reqs Windows 8+ ***

I have only done one pass at this so far but it should give some insights.

viewtopic.php?f=6&t=3851&start=300#p431860
Image

Here it is used to create a game.

viewtopic.php?f=6&t=97490&hilit=Missile+Command
Image


Another strategy is to use a single layered window and to use a separate bitmap ( i.e DrawImage( pBitmap ) ) for the client area.
You make a large bitmap and then use the source params for positioning what is displayed. ( with scrollbars etc. )

Last there is what can be seen in this one where I just use simple math to draw a few items ( the POS menu ).




I vaguely recall trying to use the built in +Resize option to do the resizing but it was too buggy to use, so that means you won't be able to monitor something like WM_EXITSIZEMOVE. Also, unless you really have a lot that needs to be drawn, there's no reason to not draw the window as you are resizing it. If you really want to you can do something like creating a new layered window and just draw the outline of the new window size, or just clear the window and only draw the outline while resizing it.

Although you can't use the WM_EXITSIZEMOVE message, you can use the LButton Down and the LButton Up messages to do the resizing.
You just create an area that once you click in it, it sets a variable to a new value and then when the up message gets called you check to see if your variable has the value you are looking for and then do your calculations, redraw the window, and reset your variable again.

With all that said, this pretty much just gets you to the same starting place as a default gui, from which other resizing problems need to be addressed as with any other gui.

If you have a specific task in mind, you can fill me in on the details and I'll see if I can offer anything.

doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Resizable Tab Menu / POS Overlay

Post by doubledave22 » 11 Nov 2022, 10:37

Hellbent wrote:
09 Nov 2022, 18:12
With all that said, this pretty much just gets you to the same starting place as a default gui, from which other resizing problems need to be addressed as with any other gui.
If you have a specific task in mind, you can fill me in on the details and I'll see if I can offer anything.
Amazing stuff, thanks again as always. I will reach out if I have any questions. Your PopUpWindow Class has been invaluable to me.

doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Resizable Tab Menu / POS Overlay

Post by doubledave22 » 13 Nov 2022, 16:54

Hellbent wrote:
09 Nov 2022, 18:12
I vaguely recall trying to use the built in +Resize option to do the resizing but it was too buggy to use, so that means you won't be able to monitor something like WM_EXITSIZEMOVE. Also, unless you really have a lot that needs to be drawn, there's no reason to not draw the window as you are resizing it. If you really want to you can do something like creating a new layered window and just draw the outline of the new window size, or just clear the window and only draw the outline while resizing it.
Here's a version I came up with that successfully uses +resize for the layered window. Worth looking into if you are interested as it will allow a few benefits:

1) You won't need to use extra space in the GUI for the diagonal lines (although I dont mind the styles of those)

2) You can leverage +Minsize +Maxsize to set hard limits

3) You won't need any timers/mouse tracking as you can monitor WM_SIZING and WM_EXITSIZEMOVE to update the layered window

downsides:

1) +Resize seems to remove the benefits of -caption so you end up with a different client area to window area.

2) The mouse seems to get stuck every so often when resizing and requires a second click (no idea whats happening here)

Here's an example:

Code: Select all

#NoEnv  						; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%     ; Ensures a consistent starting directory.
SetBatchLines -1    			; have the script run at maximum speed and never sleep
setwindelay, 0					; makes the winmoves happen instantly
#SingleInstance, Force
OnExit, exitScript

#include Gdip_All.ahk 
#Include PopUpWindow.ahk

If !pToken := Gdip_Startup()
{
	MsgBox, 262192, Error, GDIP did not start properly
	ExitApp
}

vW := 225
vH := 425
TestGUI := New LWGUI("Title"
					, {opacity: 255, bgColor: "17181E", bgTrans: "FF", stroke: {thickness: 4, color: "282A34"}, rounding: 15, maxWidth: 500, maxHeight: 500, marginX: 25}
					, {X: 500, Y: 500, W: vW, H: vH}
					, "Click_Handler")
TestGUI.Create()
return

Esc::
exitScript:
TestGUI := ""
Gdip_Shutdown(pToken)
exitapp
return

Click_Handler(obj, Msg)
{
	;tooltip, % "msg: " msg
}

class LWGUI
{
	static DerivedObjects := {}, DerivedObjectsCount := 0
	, EventHandlerFunc := ObjBindMethod(LWGUI, "EventHandler")
	, MsgList := [LWGUI.WM_RBUTTONDOWN   := 0x204
				 ,LWGUI.WM_MOUSEMOVE     := 0x200
				 ,LWGUI.WM_LBUTTONUP 	 := 0x202
				 ,LWGUI.WM_SIZING 	 	 := 0x214
				 ,LWGUI.WM_EXITSIZEMOVE  := 0x232
				 ,LWGUI.WM_LBUTTONDOWN   := 0x201
				 ,LWGUI.WM_LBUTTONDBLCLK := 0x203]
	
	__New(Title, Styles, Positions, CallBack := "", Options := " -caption +Toolwindow -DPIScale +Resize  +AlwaysOnTop")
	{
		this.Title       := Title
		this.Styles      := Styles
		this.Positions   := Positions
		this.Created     := 0
		this.Hidden      := 0
		this.CallBack    := isfunc(CallBack) ? Callback : ""
		this.Options 	 := Options
		this.minWidth 	 := Styles.HasKey("minWidth")  ? Styles.minWidth  : 100
		this.minHeight	 := Styles.HasKey("minHeight") ? Styles.minHeight : 100
		this.maxWidth	 := Styles.HasKey("maxWidth")  ? Styles.maxWidth  : 9999
		this.maxHeight	 := Styles.HasKey("maxHeight") ? Styles.maxHeight : 9999
		this.Options 	 .= instr(this.Options, "+Resize") ? " +MinSize" this.minWidth "x" this.minHeight " +MaxSize" this.maxWidth "x" this.maxHeight : ""
		this.Components  := {}
	}
	
	Create()
	{
		if (this.Created)
			return

		this.Container := New PopUpWindow({ X: this.Positions.X
										  , Y: this.Positions.Y
										  , W: this.Positions.W
										  , H: this.Positions.H
										  , Options: this.Options})
	
		LWGUI.DerivedObjects[this.Container.hwnd] := &this
		this.EventListeners("On")
		this.ShowWindow()
		this.Created := 1
		this.Update_Container()
		this.Draw(0, 1)
	}
	
	Update_Container()
	{
		wingetpos, x, y, w, h, % "ahk_id " this.Container.hwnd
		this.Container.UpdateSettings({ X: x, Y: y, W: w , H: h}, (w > this.Container.W or h > this.Container.H))
	}

	Draw_Outline(Width, Height, Stroke_Color, Rounding, Stroke_Width, X := 0, Y := 0)
	{
		Use_Size := (Width > Height) ? Height : Width
		pPen := Gdip_CreatePen("0x" this.Styles.bgTrans . Stroke_Color, Stroke_Width)
		Offset := ceil(Stroke_Width/2)
		Gdip_DrawRoundedRectangle(this.Container.G, pPen, X + Offset, Y + Offset, Width - (Offset * 2), Height - (Offset * 2), Rounding)
		Gdip_DeletePen(pPen)
	}
	
	Draw(Clear := 1, AutoUpdate := 0)
	{
		if (Clear)
			this.Clear()
		
		wingetpos, , , W, H, % "ahk_id " this.Container.hwnd
		
		Stroke_Thickness := this.Styles.stroke.thickness ? this.Styles.stroke.thickness : 0
		
		if (this.Styles.haskey("bgColor"))
			this.Container.PaintBackground({ Color: "0x" this.Styles.bgTrans . this.Styles.bgColor
											, X: (Stroke_Thickness / 2)
											, Y: (Stroke_Thickness / 2)
											, W: W - Stroke_Thickness
											, H: H - Stroke_Thickness
											, Round: this.Styles.Rounding })

		if (this.Styles.haskey("Stroke"))
			this.Draw_Outline(W, H, this.Styles.stroke.haskey("color") ? this.Styles.stroke.color : "000000", this.Styles.Rounding, this.Styles.stroke.thickness, 0, 0)

		if (AutoUpdate)
			this.Show()
	}
	
	Clear(AutoUpdate := 0)
	{
		Gdip_GraphicsClear(this.Container.G)
		
		if (AutoUpdate)
			this.Show()
	}
	
	Hide()
	{
		this.Hidden := 1
		this.Update(0)
	}
	
	Show()
	{
		if (!this.Created or this.Hidden)
			return

		this.Update(this.Styles.Opacity)
	}
	
	ShowWindow()
	{
		gui, % This.Container.Hwnd ":Show", % "x" this.Positions.X " y" this.Positions.Y " w" this.Positions.W " h" this.Positions.H, % this.Title
	}
	
	Update(Opacity)
	{
		this.Container.UpdateWindow(Opacity)
	}

	EventListeners(OnorOff := "On")
	{
		if (OnorOff = "On")
		{
			LWGUI.DerivedObjectsCount += 1
			LWGUI.DerivedObjects[this.Container.hwnd] := &this
			if (LWGUI.DerivedObjectsCount = 1)
			{
				for k, msg in LWGUI.MsgList
					OnMessage(msg, this.EventHandlerFunc)
			}
		}
		else
		{
			; make sure the layered window was created
			; this can get called on initialized but not created instances
			if (!this.Container.hwnd)
				return

			LWGUI.DerivedObjectsCount -= 1
			LWGUI.DerivedObjects.Delete(this.Container.hwnd)
			if (LWGUI.DerivedObjectsCount = 0)
			{
				for k, msg in LWGUI.MsgList
					OnMessage(msg, this.EventHandlerFunc, 0)
			}
		}
	}
	
	EventHandler(wParam, lParam, msg, hwnd)
	{
		if (!LWGUI.DerivedObjects.HasKey(A_Gui))
			return

		obj := Object(LWGUI.DerivedObjects[A_Gui])
		
		;=========== Resize Handling ===========;
		if (msg = LWGUI.WM_EXITSIZEMOVE or msg = LWGUI.WM_SIZING)
		{
			obj.Update_Container()
			obj.Draw(1, 1)
			obj.Update_All_Components()
			return
		}
			
		;=========== Left-Click handling ===========;
		if (msg = LWGUI.WM_LBUTTONDOWN 
		 or msg = LWGUI.WM_LBUTTONDBLCLK)
		{
			;============ Find Start Point =============;
			coordmode, mouse, relative
			mousegetpos, rmX, rmY
		
			hwnd := obj.Container.hwnd
			coordmode, mouse, screen
			;=============== Move freely ==============;
			while GetKeyState("LButton","P")
			{
				mousegetpos, mX, mY
				winmove, % "ahk_id " hwnd, , mX - rmX, mY - rmY
				sleep 10
			}
			obj.Update_Container()
			return
		}
		
		;============ G-Label handling =============
		if (msg = LWGUI.WM_LBUTTONUP)
		{
			if (obj.CallBack)
			{
				rmX := lParam & 0xFFFF
				rmY := lParam >> 16
				Call_Fn := func(obj.CallBack).bind(obj, msg)
				settimer, % Call_Fn, -1
			}
			return
		}
		
		;========== Right-Click handling ===========
		if (msg = LWGUI.WM_RBUTTONDOWN)
		{
			;============ Find Start Point =============;
			rmX := lParam & 0xFFFF
			rmY := lParam >> 16
			
			hwnd := obj.Container.hwnd

			if (obj.CallBack)
			{
				Call_Fn := func(obj.CallBack).bind(obj, msg)
				settimer, % Call_Fn, -1
			}
			return
		}
	}
	
	_WinGetClientPos(hwnd)
	{
		;https://www.autohotkey.com/boards/viewtopic.php?f=6&t=484
		VarSetCapacity( size, 16, 0 )
		DllCall( "GetClientRect", UInt, hwnd, Ptr, &size )
		DllCall( "ClientToScreen", UInt, hwnd, Ptr, &size )
		x := NumGet(size, 0, "Int")
		y := NumGet(size, 4, "Int")
		w := NumGet( size, 8, "Int" )
		h := NumGet( size, 12, "Int" )
		return { X: x, Y: y, W: w, H: h }
	}
	
	Destroy()
	{
		this.Components := ""
		LWGUI.DerivedObjects.Delete(this.Container.hwnd)
		this.EventListeners("Off")
		this.Container := ""
		this.Created := 0
	}
	
	__Delete()
	{
		this.Destroy()
		FileAppend, % "LWGUI delete was called: " this.Title "`n", *
	}
}

Attachments
959b12aa32fa7ee520f7b02995e4446d.gif
959b12aa32fa7ee520f7b02995e4446d.gif (413.28 KiB) Viewed 3471 times

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 07 Dec 2022, 08:41

@doubledave22 that looks great, I wonder what is was that I found buggy about it? You wouldn't happen to have a more elaborate example do you? I noticed that your example has a few methods missing.

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 07 Dec 2022, 10:01

Tab Menu V2 (Live edit)
Requires Windows 8+

Code: Select all


;****************************************************************************************************************************************************************************
#Include,  gdip.ahk
;****************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
#NoEnv
;**************************************************************************************************
;**************************************************************************************************
POS_Control.TabWidth := 280
POS_Control.TabHeight := 60
POS_Control.ButtonWidth := 300
POS_Control.ButtonHeight := 80
POS_Control.DrawTabWindow()
POS_Control.DrawButtonWindow()
;**************************************************************************************************
;**************************************************************************************************


;************************************************
;************************************************
;Added Dec 19th 2022
;Constantly set the window on top 
SetTimer, OnTop, 5000
;************************************************
;************************************************




return

;~ *Esc::ExitApp

+RButton::
GuiContextMenu:
	if( WinActive( "ahk_id " POS_Control.EditorWindow.Hwnd ) ){
		POS_Control.EditorWindow.DeleteWindow()
		return
	}
	if( !Tog := !Tog ){
		POS_Control.DrawTabWindow()
		POS_Control.DrawButtonWindow()
	}else{
		POS_Control.TabWindow.ClearWindow( 1 )
		POS_Control.ButtonWindow.ClearWindow( 1 )
	}
	return

;***********************************************
;***********************************************
;Added Dec 19th 2022
;Constantly set the window on top 
OnTop:
	Gui, % POS_Control.TabWindow.Hwnd ":Show" , NA
	Gui, % POS_Control.ButtonWindow.Hwnd ":Show" , NA
	return
;***********************************************
;***********************************************



;)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(;
;)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(;

TestLabel:
	out := SubStr( Clipboard , 1 , 1000 )
	ToolTip, % "Tab: " POS_Control.TabSelectedTab "`nButton: " POS_Control.ButtonActiveTab "`nClipboard: " out
	Sleep, 2000
	ToolTip
	return


TestLabel2_Sound:
	ToolTip, % "Tab: " POS_Control.TabSelectedTab "`nButton: " POS_Control.ButtonActiveTab
	SoundBeep
	sleep, 2000
	ToolTip,
	return
;)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(;
;)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(  User Space  )&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&(;


class MenuEditor	{
	/*
	[ SavedColors ]
	1=FED855
	2=43DDE9
	3=2765A1
	4=298CEC
	5=9C2999
	6=6CFF5D
	7=55FF80
	*/
	NewEditWindow( Type := "Tab" , Mode := "New" ){
		local h , x, y , bd , cc , k , v
		if( Type = "Tab" )
			h := 250
		else
			h := 380
		if( WinExist( "ahk_id " This.EditorWindow.Hwnd ) ){
			This.EditorWindow.DeleteWindow()
		}
		;***Changed Oct 11th, 2023 ( keeps the edit window on top)
		;This.EditorWindow := New PopUpWindow( { AutoShow: 1 , X: "Center" , Y: "Center" , W: 650 , H: h , Options: " +AlwaysOnTop -DPIScale +Owner" This[ Type "Window" ].Hwnd } ) 
		This.EditorWindow := New PopUpWindow( { AutoShow: 1 , X: "Center" , Y: "Center" , W: 650 , H: h , Options: " +AlwaysOnTop -DPIScale +Owner" This[ "ButtonWindow" ].Hwnd } )
		This.EditorWindow.Type := Type
		This.EditorWindow.Mode := Mode
		This.EditorWindow.Buttons := {}
		This.EditorWindow.ButtonHandles := []
		This.EditorWindow.Edits := {}
		This.EditorWindow.EditHandles := []
		This.EditorWindow.Defaults := {}
		This.EditorWindow.Outputs := {}
		if( Mode = "New" ){
			This.EditorWindow.Defaults.Color := "009999"
			This.EditorWindow.Defaults.Text := "Button"
			This.EditorWindow.Defaults.FontType := "Segoe UI"
			This.EditorWindow.Defaults.FontSize := "22"
			This.EditorWindow.Defaults.FontOptions := "Center vCenter Bold"
			This.EditorWindow.Defaults.FontColor := "000000"
			This.EditorWindow.Defaults.FontColorBackground := "FFFFFF"
			This.EditorWindow.Defaults.B64 := ""
			This.EditorWindow.Defaults.pBitmap := ""
			This.EditorWindow.Defaults.ImagePath := ""
			if( Type = "Tab" ){
				This.EditorWindow.Defaults.Position := ""
			}else{
				This.EditorWindow.Defaults.Tab := ""
				This.EditorWindow.Defaults.Position := ""
				This.EditorWindow.Defaults.Label := ""
				This.EditorWindow.Defaults.RunPath := ""
				This.EditorWindow.Defaults.ClipString := ""
			}
			for k , v in This.EditorWindow.Defaults
				This.EditorWindow.Outputs[ k ] := This.EditorWindow.Defaults[ k ]
		}else{
			This.EditorWindow.Defaults.Color := "009999"
			This.EditorWindow.Defaults.Text := "Button"
			This.EditorWindow.Defaults.FontType := "Segoe UI"
			This.EditorWindow.Defaults.FontSize := "22"
			This.EditorWindow.Defaults.FontOptions := "Center vCenter Bold"
			This.EditorWindow.Defaults.FontColor := "000000"
			This.EditorWindow.Defaults.FontColorBackground := "FFFFFF"
			This.EditorWindow.Defaults.B64 := ""
			This.EditorWindow.Defaults.pBitmap := ""
			This.EditorWindow.Defaults.ImagePath := ""
			This.EditorWindow.Defaults.Position := ""
			if( type = "Tab" ){
				for k , v in This.EditorWindow.Defaults
					This.EditorWindow.Outputs[ k ] := This.EditorWindow.Defaults[ k ]
				for k , v in POS_Control.Tabs[ POS_Control.TabSelectedTab ]	
					This.EditorWindow.Outputs[ k ] := POS_Control.Tabs[ POS_Control.TabSelectedTab ][ k ]
			}else{
				This.EditorWindow.Defaults.Label := ""
				This.EditorWindow.Defaults.RunPath := ""
				This.EditorWindow.Defaults.ClipString := ""
				for k , v in This.EditorWindow.Defaults	{
					This.EditorWindow.Outputs[ k ] := This.EditorWindow.Defaults[ k ]
				}
				for k , v in POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ]	{
					This.EditorWindow.Outputs[ k ] := POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ][ k ]
				}
				This.EditorWindow.Outputs.Position := POS_Control.TargetedButton
			}
		
		}
		;*********************************************************************
		;*********************************************************************
		;Buttons
		This.EditorWindow.Buttons.MoveWindowButton := { X: 10 , Y: 10 , W: 250 , H: 20 , Hwnd: "" , Method: "_MoveEditorWindow" }
		This.EditorWindow.Buttons.SubmitButton := { X: 477 , Y: 8 , W: 76 , H: 26 , Hwnd: "" , Method: "_Submit" }
		This.EditorWindow.Buttons.CancelButton := { X: 557 , Y: 8 , W: 76 , H: 26 , Hwnd: "" , Method: "_Cancel" }
		This.EditorWindow.Buttons.GetButtonColorButton := { X: 274 , Y: 50 , W: 46 , H: 30 , Hwnd: "" , Method: "_SetColors" , BindHwnd: 1 , value: "ButtonColorEdit" }
		This.EditorWindow.Buttons.GetFontColorButton := { X: 474 , Y: 50 , W: 46 , H: 30 , Hwnd: "" , Method: "_SetColors" , BindHwnd: 1 , value: "FontColorEdit" }
		This.EditorWindow.Buttons.GetFontBackgroundColorButton := { X: 168 , Y: 100 , W: 46 , H: 30 , Hwnd: "" , Method: "_SetColors" , BindHwnd: 1 , value: "FontColorBackgroundEdit" }
		This.EditorWindow.Buttons.GetImagePathButton := { X: 585 , Y: 200 , W: 46 , H: 30 , Hwnd: "" , Method: "_SetImagePath" }
		if( Type = "Button" )
			This.EditorWindow.Buttons.GetRunPathButton := { X: 585 , Y: 270 , W: 46 , H: 30 , Hwnd: "" , Method: "_GetRunPath" }
		for k , v in This.EditorWindow.Buttons	{
			cc := This.EditorWindow.Buttons[ k ]
			Gui, % This.EditorWindow.Hwnd ":Add", Text, % "x" cc.x " y" cc.y " w" cc.w " h" cc.h " hwndhwnd "
			cc.Hwnd := hwnd
			This.EditorWindow.ButtonHandles[ hwnd ] := k
			if( cc.BindHwnd )
				bd := This[ cc.Method ].Bind( This , hwnd )
			else
				bd := This[ cc.Method ].Bind( This )
			GuiControl , % This.EditorWindow.Hwnd ": +G" , % hwnd , % bd
		}
		;*********************************************************************
		;*********************************************************************
		This.EditorWindow.SavedColorButtons := []
		This.ColorHandles := []
		x := 273 
		Loop, 7	{
			cc := This.EditorWindow.SavedColorButtons[ A_Index ] := { X: x , Y: 9 , W: 24 , H: 24 }
			x += 26
			Gui, % This.EditorWindow.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
			This.ColorHandles[ hwnd ] := A_Index
			bd := This._SetSavedColor.Bind( This , hwnd )
			GuiControl, % This.EditorWindow.Hwnd ":+G" , % hwnd , % bd
			IniRead, output , % A_ScriptFullPath , SavedColors , % A_Index
			cc.Color := output 
		}
		;*********************************************************************
		;*********************************************************************
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		;*********************************************************************
		;*********************************************************************
		;Edit controls
		This.EditorWindow.Edits.ButtonColorEdit := { X: 184 + 5 , Y: 50 + 5 , W: 86 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "Color" }
		This.EditorWindow.Edits.FontColorBackgroundEdit := { X: 78 + 5 , Y: 100 + 5 , W: 86 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FontColorBackground" }
		This.EditorWindow.Edits.FontColorEdit := { X: 384 + 5 , Y: 50 + 5 , W: 86 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FontColor" }
		This.EditorWindow.Edits.PositionEdit := { X: 80 + 5 , Y: 50 + 5 , W: 40 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "Position" }
		This.EditorWindow.Edits.FontSizeEdit := { X: 579 + 5 , Y: 50 + 5 , W: 51 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FontSize" }
		This.EditorWindow.Edits.FontOptionsEdit := { X: 293 + 5 , Y: 100 + 5 , W: 337 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FontOptions" }
		This.EditorWindow.Edits.TextEdit := { X: 247 + 5 , Y: 150 + 5 , W: 384 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "Text" }
		This.EditorWindow.Edits.FontTypeEdit := { X: 65 + 5 , Y: 150 + 5 , W: 126 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FontType" }
		This.EditorWindow.Edits.B64Edit := { X: 65 + 5 , Y: 200 + 5 , W: 246 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "B64" }
		This.EditorWindow.Edits.FilePathEdit := { X: 375 + 5 , Y: 200 + 5 , W: 206 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "FilePath" }
		if( Type = "Button" ){
			This.EditorWindow.Edits.RunPathEdit := { X: 65 + 5 , Y: 270 + 5 , W: 516 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "RunPath" }
			This.EditorWindow.Edits.ClipStringEdit := { X: 65 + 5 , Y: 320 + 5 , W: 336 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "ClipString" }
			This.EditorWindow.Edits.LabelEdit := { X: 475 + 5 , Y: 320 + 5 , W: 156 - 9 , H: 30 - 9 , hwnd: "" , WinHwnd: "" , Value: "Label" }
		}
		for k , v in This.EditorWindow.Edits	{
			cc := This.EditorWindow.Edits[ k ]
			Gui, New, % " -Caption -DPIScale +E0x02000000 +E0x00080000 +Parent" This.EditorWindow.Hwnd " hwndhwnd"
			cc.WinHwnd := hwnd
			Gui, Color,, 22262a
			fs := 10 / ( A_ScreenDPI / 96 )
			Gui, Font, % "s" fs "cFFFF00" ,Segoe UI
			if( k = "PositionEdit" && Mode = "Edit" )
				Gui, Add, Edit, % "x0 y0 w" cc.W " h" cc.H " hwndhwnd -E0x200 Center Disabled" , % This.EditorWindow.Outputs[ cc.Value ]
			else if( k = "ClipStringEdit" )
				Gui, Add, Edit, % "x0 y0 w" cc.W " r2 hwndhwnd -E0x200 Center " , % This.EditorWindow.Outputs[ cc.Value ]	
			else	
				Gui, Add, Edit, % "x0 y0 w" cc.W " h" cc.H " hwndhwnd -E0x200 Center" , % This.EditorWindow.Outputs[ cc.Value ]
			cc.Hwnd := hwnd
			This.EditorWindow.EditHandles[ hwnd ] := k
			Gui, Show, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H
			bd := This._UpdateEdits.Bind( This , hwnd )
			GuiControl, % cc.WinHwnd ":+G" , % hwnd , % bd
		}
	}
	_GetRunPath(){
		local tempCB := ClipboardAll
		Clipboard := ""
		if( This.EditorWindow.Busy )
			return
		This.EditorWindow.Busy := 1
		This.EditorWindow.Buttons.GetRunPathButton.Pressed := 1
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		While( !GetKeyState( "Ctrl" ) ){
			ToolTip, select a file or highlight a url and then press "ctrl"
			Sleep, 30
		}
		ToolTip,
		Send, ^c
		clipwait,
		This.EditorWindow.Outputs.RunPath := Clipboard
		GuiControl, % This.EditorWindow.Edits.RunPathEdit.WinHwnd ":" , % This.EditorWindow.Edits.RunPathEdit.Hwnd , % This.EditorWindow.Outputs.RunPath
		This.EditorWindow.Buttons.GetRunPathButton.Pressed := 0
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		Clipboard := tempCB
		This.EditorWindow.Busy := 0
	}
	_Submit(){
		if( This.EditorWindow.Busy )
			return
		This.EditorWindow.Busy := 1
		This.EditorWindow.Buttons.SubmitButton.Pressed := 1
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		While( GetKeyState( "LButton" , "P" ) )
			Sleep, 30
		This.EditorWindow.Buttons.SubmitButton.Pressed := 0
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		cc := This.EditorWindow.Outputs
		tObj := {}
		temp := ""
		for k , v in cc	{
			if( k = "FilePath" ){
					tObj[ "FilePath" ] := cc[ "FilePath" ]
					tObj[ "pBitmap" ] := Gdip_CreateBitmapFromFile( cc[ k ] )
					temp := tObj[ "pBitmap" ]
			}else if( k = "B64" ){
				if( pos := inStr( cc[ k ] , """" ) ){
					tObj[ k ] := SubStr( cc[ k ] , pos + 1 , strLen( cc[ k ] ) - pos - 1 )
				}else{
					tObj[ k ] := cc[ k ]
				}
			}else{
				tObj[ k ] := cc[ k ]
			}
		}
		if( temp ){
			tObj[ "pBitmap" ] := temp
		}
		;******************************************************************************
		;******************************************************************************
		if( This.EditorWindow.Type = "Tab" ){
			if( This.EditorWindow.Mode = "New" ){
				if( This.EditorWindow.Outputs.Position )
					POS_Control.AddNewTab( This.EditorWindow.Outputs.Position , tObj )
				else
					POS_Control.AddNewTab( "" , tObj )
				POS_Control.TabWindow.ClearWindow()
				POS_Control.ButtonWindow.ClearWindow()
				POS_Control.DrawTabWindow()
				POS_Control.DrawButtonWindow()
				This.EditorWindow.DeleteWindow()
				for k , v in tObj	{
					if( k = "Position" && !v ){
						v := This.Tabs.MaxIndex()
						if( !v )
							v := 1
					}else if( k = "pBitmap"  ){
						continue
					}
					IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" This.Tabs.Length() , % k
				}
				IniWrite, % This.Tabs.Length() , % A_ScriptDir "\Tab Menu Data.ini" , % "TotalTabs" , % "Count"
				This.EditorWindow.Busy := 0
			}else{
				This.EditorWindow.DeleteWindow()
				for k , v in tObj	{
					if( k = "Position" && !v ){
						v := POS_Control.Tabs[ POS_Control.TabSelectedTab ][ "Position" ]	
					}else if( k = "pBitmap"  && v != "" ){
						POS_Control.Tabs[ POS_Control.TabSelectedTab ][ "Icon" ] := v
						continue
					}else if( k = "B64" ){
						POS_Control.Tabs[ POS_Control.TabSelectedTab ][ "Icon" ] := POS_Control.B64ToPBitmap( v )
						POS_Control.Tabs[ POS_Control.TabSelectedTab ][ "B64" ] := v
						IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" POS_Control.TabSelectedTab , % k
						SoundBeep
						continue
					}
					
					POS_Control.Tabs[ POS_Control.TabSelectedTab ][ k ] := v
					IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" POS_Control.TabSelectedTab , % k
				}
				if( POS_Control.Tabs[ POS_Control.TabSelectedTab ].HasKey( "Icon" ) && POS_Control.Tabs[ POS_Control.TabSelectedTab ][ "Icon" ] = "" ){
					POS_Control.Tabs[ POS_Control.TabSelectedTab ].Remove( "Icon" )
					SoundBeep
				}
				POS_Control.TabWindow.ClearWindow()
				POS_Control.ButtonWindow.ClearWindow()
				POS_Control.DrawTabWindow()
				POS_Control.DrawButtonWindow()
				This.EditorWindow.Busy := 0
			}
		;******************************************************************************
		;******************************************************************************	
		}else{
			if( This.EditorWindow.Mode = "New" ){
				if( This.EditorWindow.Outputs.Position )
					POS_Control.AddNewButton( POS_Control.TabSelectedTab , This.EditorWindow.Outputs.Position , tObj )
				else
					POS_Control.AddNewButton( POS_Control.TabSelectedTab , "" , tObj )
				POS_Control.TabWindow.ClearWindow()
				POS_Control.ButtonWindow.ClearWindow()
				POS_Control.DrawTabWindow()
				POS_Control.DrawButtonWindow()
				This.EditorWindow.DeleteWindow()
				for k , v in tObj	{
					if( k = "Position" && !v ){
						v := This.Tabs[ This.TabSelectedTab ].Buttons.MaxIndex() 
						if( !v )
							v := 1
					}else if( k = "pBitmap"  )
						continue
					else if( k = "ClipString" ){
						v := StrReplace( v , "`n" , "?" )
					}
					IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" This.TabSelectedTab "_Button_" This.Tabs[ This.TabSelectedTab ].Buttons.Length() , % k
				}
				IniWrite, % This.Tabs[ This.TabSelectedTab ].Buttons.Length() , % A_ScriptDir "\Tab Menu Data.ini" , % "Total_Buttons_Tab_" This.TabSelectedTab , % "Count"
				This.EditorWindow.Busy := 0
			}else{
				This.EditorWindow.DeleteWindow()
				tObj.Position := POS_Control.TargetedButton
				for k , v in tObj	{
					if( k = "Position" && !v ){
						v := POS_Control.TargetedButton
					}else if( k = "pBitmap"  && v != "" ){
						POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ][ "Icon" ] := v
						continue
					}else if( k = "B64" ){
						POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ][ "Icon" ] := POS_Control.B64ToPBitmap( v )
						IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" POS_Control.TabSelectedTab "_Button_" POS_Control.TargetedButton , % k
						SoundBeep
						continue
					}
					POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ][ k ] := v
					if( k = "ClipString" )
						v := StrReplace( v , "`n" , "?" )
					IniWrite, % v , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" POS_Control.TabSelectedTab "_Button_" POS_Control.TargetedButton , % k
				}
				if( POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ].HasKey( "Icon" ) && !POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ][ "Icon" ] )
					POS_Control.Tabs[ POS_Control.TabSelectedTab ].Buttons[ POS_Control.TargetedButton ].Remove( "Icon" )
				POS_Control.TabWindow.ClearWindow()
				POS_Control.ButtonWindow.ClearWindow()
				POS_Control.DrawTabWindow()
				POS_Control.DrawButtonWindow()
				This.EditorWindow.Busy := 0
			}
		}
	}
	_Cancel(){
		POS_Control.TabWindow.ClearWindow()
		POS_Control.ButtonWindow.ClearWindow()
		POS_Control.DrawTabWindow()
		POS_Control.DrawButtonWindow()
		This.EditorWindow.DeleteWindow()
	}
	_SetColors( hwnd ){
		local color 
		This.EditorWindow.Buttons[ This.EditorWindow.ButtonHandles[ hwnd ] ].Pressed := 1
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		color := This._GetColor()
		GuiControl, % This.EditorWindow.Edits[ This.EditorWindow.Buttons[ This.EditorWindow.ButtonHandles[ hwnd ] ].Value ].WinHwnd ":", % This.EditorWindow.Edits[ This.EditorWindow.Buttons[ This.EditorWindow.ButtonHandles[ hwnd ] ].Value ].Hwnd , % color
		This.EditorWindow.Outputs[ This.EditorWindow.Edits[ This.EditorWindow.Buttons[ This.EditorWindow.ButtonHandles[ hwnd ] ].Value ].Value ] := color
		This.EditorWindow.Buttons[ This.EditorWindow.ButtonHandles[ hwnd ] ].Pressed := 0
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		This.EditorWindow.Busy := 0
	}
	_GetColor(){
		local ColorDisplayWindow , cc
		if( This.EditorWindow.Busy )
			return
		This.EditorWindow.Busy := 1
		ColorDisplayWindow := New PopUpWindow( { AutoShow: 1 , X: "Center" , Y: "Center" , W: 50 , H: 50 , Options: " +AlwaysOnTop -DPIScale +ToolWindow +Owner" This[ This.EditorWindow.Type "Window" ].Hwnd } )
		CoordMode, Mouse, Screen
		CoordMode, Pixel, Screen
		CoordMode, ToolTip, Screen
		While( !GetKeyState( "ctrl" ) ){
			MouseGetPos, x , y 
			PixelGetColor, outColor , x , y , RGB
			ToolTip, PRESS "Ctrl" to Capture, % x + 55 , % y + 30
			outColor := SubStr( outColor , 3 )
			ColorDisplayWindow.UpdateSettings( { X: x + 50 , Y: y - ColorDisplayWindow.H / 2 } )
			ColorDisplayWindow.ClearWindow()
			ColorDisplayWindow.PaintBackground( { Color: "0xFF000000" , X: 2  , Y: 2  , W: ColorDisplayWindow.W - 4 , H: ColorDisplayWindow.H - 4 , Round: 10 } , AutoUpdate := 0 ) ;{ Color: "0xFF000000" , X: 2 , Y: 2 , W: ColorDisplayWindow.W - 4 , H: ColorDisplayWindow.H - 4 , Round: 10 }
			ColorDisplayWindow.PaintBackground( { Color: "0xFF" outColor , X: 6  , Y: 6  , W: ColorDisplayWindow.W - 12 , H: ColorDisplayWindow.H - 12 , Round: 5 } , AutoUpdate := 0 ) ;{ Color: "0xFF000000" , X: 2 , Y: 2 , W: ColorDisplayWindow.W - 4 , H: ColorDisplayWindow.H - 4 , Round: 10 }
			ColorDisplayWindow.UpdateWindow()
		}
		ToolTip,
		ColorDisplayWindow.DeleteWindow()
		return outColor
	}
	_SetImagePath(){
		if( This.EditorWindow.Busy )
			return
		This.EditorWindow.Busy := 1
		This.EditorWindow.Buttons.GetImagePathButton.Pressed := 1
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		Gui, % This.EditorWindow.Hwnd ": +OwnDialogs "
		FileSelectFile, outFile 
		if( outFile )
			This.EditorWindow.Outputs.FilePath := outFile
		GuiControl, % This.EditorWindow.Edits.FilePathEdit.WinHwnd ":" , % This.EditorWindow.Edits.FilePathEdit.Hwnd , % This.EditorWindow.Outputs.FilePath
		This.EditorWindow.Buttons.GetImagePathButton.Pressed := 0
		This.EditorWindow.ClearWindow()
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		This.EditorWindow.Busy := 0
	}
	_UpdateEdits( hwnd ){
		if( This.EditorWindow.Busy )
			return
		This.EditorWindow.Busy := 1
		cc := This.EditorWindow.EditHandles[ hwnd ]
		GuiControlGet, out , % This.EditorWindow.Edits[ cc ].WinHwnd ":" , % Hwnd
		for k , v in [ "ButtonColorEdit" , "FontColorEdit" , "FontColorBackgroundEdit" ]	{
			if( cc = v ){
				if( strLen( out ) = 6 ){
					This.EditorWindow.Outputs[ This.EditorWindow.Edits[ cc ].Value ] := out
					This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
					This.EditorWindow.Busy := 0
					return
				}
			}
		}
		This.EditorWindow.Outputs[ This.EditorWindow.Edits[ cc ].Value ] := out
		This.EditorWindow.Busy := 0
	}
	_SetSavedColor( hwnd ){
		local color := This._GetColor()
		This.EditorWindow.SavedColorButtons[ This.ColorHandles[ hwnd ] ].Color := color
		IniWrite, % color , % A_ScriptFullPath , SavedColors , % This.ColorHandles[ hwnd ]
		This.EditorWindow.DrawBitmap( This.EditorBitmap() , { X: 0 , Y: 0 , W: This.EditorWindow.W , H: This.EditorWindow.H } , dispose := 1 , AutoUpdate := 1 )
		This.EditorWindow.ShowWindow()
		This.EditorWindow.Busy := 0
	}
	_MoveEditorWindow(){
		local x , y 
		PostMessage, 0xA1, 2
		While( GetKeyState( "LButton" , "P" ) )
			Sleep 30			
		WinGetPos, x, y ,,, % "ahk_Id " This.EditorWindow.Hwnd
		This.EditorWindow.UpdateSettings( { X: x , Y: y } )
	}
	EditorBitmap( ScaleFactor := 1 ){
		;Bitmap Created Using: HB Bitmap Maker
		pBitmap := Gdip_CreateBitmap( 650 * ScaleFactor , This.EditorWindow.H * ScaleFactor ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
		Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRoundedRectangle( G , Brush , 1 * ScaleFactor , 2 * ScaleFactor , 646 * ScaleFactor , 371 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 3 * ScaleFactor , 3 * ScaleFactor , 649 * ScaleFactor , 189 * ScaleFactor , "0xFF777777" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 1 * ScaleFactor , 2 * ScaleFactor , 646 * ScaleFactor , 371 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_BrushCreateSolid( "0xFF004444" ) , Gdip_FillRoundedRectangle( G , Brush , 10 * ScaleFactor , 10 * ScaleFactor , 250 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFFacacac" ) , Gdip_TextToGraphics( G , "|||     New " This.EditorWindow.Type "    |||" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 51 * ScaleFactor " y" -5 * ScaleFactor  , "Segoe ui" , 160 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF444444" ) , Gdip_FillRoundedRectangle( G , Brush , 10 * ScaleFactor , 40 * ScaleFactor , 630 * ScaleFactor , 205 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 12 * ScaleFactor , 42 * ScaleFactor , 629 * ScaleFactor , 75 * ScaleFactor , "0xFF009999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 10 * ScaleFactor , 40 * ScaleFactor , 630 * ScaleFactor , 205 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		;*******************************************************
		;tab position
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 15 * ScaleFactor , 45 * ScaleFactor , 110 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Button Position" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 70 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 80 * ScaleFactor , 50 * ScaleFactor , 40 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;tab color
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 135 * ScaleFactor , 45 * ScaleFactor , 190 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Button Color" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 135 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 184 * ScaleFactor , 50 * ScaleFactor , 86 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 274 * ScaleFactor , 50 * ScaleFactor , 46 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( !This.EditorWindow.Buttons.GetButtonColorButton.Pressed ) ? ( "0xFF" This.EditorWindow.Outputs.Color ) : ( "0xFF33FFFF" ) ) , Gdip_FillRoundedRectangle( G , Brush , 277 * ScaleFactor , 53 * ScaleFactor , 40 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Get" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 272 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 280 * ScaleFactor , 74 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 280 * ScaleFactor , 56 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;tab Font color
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 335 * ScaleFactor , 45 * ScaleFactor , 190 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Font Color" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 335 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 384 * ScaleFactor , 50 * ScaleFactor , 86 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 474 * ScaleFactor , 50 * ScaleFactor , 46 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( !This.EditorWindow.Buttons.GetFontColorButton.Pressed ) ? ( "0xFF" This.EditorWindow.Outputs.FontColor ) : ( "0xFF33FFFF" ) ) , Gdip_FillRoundedRectangle( G , Brush , 477 * ScaleFactor , 53 * ScaleFactor , 40 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Get" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 472 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 480 * ScaleFactor , 74 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 480 * ScaleFactor , 56 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;tab Font Size
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 535 * ScaleFactor , 45 * ScaleFactor , 100 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Font Size" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 535 * ScaleFactor " y" 41 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 579 * ScaleFactor , 50 * ScaleFactor , 51 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Font Background Color
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 15 * ScaleFactor , 95 * ScaleFactor , 205 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Font BG Color" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 91 * ScaleFactor  , "Segoe ui" , 70 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 78 * ScaleFactor , 100 * ScaleFactor , 86 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 168 * ScaleFactor , 100 * ScaleFactor , 46 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( !This.EditorWindow.Buttons.GetFontBackgroundColorButton.Pressed ) ? ( "0xFF" This.EditorWindow.Outputs.FontColorBackground ) : ( "0xFF33FFFF" ) ) , Gdip_FillRoundedRectangle( G , Brush , 171 * ScaleFactor , 103 * ScaleFactor , 40 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Get" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 167 * ScaleFactor " y" 91 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 174 * ScaleFactor , 124 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 174 * ScaleFactor , 106 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Font Options
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 230 * ScaleFactor , 95 * ScaleFactor , 405 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Font Options" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 228 * ScaleFactor " y" 91 * ScaleFactor  , "Segoe ui" , 70 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 293 * ScaleFactor , 100 * ScaleFactor , 337 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Font Type
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 15 * ScaleFactor , 145 * ScaleFactor , 182 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Font Type" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 141 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 65 * ScaleFactor , 150 * ScaleFactor , 126 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Text
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 205 * ScaleFactor , 145 * ScaleFactor , 430 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Text" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 203 * ScaleFactor " y" 141 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 247 * ScaleFactor , 150 * ScaleFactor , 384 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Base 64 string
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 15 * ScaleFactor , 195 * ScaleFactor , 302 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "B64 String" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 191 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 65 * ScaleFactor , 200 * ScaleFactor , 246 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;pBitmap path
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 325 * ScaleFactor , 195 * ScaleFactor , 310 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Image Path" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 326 * ScaleFactor " y" 191 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 375 * ScaleFactor , 200 * ScaleFactor , 206 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 585 * ScaleFactor , 200 * ScaleFactor , 46 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( !This.EditorWindow.Buttons.GetImagePathButton.Pressed ) ? ( "0xFF009999" ) : ( "0xFF33FFFF" ) ) , Gdip_FillRoundedRectangle( G , Brush , 588 * ScaleFactor , 203 * ScaleFactor , 40 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Get" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 583 * ScaleFactor " y" 191 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 591 * ScaleFactor , 224 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 591 * ScaleFactor , 206 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;sub buttons
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 465 * ScaleFactor , 6 * ScaleFactor , 178 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 465 * ScaleFactor , 7 * ScaleFactor , 178 * ScaleFactor , 29 * ScaleFactor , "0xFF009999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 465 * ScaleFactor , 6 * ScaleFactor , 178 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		;*******************************************************
		;Cancel Button
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 557 * ScaleFactor , 8 * ScaleFactor , 76 * ScaleFactor , 26 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF009999" ) , Gdip_FillRoundedRectangle( G , Brush , 560 * ScaleFactor , 11 * ScaleFactor , 70 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 564 * ScaleFactor , 29 * ScaleFactor , 62 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 565 * ScaleFactor , 13 * ScaleFactor , 61 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Cancel" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 571 * ScaleFactor " y" -3 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Submit Button
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 477 * ScaleFactor , 8 * ScaleFactor , 76 * ScaleFactor , 26 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF009999" ) , Gdip_FillRoundedRectangle( G , Brush , 480 * ScaleFactor , 11 * ScaleFactor , 70 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x991F1F1F" ) , Gdip_FillRectangle( G , Brush , 484 * ScaleFactor , 29 * ScaleFactor , 62 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 485 * ScaleFactor , 13 * ScaleFactor , 61 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Submit" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 491 * ScaleFactor " y" -2 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Colors
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 269 * ScaleFactor , 6 * ScaleFactor , 189 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 270 * ScaleFactor , 8 * ScaleFactor , 187 * ScaleFactor , 28 * ScaleFactor , "0xFF009999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 269 * ScaleFactor , 6 * ScaleFactor , 189 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		x := 273
		Loop, 7	{
			Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , x * ScaleFactor , 9 * ScaleFactor , 24 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
			Brush := Gdip_BrushCreateSolid( "0xFF" This.EditorWindow.SavedColorButtons[ A_Index ].Color ) , Gdip_FillRoundedRectangle( G , Brush , ( x + 2 ) * ScaleFactor , 11 * ScaleFactor , 20 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
			x += 26
		}
		Brush := Gdip_CreateLineBrushFromRect( 10 * ScaleFactor , 11 * ScaleFactor , 250 * ScaleFactor , 19 * ScaleFactor , "0xFF009999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 10 * ScaleFactor , 10 * ScaleFactor , 250 * ScaleFactor , 20 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 43 * ScaleFactor , 108 * ScaleFactor , 41 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 15 * ScaleFactor , 45 * ScaleFactor , 110 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 43 * ScaleFactor , 108 * ScaleFactor , 41 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 135 * ScaleFactor , 45 * ScaleFactor , 190 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 43 * ScaleFactor , 108 * ScaleFactor , 41 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 335 * ScaleFactor , 45 * ScaleFactor , 190 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 43 * ScaleFactor , 108 * ScaleFactor , 41 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 535 * ScaleFactor , 45 * ScaleFactor , 100 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 15 * ScaleFactor , 96 * ScaleFactor , 205 * ScaleFactor , 38 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 15 * ScaleFactor , 95 * ScaleFactor , 205 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 15 * ScaleFactor , 96 * ScaleFactor , 205 * ScaleFactor , 38 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 230 * ScaleFactor , 95 * ScaleFactor , 405 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 145 * ScaleFactor , 179 * ScaleFactor , 39 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 15 * ScaleFactor , 145 * ScaleFactor , 182 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 17 * ScaleFactor , 145 * ScaleFactor , 179 * ScaleFactor , 39 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 205 * ScaleFactor , 145 * ScaleFactor , 430 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 15 * ScaleFactor , 196 * ScaleFactor , 301 * ScaleFactor , 39 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 15 * ScaleFactor , 195 * ScaleFactor , 302 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		Brush := Gdip_CreateLineBrushFromRect( 15 * ScaleFactor , 196 * ScaleFactor , 301 * ScaleFactor , 39 * ScaleFactor , "0xFF999999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 325 * ScaleFactor , 195 * ScaleFactor , 310 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		;*******************************************************
		;bottom section
		Brush := Gdip_BrushCreateSolid( "0xFF444444" ) , Gdip_FillRoundedRectangle( G , Brush , 10 * ScaleFactor , 260 * ScaleFactor , 630 * ScaleFactor , 105 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_CreateLineBrushFromRect( 12 * ScaleFactor , 262 * ScaleFactor , 629 * ScaleFactor , 66 * ScaleFactor , "0xFF009999" , "0xFF000000" , 1 , 1 ) , Pen := Gdip_CreatePenFromBrush( Brush , 1 ) , Gdip_DeleteBrush( Brush ) , Gdip_DrawRoundedRectangle( G , Pen , 10 * ScaleFactor , 260 * ScaleFactor , 630 * ScaleFactor , 105 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeletePen( Pen )
		;*******************************************************
		;Run path
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 15 * ScaleFactor , 265 * ScaleFactor , 620 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Run Path" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 261 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 65 * ScaleFactor , 270 * ScaleFactor , 516 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 585 * ScaleFactor , 270 * ScaleFactor , 46 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( ( !This.EditorWindow.Buttons.GetRunPathButton.Pressed ) ? ( "0xFF009999" ) : ( "0xFF33FFFF" ) ) , Gdip_FillRoundedRectangle( G , Brush , 588 * ScaleFactor , 273 * ScaleFactor , 40 * ScaleFactor , 24 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x66F0F0F0" ) , Gdip_FillRectangle( G , Brush , 591 * ScaleFactor , 276 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0x99000000" ) , Gdip_FillRectangle( G , Brush , 591 * ScaleFactor , 294 * ScaleFactor , 34 * ScaleFactor , 1 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Get" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 583 * ScaleFactor " y" 261 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Clipboard string
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 17 * ScaleFactor , 315 * ScaleFactor , 390 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Clip String" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 13 * ScaleFactor " y" 311 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 65 * ScaleFactor , 320 * ScaleFactor , 336 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		;*******************************************************
		;Label
		Brush := Gdip_BrushCreateSolid( "0xFF006666" ) , Gdip_FillRoundedRectangle( G , Brush , 417 * ScaleFactor , 315 * ScaleFactor , 218 * ScaleFactor , 40 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF1F1F1F" ) , Gdip_FillRoundedRectangle( G , Brush , 475 * ScaleFactor , 320 * ScaleFactor , 156 * ScaleFactor , 30 * ScaleFactor , 5 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Brush := Gdip_BrushCreateSolid( "0xFF000000" ) , Gdip_TextToGraphics( G , "Label" , "s" 12 * ScaleFactor " Center vCenter Bold c" Brush " x" 423 * ScaleFactor " y" 311 * ScaleFactor  , "Segoe ui" , 50 * ScaleFactor , 50 * ScaleFactor ) , Gdip_DeleteBrush( Brush )
		Gdip_DeleteGraphics( G )
		return pBitmap
	}
}

;************
;POS_Control Class v1.2
;Written By: Hellbent
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
class POS_Control extends MenuEditor	{
	static init := POS_Control.SetUp()
	TabMoveButton_Y[]{
		Get{
			return This.TabMoveAllButton_Y + This.TabMoveAllButton_H + This.TabMargin
		}
	}
	TabMoveButton_H[]{
		Get{
			return This.TabWindow.H - This.TabMoveAllButton_H - 3 * This.TabMargin
		}
	}
	TabDisplayArea_W[]{
		Get{
			return This.TabWindow.W - This.TabMoveButton_W - 3 * This.TabMargin - This.TabMoveButton_W - This.TabMargin
		}
	}
	TabDisplayArea_H[]{
		Get{
			return This.TabWindow.H - 3 * This.TabMargin - This.TabAddButton_H
		}
	}
	TabUPButton_X[]{
		Get{
			return This.TabMoveButton_W + This.TabDisplayArea_W + 3 * This.TabMargin
		}
	}
	TabDownButton_X[]{
		Get{
			return This.TabUPButton_X
		}
	}
	TabResizeButton_X[]{
		Get{
			return This.TabWindow.W - 28
		}
	}
	TabResizeButton_Y[]{
		Get{
			return This.TabWindow.H - 28
		}
	}
	ButtonMoveButton_Y[]{
		Get{
			return This.ButtonMoveAllButton_Y + This.ButtonMoveAllButton_H + This.ButtonMargin
		}
	}
	ButtonMoveButton_H[]{
		Get{
			return This.ButtonWindow.H - This.ButtonMoveAllButton_H - 3 * This.ButtonMargin
		}
	}
	ButtonDisplayArea_W[]{
		Get{
			return This.ButtonWindow.W - This.ButtonMoveButton_W - 3 * This.ButtonMargin - This.ButtonMoveButton_W - This.ButtonMargin
		}
	}
	ButtonDisplayArea_H[]{
		Get{
			return This.ButtonWindow.H - 2 * This.ButtonMargin - ( This.ButtonMargin + This.ButtonAddButton_H )
		}
	}
	ButtonUPButton_X[]{
		Get{
			return This.ButtonMoveButton_W + This.ButtonDisplayArea_W + 3 * This.ButtonMargin
		}
	}
	ButtonDownButton_X[]{
		Get{
			return This.ButtonUPButton_X
		}
	}
	ButtonResizeButton_X[]{
		Get{
			return This.ButtonWindow.W - 28
		}
	}
	ButtonResizeButton_Y[]{
		Get{
			return This.ButtonWindow.H - 28
		}
	}
	TabUnit_Width[]{
		Get{
			return ( out := Floor( This.TabDisplayArea_W - This.TabMargin ) / ( This.TabWidth + This.TabMargin ) ) ? ( floor( out ) ) : ( 1 )
		}
	}
	TabUnit_Height[]{
		Get{
			return ( out := Floor( This.TabDisplayArea_H - This.TabMargin ) / ( This.TabHeight + This.TabMargin ) ) ? ( Floor( out ) ) : ( 1 )
		}
	}
	TabUnit_Area[]{
		Get{
			return ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) + This.TabUnit_Width * This.TabUnit_Height ) 
		}
	}
	ButtonUnit_Width[]{
		Get{
			return ( out := Floor( This.ButtonDisplayArea_W - This.ButtonMargin ) / ( This.ButtonWidth + This.ButtonMargin ) ) ? ( floor( out ) ) : ( 1 )
		}
	}
	ButtonUnit_Height[]{
		Get{
			return ( out := Floor( This.ButtonDisplayArea_H - This.ButtonMargin ) / ( This.ButtonHeight + This.ButtonMargin ) ) ? ( Floor( out ) ) : ( 1 )
		}
	}
	ButtonUnit_Area[]{
		Get{
			return ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) + This.ButtonUnit_Width * This.ButtonUnit_Height ) 
		}
	}
	ButtonMinWidth[]{
		Get{
			return This.ButtonWidth + This.ButtonMoveAllButton_W + This.ButtonUPButton_W + 6 * This.ButtonMargin
		}
	}
	ButtonMinHeight[]{
		Get{
			if( This.ButtonHeight + 4 * This.ButtonMargin < 120 )
				return 120
			else 
				return This.ButtonHeight + 4 * This.ButtonMargin
		}
	}	
	TabMinWidth[]{
		Get{
			return This.TabWidth + This.TabMoveAllButton_W + This.TabUPButton_W + 6 * This.TabMargin
		}
	}
	TabMinHeight[]{
		Get{
			;~ if( ( This.TabHeight + 4 * This.TabMargin ) < ( 120  + This.TabAddButton_H + This.TabMargin ) )
			if( ( This.TabHeight + 5 * This.TabMargin ) < ( 85  + This.TabAddButton_H + This.TabMargin ) )
				return 85 + This.TabAddButton_H + This.TabMargin * 3
			else
				return This.TabHeight + 5 * This.TabMargin + This.TabAddButton_H 
		}
	}
	SetUp(){
		;**********************************
		;~ This.Color2 := "0x99000000"
		;~ This.Color2 := "0x990A9EFA"
		This.Color2 := "0x6622262a"
		;~ This.Color3 := "0x99000000"
		;~ This.Color3 := "0x660A9EFA"
		This.Color3 := "0x6622262a"
		;**********************************
		StartTime := A_TickCount
		Gdip_Startup()
		This.Tabs := []
		This.TabWindow := New PopUpWindow( { AutoShow: 1 , X: 100 , Y: 100 , W: 380 , H: 600 , Options: " -DPIScale +AlwaysOnTop +ToolWindow" } )
		This.TabWidth := 320
		This.TabHeight := 80
		This.TabMargin := 10
		;~ This.TabBackgroundColor := "0x66000000"
		This.TabBackgroundColor := "0x99000000"
		
		;~ This.TabMoveAllButton_Color := "0xFF004444"
		This.TabMoveAllButton_Color := "0xFF42464a"
		
		This.TabMoveButton_Color := This.TabMoveAllButton_Color
		This.TabDisplayArea_Color := "0xff22262a"
		This.TabUPButton_Color := This.TabMoveAllButton_Color
		This.TabDownButton_Color := This.TabMoveAllButton_Color
		;~ This.TabResizeButton_Color := "0xFFFFFF00"
		This.TabResizeButton_Color := "0xaaacacff"
		;~ This.TabControlBackgroundColor := "0xFF22262a"
		This.TabControlBackgroundColor := "0xFF00aacc"
		
		This.TabHighlightColor := "0xFF00aacc"
		;~ This.TabHighlightColor := "0xFF32363a"
		
		This.TabAddButtonColor := This.TabMoveAllButton_Color
		This.TabEditButtonColor := This.TabMoveAllButton_Color
		This.TabMoveAllButton_X := This.TabMargin
		This.TabMoveAllButton_Y := This.TabMargin
		This.TabMoveAllButton_W := 20
		This.TabMoveAllButton_H := 30
		This.TabMoveButton_X := This.TabMargin
		This.TabMoveButton_W := 20
		This.TabAddButton_X := This.TabMoveAllButton_W + 2 * This.TabMargin + 3 * This.TabMargin
		This.TabAddButton_Y := This.TabMargin
		This.TabAddButton_W := 50
		This.TabAddButton_H := 20
		This.TabEditButton_X := This.TabAddButton_X + This.TabAddButton_W + This.TabMargin
		This.TabEditButton_Y := This.TabMargin
		This.TabEditButton_W := This.TabAddButton_W
		This.TabEditButton_H := This.TabAddButton_H
		This.TabDisplayArea_X := This.TabMoveButton_W + 2 * This.TabMargin
		This.TabDisplayArea_Y := 2 * This.TabMargin + This.TabAddButton_H
		This.TabUPButton_Y := This.TabMargin
		This.TabUPButton_W := 20
		This.TabUPButton_H := 30
		This.TabDownButton_Y := This.TabUPButton_H + 2 * This.TabMargin
		This.TabDownButton_W := 20
		This.TabDownButton_H := 30
		This.TabResizeButton_W := 20
		This.TabResizeButton_H := 20
		This.TabSelectedTab := 1
		This.TabSelectedRow := 1
		This.ButtonWindow := New PopUpWindow( { AutoShow: 1 , X: This.TabWindow.X + This.TabWindow.W , Y: This.TabWindow.Y , W: 710 , H: This.TabWindow.H , Options: " -DPIScale +AlwaysOnTop +ToolWindow" } )
		This.ButtonWidth := 250
		This.ButtonHeight := 50
		This.ButtonMargin := 10
		;~ This.ButtonMoveAllButton_Color := "0xFF3377aa"
		This.ButtonMoveAllButton_Color := "0xFF42464a"
		This.ButtonMoveButton_Color := This.ButtonMoveAllButton_Color
		;~ This.ButtonDisplayArea_Color := "0xFF227788"
		This.ButtonDisplayArea_Color := "0xFF32363a"
		This.ButtonUPButton_Color := This.ButtonMoveAllButton_Color
		This.ButtonDownButton_Color := This.ButtonMoveAllButton_Color
		;~ This.ButtonResizeButton_Color := "0xFFFFFF00"
		This.ButtonResizeButton_Color := "0xaaacacff"
		This.ButtonControlBackgroundColor := "0xFF000000"
		This.ButtonAddButtonColor := This.ButtonMoveAllButton_Color
		This.ButtonEditButtonColor := This.ButtonMoveAllButton_Color
		This.ButtonMoveAllButton_X := This.ButtonMargin
		This.ButtonMoveAllButton_Y := This.ButtonMargin
		This.ButtonMoveAllButton_W := 20
		This.ButtonMoveAllButton_H := 30
		This.ButtonMoveButton_X := This.ButtonMargin
		This.ButtonMoveButton_W := 20
		This.ButtonAddButton_X := This.ButtonMoveAllButton_W + 2 * This.ButtonMargin + 3 * This.ButtonMargin
		This.ButtonAddButton_Y := This.ButtonMargin
		This.ButtonAddButton_W := 50
		This.ButtonAddButton_H := 20
		This.ButtonEditButton_X := This.ButtonAddButton_X + This.ButtonAddButton_W + This.ButtonMargin
		This.ButtonEditButton_Y := This.ButtonMargin
		This.ButtonEditButton_W := This.ButtonAddButton_W
		This.ButtonEditButton_H := This.ButtonAddButton_H
		This.ButtonDisplayArea_X := This.ButtonMoveButton_W + 2 * This.ButtonMargin
		This.ButtonDisplayArea_Y := This.ButtonMargin * 2 + This.ButtonAddButton_H
		This.ButtonUPButton_Y := This.ButtonMargin
		This.ButtonUPButton_W := 20
		This.ButtonUPButton_H := 30
		This.ButtonDownButton_Y := This.ButtonUPButton_H + 2 * This.ButtonMargin
		This.ButtonDownButton_W := 20
		This.ButtonDownButton_H := 30
		This.ButtonResizeButton_W := 20
		This.ButtonResizeButton_H := 20
		This.ButtonSelectedTab := 0
		This.ButtonSelectedRow := 1
		This.ButtonActiveTab := 0
		This.TargetedButton := ""
		This.ButtonEditMode := 0
		OnMessage( 0x201 , This.OnClick.Bind( This ) )
		OnMessage( 0x020A , This.OnWheelChange.Bind( This ) )
		;~ ToolTip, Loading...
		IfNotExist, % A_ScriptDir "\Tab Menu Data.ini"
			FileAppend, , % A_ScriptDir "\Tab Menu Data.ini"
		tObj := {} , bObj := {}
		IniRead, TabLoopLength , % A_ScriptDir "\Tab Menu Data.ini" , % "TotalTabs" , % "Count" , ""
		Loop, % TabLoopLength	{
			;~ ToolTip, % "Loading Tab: " A_Index " of " TabLoopLength
			index := A_Index
			IniRead, Color , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" Index , Color
			if( Color = "Error" || Color = "" )
				continue
			for k , v in [ "Text" , "FontType" , "pBitmap" , "B64" , "FontOptions" , "FontSize" , "FontColor" , "Color" , "FontColorBackground" , "Position" , "FilePath" ]	{
				IniRead, out , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" index , % v , ""
				tObj[ v ] := out
			}
			if( tObj.FilePath ){
				tObj.pBitmap := Gdip_CreateBitmapFromFile( tObj.FilePath )
				if( Gdip_GetImageWidth( tObj.pBitmap ) > 100 || Gdip_GetImageHeight( tObj.pBitmap ) > 100 ){
					TempBitmap := NewpBitmap()
					Gdip_DrawImage( TempBitmap.G , tObj.pBitmap , 0 , 0 , 100 , 100 )
					Gdip_DisposeImage( tObj.pBitmap )
					Gdip_DeleteGraphics( TempBitmap.G )
					tObj.pBitmap := TempBitmap.pBitmap
				}
			}
			POS_Control.AddNewTab( tObj.Position , tObj )
			IniRead, ButtonLoopLength , % A_ScriptDir "\Tab Menu Data.ini" , % "Total_Buttons_Tab_" index , % "Count" , ""
			Loop, % ButtonLoopLength	{
				bIndex := A_Index 
				IniRead, Color , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" Index "_Button_" bIndex , Color
				if( Color = "Error" || Color = "" )
					continue
				for k, v in [ "Text" , "FontType" , "pBitmap" , "B64" , "FontOptions" , "FontSize" , "FontColor" , "Color" , "FontColorBackground" , "Position" , "FilePath" , "RunPath" , "Tab" , "ClipString" , "Label" ]	{
					IniRead, out , % A_ScriptDir "\Tab Menu Data.ini" , % "Tab_" Index "_Button_" bIndex , % v , % A_Space
					if( v = "ClipString" && out )
							out := StrReplace( out , "?" , "`n" )
					bObj[ v ] := out
				}
				if( bObj.FilePath ){
					bObj.pBitmap := Gdip_CreateBitmapFromFile( bObj.FilePath )
					if( Gdip_GetImageWidth( bObj.pBitmap ) > 100 || Gdip_GetImageHeight( bObj.pBitmap ) > 100 ){
						TempBitmap := NewpBitmap()
						Gdip_DrawImage( TempBitmap.G , bObj.pBitmap , 0 , 0 , 100 , 100 )
						Gdip_DisposeImage( bObj.pBitmap )
						Gdip_DeleteGraphics( TempBitmap.G )
						bObj.pBitmap := TempBitmap.pBitmap
					}
				}
				POS_Control.AddNewButton( bObj.Tab , bObj.Position , bObj )
			}
		}
		;~ ToolTip, % "Loaded in " (A_TickCount - StartTime ) / 1000 " Seconds"
		;~ Sleep, 2000
		;~ ToolTip,
	}
	AddNewTab( position := "" , obj := "" ){
		
		local TabObj := {} , k , v
		if( !position )
			position := This.Tabs.MaxIndex() + 1
		if( !position )
			position := 1
		TabObj.Position := position
		TabObj.Text := ""
		TabObj.Color := "FF0000"
		TabObj.FontType := "Segoe UI"
		TabObj.FontSize := 12
		TabObj.FontOptions := " Center vCenter Bold "
		TabObj.FontColor := "000000"
		TabObj.FontColorBackground := "FFFFFF"
		if( IsObject( obj ) ){
			for k , v in obj 	{
				if( TabObj.HasKey( k ) )
					TabObj[ k ] := obj[ k ]
			}
		}
		This.Tabs[ Position ] := TabObj
		This.Tabs[ Position ].Buttons := []
		if( obj.Haskey( "B64" ) && obj.B64 ){
			This.Tabs[ Position ].B64 := obj.B64
			This.Tabs[ Position ].Icon := This.B64ToPBitmap( obj.B64 )
		}else if( obj.Haskey( "pBitmap" ) && obj.pBitmap ){
			This.Tabs[ Position ].FilePath := obj.FilePath
			This.Tabs[ Position ].Icon := obj.pBitmap
		}
	}
	AddNewButton( Tab := "" , position := "" , obj := "" ){
		local ButtonObj := {} , k , v 
		if( !Tab )
			Tab := This.Tabs.MaxIndex() 
		if( !position ){
			position := This.Tabs[ Tab ].Buttons.MaxIndex() + 1
			if( !position )
				position := 1
		}
		ButtonObj.Text := ""
		ButtonObj.Color := "FF0000"
		ButtonObj.FontType := "Segoe UI"
		ButtonObj.FontSize := 12
		ButtonObj.FontOptions := " Center vCenter Bold "
		ButtonObj.FontColor := "000000"
		ButtonObj.FontColorBackground := "FFFFFF"		
		if( IsObject( obj ) ){
			for k , v in obj 	{
				if( ButtonObj.HasKey( k ) )
					ButtonObj[ k ] := obj[ k ]
			}
		}		
		This.Tabs[ Tab ].Buttons[ position ] := ButtonObj		
		if( obj.HasKey( "Label" ) && obj.Label ){
			This.Tabs[ Tab ].Buttons[ position ].Label := obj.Label
		}else if( obj.HasKey( "RunPath" ) && obj.RunPath ){
			This.Tabs[ Tab ].Buttons[ position ].RunPath := obj.RunPath
		}else if( obj.HasKey( "ClipString" ) && obj.ClipString != "" ){
			This.Tabs[ Tab ].Buttons[ position ].ClipString := obj.ClipString
		}
		if( obj.Haskey( "B64" ) && obj.B64 ){
			This.Tabs[ Tab ].Buttons[ position ].B64 := obj.B64
			This.Tabs[ Tab ].Buttons[ position ].Icon := This.B64ToPBitmap( obj.B64 )
		}else if( obj.Haskey( "pBitmap" ) && obj.pBitmap ){
			This.Tabs[ Tab ].Buttons[ position ].FilePath := obj.FilePath
			This.Tabs[ Tab ].Buttons[ position ].Icon := obj.pBitmap
		}
	}
	MoveWindow( Window := "Tab" , all := 0 ){
		local x , y 
		if( all ){
			if( window = "tab" ){
				This.WinVector := New Vector( This.ButtonWindow.X , This.ButtonWindow.Y )
				This.WinVector.Sub( This.TabWindow.X , This.TabWindow.Y )
				PostMessage, 0xA1, 2 
				While( GetKeyState( "LButton" , "P" ) )
					Sleep 30
				WinGetPos, x, y,,, % "ahk_id " This.TabWindow.Hwnd
				This.TabWindow.UpdateSettings( { X: x , Y: y } )
				This.ButtonWindow.UpdateSettings( { X: x + This.WinVector.X , Y: y + This.WinVector.Y } )
				This.DrawButtonWindow()
			}else{
				This.WinVector := New Vector( This.TabWindow.X , This.TabWindow.Y )
				This.WinVector.Sub( This.ButtonWindow.X , This.ButtonWindow.Y )
				PostMessage, 0xA1, 2 
				While( GetKeyState( "LButton" , "P" ) )
					Sleep 30
				WinGetPos, x, y,,, % "ahk_id " This.ButtonWindow.Hwnd
				This.ButtonWindow.UpdateSettings( { X: x , Y: y } )
				This.TabWindow.UpdateSettings( { X: x + This.WinVector.X , Y: y + This.WinVector.Y } )
				This.DrawTabWindow()
			}
		}else{
			PostMessage, 0xA1, 2 
			While( GetKeyState( "LButton" , "P" ) )
				Sleep 30
			WinGetPos, x, y,,, % "ahk_id " This[ window "Window" ].Hwnd
			This[ window "Window" ].UpdateSettings( { X: x , Y: y } )
		}
	}
	ResizeWindow( window := "Tab" ){
		local lx , ly , x , y 
		CoordMode, Mouse, Screen
		This[ window "SelectedRow" ] := 1
		While( GetKeyState( "LButton" , "P" ) ){
			MouseGetPos, x , y
			if( x != lx || y != ly ){
				lx := x , ly := y
				if( ( This[ window "Window" ].W := x - This[ window "Window" ].X ) < This[ window "MinWidth" ] )
					This[ window "Window" ].W := This[ window "MinWidth" ]
				if( ( This[ window "Window" ].H := y - This[ window "Window" ].Y ) < This[ window "MinHeight" ] )
					This[ window "Window" ].H := This[ window "MinHeight" ]
				This[ window "Window" ].UpdateSettings( "" , 1 )
				This[ "Draw" Window "Window" ]()
			}
		}
	}
	CheckWindowTriggers( Window := "Tab" ){
		local x , y , k , v
		CoordMode, Mouse, Client
		MouseGetPos, x , y 
		for k , v in [ Window "MoveAllButton_" , Window "MoveButton_" , Window "DisplayArea_" , Window "UPButton_" , Window "DownButton_" , Window "ResizeButton_" , Window "AddButton_" , Window "EditButton_" ]{
			if( x >= This[ v "X" ] && x <= This[ v "X" ] + This[ v "W" ] && y >= This[ v "Y" ] && y <= This[ v "Y" ] + This[ v "H" ])
				return A_Index
		}
	}
	CheckTabControls(){
		local x , y , k , v , index , mx , my
		CoordMode, Mouse, Client
		MouseGetPos, mx , my 
		index := 1 + ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) )
		y := This.TabDisplayArea_Y + This.TabMargin
		Loop, % This.TabUnit_Height	{
			x := This.TabDisplayArea_X + This.TabMargin
			Loop, % This.TabUnit_Width	{
				if( IsObject( This.Tabs[ index ] ) ){					
					if( mx >= x && mx <= x + This.TabWidth && my >= y && my <= y + This.TabHeight )					
						return index					
				}				
				x += This.TabWidth + This.TabMargin
				index++			
			}			
			y += This.TabHeight + This.TabMargin		
		}		
	}
	CheckButtonControls(){		
		local x , y , mx , my , index		
		CoordMode, Mouse, Client		
		MouseGetPos, mx , my 		
		index := 1 + ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) )
		y := This.ButtonDisplayArea_Y + This.ButtonMargin		
		Loop, % This.ButtonUnit_Height	{			
			x := This.ButtonDisplayArea_X + This.ButtonMargin			
			Loop, % This.ButtonUnit_Width	{				
				if( IsObject( This.Tabs[ This.TabSelectedTab ].Buttons[ index ] ) ){					
					if( mx >= x && mx <= x + This.ButtonWidth && my >= y && my <= y + This.ButtonHeight ){
						This.ButtonActiveTab := Index
						if( This.ButtonEditMode ){							
							This.ButtonEditMode := 0
							This.TargetedButton := index
							This.NewEditWindow( "Button" , "Edit" )
							return
						}
						if( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].ClipString != "" )						
							Clipboard := This.Tabs[ This.TabSelectedTab ].Buttons[ index ].ClipString													
						if( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].RunPath != "" ){
							Try{
								Run, % This.Tabs[ This.TabSelectedTab ].Buttons[ index ].RunPath								
							}catch{
								ToolTip, Failed to run the path.
								Loop, 3
									SoundBeep, 999
								sleep, 2000
								ToolTip,
							}							
						}
						if( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Label != "" ){
							if( IsLabel( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Label ) ){
								Try{
									SetTimer, % This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Label , -30
								}catch{
									ToolTip, Failed to run the label.
									Loop, 3
										SoundBeep, 999
									sleep, 2000
									ToolTip,
								}
							}else{
								ToolTip, Failed to run the label.
								Loop, 3
									SoundBeep, 999
								sleep, 2000
								ToolTip,
							}
						}
						return index
					}
				}
				x += This.ButtonWidth + This.ButtonMargin
				index++
			}
			y += This.ButtonHeight + This.ButtonMargin
		}
	}
	OnWheelChange( input , w , m , hwnd ){
		local dir , sel , test
		if( This.Active )
			return
		This.Active := 1
		if( hwnd = This.TabWindow.Hwnd )
			sel := "Tab"
		else
			sel := "Button"
		dir := ( ( input >> 16 ) > 0x7FFF ) || ( ( input < 0 ) ? ( 1 ) : ( 0 ) )
		if( !dir ){
			if( This[ sel "SelectedRow" ] > 1 ){
				--This[ sel "SelectedRow" ]
				This[ "Draw" sel "Window" ]()
			}
		}else{			
			if( sel = "Tab" ){				
				if( This.TabUnit_Area < This.Tabs.MaxIndex() ){					
					This.TabSelectedRow++
					This.DrawTabWindow()				
				}				
			}else{				
				if( This.ButtonUnit_Area < This.Tabs[ This.TabSelectedTab ].Buttons.MaxIndex() ){					
					This.ButtonSelectedRow++
					This.DrawButtonWindow()				
				}			
			}		
		}		
		Sleep, 30
		This.Active := 0		
	}
	OnClick( l , w , m , hwnd ){
		local sel		
		if( hwnd = This.TabWindow.Hwnd ){			
			if( control := This.CheckWindowTriggers( "Tab" ) ){				
				if( control = 1 ){					
					This.MoveWindow( "Tab" , 1 )				
				}else if( control = 2 ){					
					This.MoveWindow( "Tab" )				
				}else if( control = 3 ){					
					if( sel := This.CheckTabControls()  ){						
						This.TabSelectedTab := sel
						This.ButtonSelectedRow := 1						
						This.DrawTabWindow()
						This.DrawButtonWindow()					
					}					
				}else if( control = 4 ){	
					While( GetKeyState( "LButton" , "P" ) ){
						if( This.TabSelectedRow > 1 ){			
							--This.TabSelectedRow
							This.DrawTabWindow()					
						}	
						Sleep, 50
					}
				}else if( control = 5 ){	
					While( GetKeyState( "LButton" , "P" ) ){
						if( This.TabUnit_Area < This.Tabs.MaxIndex() ){						
							This.TabSelectedRow++
							This.DrawTabWindow()					
						}	
						Sleep, 50
					}
				}else if( control = 6 ){					
					This.ResizeWindow( "Tab" )				
				}else if( control = 7 ){		
					This.NewEditWindow( "Tab" , "New" )
				}else if( control = 8 ){
					This.NewEditWindow( "Tab" , "Edit" )
				}
			}
			return 1
		}else if( hwnd = This.ButtonWindow.Hwnd ){
			if( control := This.CheckWindowTriggers( "Button" ) ){
				if( control = 1 ){
					This.MoveWindow( "Button" , 1 )
				}else if( control = 2 ){
					This.MoveWindow( "Button" )
				}else if( control = 3 ){
					if( sel := This.CheckButtonControls()  ){
						This.ButtonSelectedTab := sel
						This.DrawButtonWindow()
						While( GetKeyState( "LButton" , "P" ) )
							Sleep, 30
						if( This.Tabs[ This.TabSelectedTab ].Buttons[ This.ButtonSelectedTab ].Label )
							This.ButtonActiveTab := This.ButtonSelectedTab
						This.ButtonSelectedTab := 0
						This.DrawButtonWindow()
					}
				}else if( control = 4 ){
					While( GetKeyState( "LButton" , "P" ) ){
						if( This.ButtonSelectedRow > 1 ){
							--This.ButtonSelectedRow
							This.DrawButtonWindow()
						}
						Sleep, 50
					}
				}else if( control = 5 ){
					While( GetKeyState( "LButton" , "P" ) ){
						if( This.ButtonUnit_Area < This.Tabs[ This.TabSelectedTab ].Buttons.MaxIndex() ){
							This.ButtonSelectedRow++
							This.DrawButtonWindow()
						}
						Sleep, 50
					}
				}else if( control = 6 ){
					This.ResizeWindow( "Button" )
				}else if( control = 7 ){
					This.NewEditWindow( "Button" )
				}else if( control = 8 ){
					This.ButtonEditMode := 1
					This.TipTimer := bd := This.Tip.Bind( This )
					SetTimer, % bd , 30
				}
			}
			return 1
		}
	}
	Tip(){
		if( This.ButtonEditMode ){
			ToolTip, Select the button that you want to edit
		}else{
			ToolTip, 
			bd := This.TipTimer
			SetTimer, % bd , Delete
		}
	}
	DrawTabWindow(){
		This.TabWindow.UpdateSettings(,1)
		This.TabWindow.ClearWindow()
		;Paint Background
		This.TabWindow.PaintBackground( { Color: This.TabBackgroundColor , X: 2 , Y: 2 , W: This.TabWindow.W - 4 , H: This.TabWindow.H - 4 , Round: 5 } )  
		;Paint Move all button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabMoveAllButton_X - 1 , Y: This.TabMoveAllButton_Y - 1 , W: This.TabMoveAllButton_W + 2 , H: This.TabMoveAllButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabMoveAllButton_Color , X: This.TabMoveAllButton_X , Y: This.TabMoveAllButton_Y , W: This.TabMoveAllButton_W , H: This.TabMoveAllButton_H , Round: 5 } ) 
		;Paint Move Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabMoveButton_X - 1 , Y: This.TabMoveButton_Y - 1 , W: This.TabMoveButton_W + 2 , H: This.TabMoveButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabMoveButton_Color , X: This.TabMoveButton_X , Y: This.TabMoveButton_Y , W: This.TabMoveButton_W , H: This.TabMoveButton_H , Round: 5 } )  
		;Paint Add Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabAddButton_X - 1 , Y: This.TabAddButton_Y - 1 , W: This.TabAddButton_W + 2 , H: This.TabAddButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabAddButtonColor , X: This.TabAddButton_X , Y: This.TabAddButton_Y , W: This.TabAddButton_W , H: This.TabAddButton_H , Round: 5 } )  
		DrawText( This.TabWindow.G , This.TabAddButton_X - 1 , This.TabAddButton_Y - 1 , "NEW" ,  "0xFF000000" , This.TabAddButton_W , This.TabAddButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		DrawText( This.TabWindow.G , This.TabAddButton_X , This.TabAddButton_Y + 1 , "NEW" ,  "0xFFFFFF00" , This.TabAddButton_W , This.TabAddButton_H , " Center vCenter " " s" 16 , "Segoe UI" )	
		;Paint Edit Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabEditButton_X - 1 , Y: This.TabEditButton_Y - 1 , W: This.TabEditButton_W + 2 , H: This.TabEditButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabEditButtonColor , X: This.TabEditButton_X , Y: This.TabEditButton_Y , W: This.TabEditButton_W , H: This.TabEditButton_H , Round: 5 } )  
		DrawText( This.TabWindow.G , This.TabEditButton_X - 1 , This.TabEditButton_Y - 1 , "Edit" ,  "0xFF000000" , This.TabEditButton_W , This.TabEditButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		DrawText( This.TabWindow.G , This.TabEditButton_X , This.TabEditButton_Y + 1 , "Edit" ,  "0xFFFFFF00" , This.TabEditButton_W , This.TabEditButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		;Paint Resize Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabResizeButton_X - 1 , Y: This.TabResizeButton_Y - 1 , W: This.TabResizeButton_W + 2 , H: This.TabResizeButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabResizeButton_Color , X: This.TabResizeButton_X , Y: This.TabResizeButton_Y , W: This.TabResizeButton_W , H: This.TabResizeButton_H , Round: 5 } )  
		;Paint display area
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabDisplayArea_X - 1 , Y: This.TabDisplayArea_Y - 1 , W: This.TabDisplayArea_W + 2 , H: This.TabDisplayArea_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabDisplayArea_Color , X: This.TabDisplayArea_X , Y: This.TabDisplayArea_Y , W: This.TabDisplayArea_W , H: This.TabDisplayArea_H , Round: 5 } )  
		;Paint Up Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabUPButton_X - 1 , Y: This.TabUPButton_Y - 1 , W: This.TabUPButton_W + 2 , H: This.TabUPButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabUPButton_Color , X: This.TabUPButton_X , Y: This.TabUPButton_Y , W: This.TabUPButton_W , H: This.TabUPButton_H , Round: 5 } )  
		;Paint Down Button
		This.TabWindow.PaintBackground( { Color: This.TabHighlightColor , X: This.TabDownButton_X - 1  , Y: This.TabDownButton_Y - 1 , W: This.TabDownButton_W + 2 , H: This.TabDownButton_H + 2 , Round: 5 } )  
		This.TabWindow.PaintBackground( { Color: This.TabDownButton_Color , X: This.TabDownButton_X , Y: This.TabDownButton_Y , W: This.TabDownButton_W , H: This.TabDownButton_H , Round: 5 } )  
		index := 1 + ( This.TabUnit_Width * ( This.TabSelectedRow - 1 ) )
		y := This.TabDisplayArea_Y + This.TabMargin
		Loop, % This.TabUnit_Height	{
			x := This.TabDisplayArea_X + This.TabMargin
			Loop, % This.TabUnit_Width	{
				if( IsObject( This.Tabs[ index ] ) ){
					if( This.Tabs[ index ].Icon && ( This.Tabs[ index ].B64 || This.Tabs[ index ].FilePath ) ){
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 5 , Y: y - 5 , W: This.TabWidth + 10 , H: This.TabHeight + 10 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						if( index != This.TabSelectedTab )
							;~ Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , "0xFF" This.Tabs[ Index ].Color , "0x99000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
							Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , "0xFF" This.Tabs[ Index ].Color , This.Color2 , 1 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
						This.TabWindow.PaintBackground( { Color: "0xFF" This.Tabs[ Index ].Color , X: x - 1 , Y: y - 1 , W: This.TabWidth + 2 , H: This.TabHeight + 2 , Round: 5 } )  
						This.TabWindow.PaintBackground( { Color: "0xFF" This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						;~ Brush := Gdip_CreateLineBrushFromRect( x , y , This.TabWidth , This.TabHeight , "0xFF" This.Tabs[ index ].Color , "0x99000000" , 2 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x , y , This.TabWidth , This.TabHeight , 5 ) , Gdip_DeleteBrush( Brush )
						Brush := Gdip_CreateLineBrushFromRect( x , y , This.TabWidth , This.TabHeight , "0xFF" This.Tabs[ index ].Color , This.Color2 , 2 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x , y , This.TabWidth , This.TabHeight , 5 ) , Gdip_DeleteBrush( Brush )
						w := ( This.TabWidth <= This.TabHeight ) ? ( This.TabWidth ) : ( This.TabHeight )
						This.TabWindow.DrawBitmap( This.Tabs[ index ].Icon , { X: x + w / 20 , Y: y + w / 20 , W: w - w / 10 , H: w  - w / 10 } , 0 )
						DrawText( This.TabWindow.G , x + w - 1 , y - 1 , This.Tabs[ index ].text ,  "0xFF" This.Tabs[ index ].FontColorBackground , This.TabWidth - w , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
						DrawText( This.TabWindow.G , x + w , y , This.Tabs[ index ].text , "0xFF" This.Tabs[ index ].FontColor , This.TabWidth - w , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}else{
						This.TabWindow.PaintBackground( { Color: ( index = This.TabSelectedTab ) ? ( "0xFFFF0000" ) : ( "0xFF000000" ) , X: x - 4 , Y: y - 4 , W: This.TabWidth + 8 , H: This.TabHeight + 8 , Round: 5 } )  
						if( index != This.TabSelectedTab )
							;~ Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , "0xFF" This.Tabs[ Index ].Color , "0x99000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
							Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , "0xFF" This.Tabs[ Index ].Color , This.Color2 , 1 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x - 4 , y - 4 , This.TabWidth + 8 , This.TabHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
						This.TabWindow.PaintBackground( { Color: "0xFF" This.Tabs[ index ].Color , X: x , Y: y , W: This.TabWidth , H: This.TabHeight , Round: 5 } )  
						;~ Brush := Gdip_CreateLineBrushFromRect( x , y , This.TabWidth , This.TabHeight , "0xFF" This.Tabs[ index ].Color , "0x99000000" , 2 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x , y , This.TabWidth , This.TabHeight , 5 ) , Gdip_DeleteBrush( Brush )
						Brush := Gdip_CreateLineBrushFromRect( x , y , This.TabWidth , This.TabHeight , "0xFF" This.Tabs[ index ].Color , This.Color2 , 2 , 1 ) , Gdip_FillRoundedRectangle( This.TabWindow.G , Brush , x , y , This.TabWidth , This.TabHeight , 5 ) , Gdip_DeleteBrush( Brush )
						DrawText( This.TabWindow.G , x - 1 , y - 1  , This.Tabs[ index ].text ,  "0xFF" This.Tabs[ index ].FontColorBackground , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
						DrawText( This.TabWindow.G , x , y , This.Tabs[ index ].text ,  "0xFF" This.Tabs[ index ].FontColor , This.TabWidth , This.TabHeight , This.Tabs[ index ].FontOptions " s" This.Tabs[ index ].FontSize , This.Tabs[ index ].FontType )
					}
				}
				x += This.TabWidth + This.TabMargin
				index++
			}
			y += This.TabHeight + This.TabMargin
		}
		This.TabWindow.UpdateWindow()
	}
	DrawButtonWindow(){
		This.ButtonWindow.UpdateSettings(,1)
		This.ButtonWindow.ClearWindow()
		;Paint Background
		This.ButtonWindow.PaintBackground( { Color: "0x66000000" , X: 2 , Y: 2 , W: This.ButtonWindow.W - 4 , H: This.ButtonWindow.H - 4 , Round: 5 } )  
		;Paint Move all button
		This.ButtonWindow.PaintBackground( { Color: "0xFF000000" , X: This.ButtonMoveAllButton_X - 1 , Y: This.ButtonMoveAllButton_Y - 1 , W: This.ButtonMoveAllButton_W + 2 , H: This.ButtonMoveAllButton_H + 2 , Round: 5 } )  
		This.ButtonWindow.PaintBackground( { Color: This.ButtonMoveAllButton_Color , X: This.ButtonMoveAllButton_X , Y: This.ButtonMoveAllButton_Y , W: This.ButtonMoveAllButton_W , H: This.ButtonMoveAllButton_H , Round: 5 } )  
		;Paint Move Button
		This.ButtonWindow.PaintBackground( { Color: "0xFF000000" , X: This.ButtonMoveButton_X - 1 , Y: This.ButtonMoveButton_Y - 1 , W: This.ButtonMoveButton_W + 2 , H: This.ButtonMoveButton_H + 2 , Round: 5 } )  
		This.ButtonWindow.PaintBackground( { Color: This.ButtonMoveButton_Color , X: This.ButtonMoveButton_X , Y: This.ButtonMoveButton_Y , W: This.ButtonMoveButton_W , H: This.ButtonMoveButton_H , Round: 5 } )  
		;Paint Add Button
		This.ButtonWindow.PaintBackground( { Color: "0xFF000000" , X: This.ButtonAddButton_X - 1 , Y: This.ButtonAddButton_Y - 1 , W: This.ButtonAddButton_W + 2 , H: This.ButtonAddButton_H + 2 , Round: 5 } )  
		This.ButtonWindow.PaintBackground( { Color: This.ButtonAddButtonColor , X: This.ButtonAddButton_X , Y: This.ButtonAddButton_Y , W: This.ButtonAddButton_W , H: This.ButtonAddButton_H , Round: 5 } )  
		DrawText( This.ButtonWindow.G , This.ButtonAddButton_X - 1 , This.ButtonAddButton_Y - 1 , "NEW" ,  "0xFF000000" , This.ButtonAddButton_W , This.ButtonAddButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		DrawText( This.ButtonWindow.G , This.ButtonAddButton_X , This.ButtonAddButton_Y + 1 , "NEW" ,  "0xFFFFFF00" , This.ButtonAddButton_W , This.ButtonAddButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		;Paint Edit Button
		This.ButtonWindow.PaintBackground( { Color: "0xFF000000" , X: This.ButtonEditButton_X - 1 , Y: This.ButtonEditButton_Y - 1 , W: This.ButtonEditButton_W + 2 , H: This.ButtonEditButton_H + 2 , Round: 5 } )  
		This.ButtonWindow.PaintBackground( { Color: This.ButtonEditButtonColor , X: This.ButtonEditButton_X , Y: This.ButtonEditButton_Y , W: This.ButtonEditButton_W , H: This.ButtonEditButton_H , Round: 5 } )  
		DrawText( This.ButtonWindow.G , This.ButtonEditButton_X - 1 , This.ButtonEditButton_Y - 1 , "Edit" ,  "0xFF000000" , This.ButtonEditButton_W , This.ButtonEditButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		DrawText( This.ButtonWindow.G , This.ButtonEditButton_X , This.ButtonEditButton_Y + 1 , "Edit" ,  "0xFFFFFF00" , This.ButtonEditButton_W , This.ButtonEditButton_H , " Center vCenter " " s" 16 , "Segoe UI" )
		;Paint Resize Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonResizeButton_Color , X: This.ButtonResizeButton_X , Y: This.ButtonResizeButton_Y , W: This.ButtonResizeButton_W , H: This.ButtonResizeButton_H , Round: 5 } )  
		;Paint display area
		This.ButtonWindow.PaintBackground( { Color: This.ButtonDisplayArea_Color , X: This.ButtonDisplayArea_X , Y: This.ButtonDisplayArea_Y , W: This.ButtonDisplayArea_W , H: This.ButtonDisplayArea_H , Round: 5 } )  
		;Paint Up Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonUPButton_Color , X: This.ButtonUPButton_X , Y: This.ButtonUPButton_Y , W: This.ButtonUPButton_W , H: This.ButtonUPButton_H , Round: 5 } )  
		;Paint Down Button
		This.ButtonWindow.PaintBackground( { Color: This.ButtonDownButton_Color , X: This.ButtonDownButton_X , Y: This.ButtonDownButton_Y , W: This.ButtonDownButton_W , H: This.ButtonDownButton_H , Round: 5 } )  
		index := 1 + ( This.ButtonUnit_Width * ( This.ButtonSelectedRow - 1 ) )
		y := This.ButtonDisplayArea_Y + This.ButtonMargin
		Loop, % This.ButtonUnit_Height	{
			x := This.ButtonDisplayArea_X + This.ButtonMargin
			Loop, % This.ButtonUnit_Width	{
				if( IsObject( This.Tabs[ This.TabSelectedTab ].Buttons[ index ] ) ){
					if( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Icon && ( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].B64 || This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FilePath ) ){
						This.ButtonWindow.PaintBackground( { Color: ( This.ButtonSelectedTab = index ) ? ( "0xFFFF0000" ) : ( This.ButtonControlBackgroundColor ) , X: x - 5 , Y: y - 5 , W: This.ButtonWidth + 10 , H: This.ButtonHeight + 10 , Round: 5 } )  
						This.ButtonWindow.PaintBackground( { Color: ( This.ButtonSelectedTab = index ) ? ( "0xFFFF0000" ) : ( This.ButtonControlBackgroundColor ) , X: x - 4 , Y: y - 4 , W: This.ButtonWidth + 8 , H: This.ButtonHeight + 8 , Round: 5 } )  
						if( index != This.ButtonSelectedTab )
							Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , "0x99000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
							;~ Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , This.Color3 , 1 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
						This.ButtonWindow.PaintBackground( { Color: "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , X: x , Y: y , W: This.ButtonWidth , H: This.ButtonHeight , Round: 5 } )  
						;~ Brush := Gdip_CreateLineBrushFromRect( x , y , This.ButtonWidth , This.ButtonHeight , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , "0x99000000" , 2 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x , y , This.ButtonWidth , This.ButtonHeight , 5 ) , Gdip_DeleteBrush( Brush )
						Brush := Gdip_CreateLineBrushFromRect( x , y , This.ButtonWidth , This.ButtonHeight , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , This.Color3 , 2 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x , y , This.ButtonWidth , This.ButtonHeight , 5 ) , Gdip_DeleteBrush( Brush )
						w := ( This.ButtonWidth <= This.ButtonHeight ) ? ( This.ButtonWidth ) : ( This.ButtonHeight )
						This.ButtonWindow.DrawBitmap( This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Icon , { X: x + w / 20 , Y: y + w / 20 , W: w - w / 10 , H: w - w / 10 } , 0 )
						DrawText( This.ButtonWindow.G , x + w - 1 , y - 1 , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColorBackground , This.ButtonWidth - w , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
						DrawText( This.ButtonWindow.G , x + w , y , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColor , This.ButtonWidth - w , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
					}else{
						This.ButtonWindow.PaintBackground( { Color: ( This.ButtonSelectedTab = index ) ? ( "0xFFFF0000" ) : ( This.ButtonControlBackgroundColor ) , X: x - 4 , Y: y - 4 , W: This.ButtonWidth + 8 , H: This.ButtonHeight + 8 , Round: 5 } )  
						if( index != This.ButtonSelectedTab )
							Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , "0x99" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , "0x99000000" , 1 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
							;~ Brush := Gdip_CreateLineBrushFromRect( x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , "0x99" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , This.Color3 , 1 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x - 4 , y - 4 , This.ButtonWidth + 8 , This.ButtonHeight + 8 , 5 ) , Gdip_DeleteBrush( Brush )
						This.ButtonWindow.PaintBackground( { Color: "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , X: x , Y: y , W: This.ButtonWidth , H: This.ButtonHeight , Round: 5 } )  
						;~ Brush := Gdip_CreateLineBrushFromRect( x , y , This.ButtonWidth , This.ButtonHeight , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , "0x99000000" , 2 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x , y , This.ButtonWidth , This.ButtonHeight , 5 ) , Gdip_DeleteBrush( Brush )
						Brush := Gdip_CreateLineBrushFromRect( x , y , This.ButtonWidth , This.ButtonHeight , "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].Color , This.Color3 , 2 , 1 ) , Gdip_FillRoundedRectangle( This.ButtonWindow.G , Brush , x , y , This.ButtonWidth , This.ButtonHeight , 5 ) , Gdip_DeleteBrush( Brush )
						DrawText( This.ButtonWindow.G , x - 1 , y - 1 , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColorBackground , This.ButtonWidth , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
						DrawText( This.ButtonWindow.G , x , y , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].text ,  "0xFF" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontColor , This.ButtonWidth , This.ButtonHeight , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontOptions " s" This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontSize , This.Tabs[ This.TabSelectedTab ].Buttons[ index ].FontType )
					}
				}
				x += This.ButtonWidth + This.ButtonMargin
				index++
			}
			y += This.ButtonHeight + This.ButtonMargin
		}
		This.ButtonWindow.UpdateWindow()
	}
	B64ToPBitmap( Input ){
		local ptr , uptr , pBitmap , pStream , hData , pData , Dec , DecLen , B64
		VarSetCapacity( B64 , strlen( Input ) << !!A_IsUnicode )
		B64 := Input
		If !DllCall("Crypt32.dll\CryptStringToBinary" ( ( A_IsUnicode ) ? ( "W" ) : ( "A" ) ), Ptr := A_PtrSize ? "Ptr" : "UInt" , &B64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0)
			Return False
		VarSetCapacity( Dec , DecLen , 0 )
		If !DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), Ptr, &B64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0)
			Return False
		DllCall("Kernel32.dll\RtlMoveMemory", Ptr, pData := DllCall("Kernel32.dll\GlobalLock", Ptr, hData := DllCall( "Kernel32.dll\GlobalAlloc", "UInt", 2,  UPtr := A_PtrSize ? "UPtr" : "UInt" , DecLen, UPtr), UPtr) , Ptr, &Dec, UPtr, DecLen)
		DllCall("Kernel32.dll\GlobalUnlock", Ptr, hData)
		DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, hData, "Int", True, Ptr "P", pStream)
		DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  Ptr, pStream, Ptr "P", pBitmap)
		return pBitmap
	}
}
;************
;Vector Class
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
Class Vector	{
	;Written By: HB
	;Date: Sept 23rd, 2022
	;Last Edit: Sept 24th, 2022
	;Purpose: Vector math class 
	;Credit: Rohwedder 
	;Resources: 
		;Line intercept concepts and code: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=37175
		;Create an Arrow: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=92039&p=479129#p478944
		;Getting an angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483661#p483678
		;Setting an Angle: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=108760&p=483786#p483811
		;
		
	static RadToDeg := 45 / ATan( 1 ) 
		, DegToRad := ATan( 1 ) / 45 
		
	__New( x := 0 , y := 0 , rotate := 0 ){ 
		if( IsObject( x ) ){
			if( rotate = 3 ){
				This.X := x.X * -1
				,This.Y := x.Y * -1
			}else if( rotate = 2 ){
				This.X := x.Y 
				,This.Y := x.X * -1
			}else if( rotate = 1 ){
				This.X := x.Y * -1
				,This.Y := x.X 
			}else{
				This.X := x.X
				,This.Y := x.Y
			}
		}else{
			if( rotate = 3 ){
				This.X := X * -1
				,This.Y := Y * -1
			}else if( rotate = 2 ){
				This.X := Y 
				,This.Y := X * -1
			}else if( rotate = 1 ){
				This.X := Y * -1
				,This.Y := X 
			}else{
				This.X := X
				,This.Y := Y
			}
		}
	}
	Add( x , y := "" ){
		if( IsObject( x ) ){
			This.X += x.X
			,This.Y += x.Y
		}else if( y = "" ){
			This.X += x 
			,This.Y += x
		}else{
			This.X += x 
			,This.Y += y 
		}
	}
	Sub( x , y := "" ){
		if( IsObject( x ) ){
			This.X -= x.X
			,This.Y -= x.Y
		}else if( y = "" ){
			This.X -= X
			,This.Y -= X
		}else{
			This.X -= X
			,This.Y -= Y
		}
	}
	Div( x , y := "" ){
		if( IsObject( x ) ){
			This.X /= x.X
			,This.Y /= x.Y
		}else if( x && y = "" ){
			This.X /= x 
			,This.Y /= x 
		}else{
			This.X /= X
			,This.Y /= Y
		}
	}
	Mult( x , y := "" ){
		if( IsObject( x ) ){
			This.X *= x.X
			,This.Y *= x.Y
		}else if( x && y = "" ){
			This.X *= x 
			,This.Y *= x 
		}else{
			This.X *= X
			,This.Y *= Y
		}
	}
	Dist( x , y := "" ){
		if( IsObject( x ) )
			return Sqrt( ( ( This.X - x.X ) **2 ) + ( ( This.Y - x.Y ) **2 ) )
		else 
			return Sqrt( ( ( This.X - X ) **2 ) + ( ( This.Y - Y ) **2 ) )
	}
	GetMag(){
		return Sqrt( This.X * This.X + This.Y * This.Y )
	}
	SetMag( magnitude ){
		local m := This.GetMag()
		This.X := This.X * magnitude / m
		,This.Y := This.Y * magnitude / m
	}
	MagSq(){
		return This.GetMag()**2
	}	
	Dot( x , y := "" ){
		if( IsObject( x ) )
			return ( This.X * x.X ) + ( This.Y * x.Y )
		else
			return ( This.X * X ) + ( This.Y * Y )
	}
	Cross( x , y := "" ){
		if( IsObject( x ) )
			return This.X * x.Y - This.Y * x.X
		else
			return This.X * Y - This.Y * X
		
	}
	Norm(){
		local m := This.GetMag()
		This.X /= m
		This.Y /= m
	}
	GetAngle(){ 
		local angle 
		( (  angle := Vector.RadToDeg * DllCall( "msvcrt\atan2" , "Double" , This.Y , "Double" , This.X , "CDECL Double" ) ) < 0 ) ? ( angle += 360 )
		return angle
	}
	SetAngle( newAngle := 0 , NewVector := 0 ){
		local Angle := This.GetAngle()
		, ChangeAngle := newAngle - Angle 
		, Co := Cos( Vector.DegToRad * ChangeAngle )
		, Si := Sin( Vector.DegToRad * ChangeAngle )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	RotateAngle( rotationAmount := 90 , NewVector := 0 ){
		local Co := Cos( Vector.DegToRad * rotationAmount )
		, Si := Sin( Vector.DegToRad * rotationAmount )
		, X := This.X 
		, Y := This.Y
		, X2 := X * Co - Y * Si 
		, Y2 := X * Si + Y * Co 
		
		if( !NewVector )
			This.X := X2 , This.Y := Y2
		else 
			return New Vector( X2 , Y2 )
	}
	;********************************************
	;class methods
	TestLineInterceptPoint( interceptPoint , Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } } , interceptPoint = { X: , Y: }
		local
		for k , v in [ "X" , "Y" ]	
			M%v%_Min := min( Line1.Start[ v ] , Line1.End[ v ] )
			,M%v%_Max := max( Line1.Start[ v ] , Line1.End[ v ] )
			,L%v%_Min := min( Line2.Start[ v ] , Line2.End[ v ] )
			,L%v%_Max := max( Line2.Start[ v ] , Line2.End[ v ] )
		if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
			return 1
		return 0
	}
	GetLineInterceptPoint( Line1 , Line2 ){ ; Line = { Start: { X: , Y: } , End: { X: , Y: } }
		local A1 := Line1.End.Y - Line1.Start.Y
		,B1 := Line1.Start.X - Line1.End.X
		,C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
		,A2 := Line2.End.Y - Line2.Start.Y
		,B2 := Line2.Start.X - Line2.End.X
		,C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
		,Denominator := A1 * B2 - A2 * B1 
		return New Vector( { X: ( ( B2 * C1 - B1 * C2 ) / Denominator )  , Y: ( ( A1 * C2 - A2 * C1 ) / Denominator ) } )
	}
	;********************************************
}
;**************************************************************************************************************************************************************************
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 00000 <<<>>> 00000 
;**************************************************************************************************************************************************************************
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2.2
;Date Written: Oct 28th, 2021
;Last Edit: Feb 7th, 2022 :Changed the trigger method.
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		Gdip_DeleteGraphics( This.G )
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow( alpha := 255 ){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H , alpha )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
}
;**************************************************************************************************
;**************************************************************************************************
;**************************************************************************************************
DrawText( G , x , y , text ,  color , width , height , options := " Center vCenter Bold s12 " , type := "comic Sans MS" ){
	Brush := Gdip_BrushCreateSolid( color ) , Gdip_TextToGraphics( G , text , options " c" brush " x" x " y" y  , type , width , height ) , Gdip_DeleteBrush( Brush )
}	
FillCircle( G , x , y  , color := "0xFFFF0000" , width := 30 , height := "" ){
	local Brush
	if( !height )
		Brush := Gdip_BrushCreateSolid( color ) , Gdip_FillEllipse( G , Brush , x , y , width , width ) , Gdip_DeleteBrush( Brush )
	else
		Brush := Gdip_BrushCreateSolid( color ) , Gdip_FillEllipse( G , Brush , x , y , width , height ) , Gdip_DeleteBrush( Brush )
}
Random( Min := 0 , Max := 100 ){
	local out
	Random, out , Min , Max
	return out
}

NewpBitmap( w := 100 , h := 100 , smoothingMode := 2 , interpolationMode := 7 ){
	local obj := {}
	obj.pBitmap := Gdip_CreateBitmap( obj.W := w , obj.H := h  )
	obj.G := Gdip_GraphicsFromImage( obj.pBitmap )
	Gdip_SetSmoothingMode( obj.G , obj.SmoothingMode := smoothing )
	Gdip_SetInterpolationMode( obj.G , obj.InterpolationMode := InterpolationMode )
	return obj 
}

Add new tabs and buttons.
Set buttons to run a path or url.
Set buttons to place a string in your clipboard.
Set buttons to call up a label you add to the script.
menu 9.gif
menu 9.gif (963.01 KiB) Viewed 3227 times
Currently no way to remove buttons once added (can only edit them).
*It is advised that you don't use the positioning feature (i.e. leave the position blank).
If you have question feel free to ask.
Last edited by Hellbent on 11 Oct 2023, 06:19, edited 2 times in total.

User avatar
HiSoKa
Posts: 480
Joined: 27 Jan 2020, 15:43

Re: Resizable Tab Menu / POS Overlay

Post by HiSoKa » 07 Dec 2022, 10:27

Thanks you @Hellbent Unfortunately, I love old and classic things That's why i have windows 7 and im comfortable with it :mrgreen:,
When I tried to run Tab Menu V2 , I got an error message when trying to add a new button or tab.
I hope to try it soon when I upgrade my Windows .. Thank you again ;)

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Resizable Tab Menu / POS Overlay

Post by Hellbent » 07 Dec 2022, 10:42

HiSoKa wrote:
07 Dec 2022, 10:27
Thanks you @Hellbent Unfortunately, I love old and classic things That's why i have windows 7 and im comfortable with it :mrgreen:,
When I tried to run Tab Menu V2 , I got an error message when trying to add a new button or tab.
I hope to try it soon when I upgrade my Windows .. Thank you again ;)
I hadn't planned on adding the edit ability and it was pretty much just hacked in. I still need to do a second draft starting from scratch but I don't have the time atm. I should be able to do this with windows 7 in mind on my next pass but the first version is still windows 7 compatible. The real difference is that you write out the code for the buttons and tabs rather than save them to a .ini file.

doubledave22
Posts: 343
Joined: 08 Jun 2019, 17:36

Re: Resizable Tab Menu / POS Overlay

Post by doubledave22 » 07 Dec 2022, 16:43

Hellbent wrote:
07 Dec 2022, 08:41
@doubledave22 that looks great, I wonder what is was that I found buggy about it? You wouldn't happen to have a more elaborate example do you? I noticed that your example has a few methods missing.
Which methods am I missing? just wondering... it's definitely not complete.

Ultimately I ended up going with a pseudo-drag to resize method similar to yours. I found the cursor getting stuck in re-size mode as well as the added +resize pixel boundaries to be difficult to work with.

If you are interested, I did build your resize lines into a "resizable" format. It would take a tiny bit of modification to build into your projects but you may find it useful.

For reference:
this.Container is the instance of your popupwindow class.
Triggers you could configure to match your class, so you know when to trigger the resize.

Code: Select all

	Draw_Resize_Icon()
	{
		static line_color := "4A4D5E"		; color of all 3 lines
			 , offset := 8					; distance from bottom and right edges to draw
			 , relativeWidth := .045		; total width of all 3 lines (based on container width)
			 , relativeSpacing := .6		; space between lines. This draws the 1st line 30% then second 60% of total resize icon width (best to stay between .5-.8 here)
			 , idealContainerW := 300		; roughly your expected width for the window
			 , relativeThickness := 1		; increase for thicker lines
		
		;================================================
		; lines will get thicker as window increases in width
		line_thickness := ceil((this.Container.W * relativeThickness)/idealContainerW)
		
		;================================================
		; first we create small square in bottom right of window with dimensions of width * relativeWidth
		sW := ceil(This.Container.W * relativeWidth)
		; position it [offset] pixels from the edge
		sX := this.Container.W - sW - offset
		sY := this.Container.H - sW - offset
		
		;================================================
		; add triggers to track with WM_LBUTTONDOWN
		this.Triggers.Resize_Icon := {X: sX - sW, Y: sY - sW, W: sW, H: sW}
		
		;================================================
		; now calculate lines
		;=================== Line 1 =====================
		 x1 := sX
		,y1 := this.Container.H - offset
		,x2 := this.Container.W - offset
		,y2 := sY
		,Brush := Gdip_BrushCreateSolid("0xFF" line_color) , Pen := Gdip_CreatePenFromBrush(Brush , line_thickness) , Gdip_DeleteBrush(Brush) , Gdip_DrawLine(This.Container.G , Pen, x1, y1, x2, y2) , Gdip_DeletePen(Pen)
		;=================== Line 2 =====================
		,x1 := sX + (sW * (relativeSpacing / 2))
		,y2 := sY + (sW * (relativeSpacing / 2))
		,Brush := Gdip_BrushCreateSolid("0xFF" line_color) , Pen := Gdip_CreatePenFromBrush(Brush , line_thickness) , Gdip_DeleteBrush(Brush) , Gdip_DrawLine(This.Container.G , Pen, x1, y1, x2, y2) , Gdip_DeletePen(Pen)
		;=================== Line 3 =====================
		,x1 := sX + (sW * relativeSpacing)
		,y2 := sY + (sW * relativeSpacing)
		,Brush := Gdip_BrushCreateSolid("0xFF" line_color) , Pen := Gdip_CreatePenFromBrush(Brush , line_thickness) , Gdip_DeleteBrush(Brush) , Gdip_DrawLine(This.Container.G , Pen, x1, y1, x2, y2) , Gdip_DeletePen(Pen)
	}
Now the three lines will grow and shrink with your window when you call this.Draw_Resize_Icon() during your resize drawing.
cdc6899cc94297a72f2221dc9546a1bd.gif
cdc6899cc94297a72f2221dc9546a1bd.gif (180.2 KiB) Viewed 3159 times

Kisang Kim
Posts: 12
Joined: 31 Jul 2019, 02:37

Re: Resizable Tab Menu / POS Overlay

Post by Kisang Kim » 07 Dec 2022, 23:55

Image
Attachments
221208_15234.jpg
221208_15234.jpg (93.85 KiB) Viewed 3128 times

Post Reply

Return to “Scripts and Functions (v1)”