[Solved] Prototype Window and Pane Class problems

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Innominate
Posts: 3
Joined: 16 Jul 2016, 02:15

[Solved] Prototype Window and Pane Class problems

16 Jul 2016, 03:11

Okay, so I'm working with window boxes within another application, where the window boxes don't have handles. I have programmed my program to find and interact with the windows, but I'm having trouble figuring out how to implement the Pane Prototype class.

Example structure I need to accommodate:
ParentWindow{
TopPane{}, LeftPane{ LeftPane{}, RightPane{} }, RightPane{}
}
(The classes keep track of the parent-child relationships via the parent and child InstanceVars.)

Everything has a LeftX, RightX, TopY, and BottomY so that I can track where the objects are.
Each main Window has a title and unique configuration of Panes, so I'm using the Window prototype as my base and adding all the code for the Pane behavior/configuration within the class for the WindowTitle.

Panes hold objects that are unique to that pane, so each one is different. The panes can be hidden or change in size because you can expand one pane into the space of the adjoining Pane(s). If I drag the top Pane down, the left and right panes get shorter.

What I feel would work best here is if I could define each pane's edge coordinates as an expression using the edge coordinates of the objects that influence the pane's dimensions. Like define LeftPane's LeftX InstanceVar as "LeftPane.Parent.LeftX + 2" and LeftPane's RightX InstanceVar as "this.Parent.Left-Right Divider - 2" and so forth.

I just can't figure out how to change a class' instance variable to act like a method. Can this be done? Is there a better alternative?

This is basically the best way I can think of to accomplish my goals, but it gives me errors for the dots in stuff like "this.RightNeighborObj.%RightNeighborXName%". Basically, I want them to be able to influence each other without having to make a custom class for each pane.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

window1 := new Window()
`::
InputBox,  num, "Pane Manipulation", "Enter a x value for LeftPane's right wall, 100-200. Current value of LeftPane's right wall is " window1.LeftPane.RightX
window1.LeftPane.RightX := num
MsgBox, % "LeftPane.RightX = " window1.LeftPane.RightX "`t window1.RightPane.LeftX = " window1.RightPane.LeftX
return

Class Window{
	Title := 
	TitleImg := 
	LeftX := 100
	RightX := 100
	TopY := 200
	BottomY := 200
	Parent := 
	Children := []
	LeftPane := [] 
	RightPane := []
	__New(){
		;MsgBox, % "Starting Window"
		this.LeftPane := new Pane(this, "LeftPane", "", this, "LeftX", 2, this.RightPane, "LeftX", -3, this, "TopY", 20, this, "BottomY", -2)
		this.RightPane := new Pane(this, "RightPane", "", this.LeftPane, "RightX", 3, this, "RightX", -2, this, "TopY", 20, this, "BottomY", -2)
		this.Children.Push(this.LeftPane, this.RightPane)
	}
}
Class Pane{
	Title := 
	LeftX {
		; Parent Window's coords must be set before Pane's dimensions are so that 
		get {
			Return this._LeftX
		}
		set {
			if(value = this.LeftNeighborObj){
				this._LeftX := value.%LeftNeighborXName% + LeftNeighborOffsetX ; Only set it because it was sent by its neighbor after setting its own value
			}
			Else if(value = Integer && value > this.LeftNeighborObj.%LeftNeighborXName% && value < this.RightNeighborObj.%RightNeighborXName%){
				this._LeftX := value
				this.LeftNeighborObj.%LeftNeighborXName% := this ; Send this object so that they infinitely setting eachother
			}
			else{
				Return False
			}
		}
	}
	RightX {
		; Parent Window's coords must be set before Pane's dimensions are so that 
		get {
			Return this._RightX
		}
		set {
			if(value = this.RightNeighborObj){
				this._RightX := value.%RightNeighborXName% + RightNeighborOffsetX ; Only set it because it was sent by its neighbor after setting its own value
			}
			Else if(value = Integer && value > this.RightNeighborObj.%RightNeighborXName% && value < this.LeftNeighborObj.%LeftNeighborXName%){
				this._RightX := value
				this.RightNeighborObj.%RightNeighborXName% := this ; Send this object so that they infinitely setting eachother
			}
			else{
				Return False
			}
		}
	}
	TopY := 
	BottomY := 
	Parent :=
	Children := 
	__New(parent, title, titleImg, leftNeighborObj, leftNeighborXName, leftNeighborOffsetX, rightNeighborObj, rightNeighborXName, rightNeighborOffsetX, topNeighborObj, topNeighborYName, topNeighborOffsetY, bottomNeighborObj, bottomNeighborYName, bottomNeighborOffsetY){
		;MsgBox, % "Starting Pane"
		this.Parent := parent
		this.Title:= title
		this.TitleImg := titleImg
		this.LeftNeighborObj := leftNeighborObj
		this.LeftNeighborXName := leftNeighborXName
		this.LeftNeighborOffsetX := leftNeighborOffsetX
		this.RightNeighborObj := rightNeighborObj
		this.RightNeighborXName := rightNeighborXName
		this.RightNeighborOffsetX := rightNeighborOffsetX
		this.TopNeighborObj := topNeighborObj
		this.TopNeighborYName := topNeighborYName
		this.TopNeighborOffsetY := topNeighborOffsetY
		this.BottomNeighborObj := bottomNeighborObj
		this.BottomNeighborYName := bottomNeighborYName
		this.BottomNeighborOffsetY := bottomNeighborOffsetY
	}
}
Last edited by Innominate on 18 Jul 2016, 22:59, edited 1 time in total.
Innominate
Posts: 3
Joined: 16 Jul 2016, 02:15

Re: Prototype Window and Pane Class problems

18 Jul 2016, 22:57

Thanks to GeekDude for helping me out with understanding that you can do this.Object[var, var].InstanceVar (see Objects doc for "Arrays of Arrays") instead of this.Object.%var%.%var%.InstanceVar. Because I couldn't find anything like GeekDude's advice, this was the most frustrating thing I've done. I hope someone benefits from this.

I decided that a pane should not be able to change the dimensions of its parent window/pane. To do that I'm going to add in some calls to parent methods.
Here's my solution:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;MsgBox, % "Starting="

window1 := new Window("ParentWindow")
`::
leftPaneRightWallX := window1.LeftPane.RightX
InputBox,  txt, Pane Manipulation, Enter LeftPane's new RightWallX value (100-200). Current= "%leftPaneRightWallX%"
num := txt + 1 - 1
;MsgBox, % "num = " num
window1.LeftPane.RightX := num
MsgBox, % "LeftPane.RightX = " window1.LeftPane.RightX "`t RightPane.LeftX = " window1.RightPane.LeftX

rightPaneRightWallX := window1.RightPane.LeftX
InputBox,  txt, Pane Manipulation, Enter RightPane's new LefttWallX value (100-200). Current= "%rightPaneRightWallX%"
num := txt + 1 - 1
;MsgBox, % "num = " num
window1.RightPane.LeftX := num
MsgBox, % "LeftPane.RightX = " window1.LeftPane.RightX "`t RightPane.LeftX = " window1.RightPane.LeftX



leftPaneTopY := window1.LeftPane.TopY
InputBox,  txt, Pane Manipulation, Enter LeftPane's new TopY value (100-200). Current= "%leftPaneTopY%"
num := txt + 1 - 1
;MsgBox, % "num = " num
window1.LeftPane.TopY := num
MsgBox, % "LeftPane.TopY = " window1.LeftPane.TopY "`t LeftPane.BottomY = " window1.LeftPane.BottomY 


leftPaneBottomY := window1.LeftPane.BottomY
InputBox,  txt, Pane Manipulation, Enter LeftPane's new BottomY value (100-200). Current= "%leftPaneBottomY%"
num := txt + 1 - 1
;MsgBox, % "num = " num
window1.LeftPane.BottomY := num
MsgBox, % "LeftPane.TopY = " window1.LeftPane.TopY "`t LeftPane.BottomY = " window1.LeftPane.BottomY 

return


; Pane creation could have inputs for where it connects to the rest of the window\

Class Window{
	Title := "ParentWindow"
	TitleImg := 
	LeftX := 100
	RightX := 200
	TopY := 100
	BottomY := 200
	Parent := 
	Children := []
	LeftPane := [] 
	RightPane := []
	__New(title := ""){
		this.Title := title
		;MsgBox, % this.Title
		this.LeftPane := new Pane(this, "LeftPane", "L", this, "LeftX", 2, this.RightPane, "LeftX", -3, this, "TopY", 20, this, "BottomY", -2)
		this.RightPane := new Pane(this, "RightPane", "R", this.LeftPane, "RightX", 3, this, "RightX", -2, this, "TopY", 20, this, "BottomY", -2)
		this.LeftPane.RightNeighborObj := this.RightPane	; Have to set after neighborPane was fully created
		this.LeftPane.LeftX := this.LeftX + 2
		this.LeftPane.RightX := 145
		this.RightPane.RightX := this.RightX - 2
	}
}
Class Pane{
	Title := 
		; Parent Window's coords must be set before Pane's dimensions are set 
	LeftX {
		get {
			Return this._LeftX
		}
		set {
			;MsgBox, % "Set LeftX received = " value
			if(value = this.LeftNeighborObj){
				; Set it this way because it was sent by its neighbor after setting its own value
				;MsgBox % this.Title "LeftX(value = this.LeftNeighborObj)"
				tmpLNXN := this.LeftNeighborXName
				this._LeftX := this.LeftNeighborObj[tmpLNXN] + this.LeftNeighborOffsetX
				;MsgBox, % this.Title "LeftX is now " this._LeftX
			}
			Else if(value is Number And value >= this.Parent.LeftX + this.LeftNeighborOffsetX And value <= this.Parent.RightX + this.RightNeighborOffsetX){
				; Add Check if value is beyond opposing wall. Maybe add MinWidth?
				;MsgBox % this.Title "LeftX(value (" value ") is Number And value >= this.Parent.LeftX (" this.Parent.LeftX ") + this.LeftNeighborOffsetX (" this.LeftNeighborOffsetX ") And value <= this.Parent.RightX (" this.Parent.RightX ") + this.RightNeighborOffsetX (" this.RightNeighborOffsetX ") )"
				this._LeftX := value
				;MsgBox, % this.Title "LeftX is now " this._LeftX
				; Panes cannot change the dimensions of Parents
				if(this.LeftNeighborObj != this.Parent){
					;MsgBox, % this.Title "LeftX is now " this._LeftX ". About to update this.LeftNeighborObj - " this.LeftNeighborObj.Title
					;this.LeftNeighborWallX(this)
					tmpLNXN := this.LeftNeighborXName
					this.LeftNeighborObj[tmpLNXN] := this
				}
				else{
					return False
				}
			}
			else{
				MsgBox, % this.Title "Set LeftX Error - Returning False because not this.LeftNeighborObj (" this.LeftNeighborObj.Title ") or False = (value (" value ") is Number And value >= this.Parent.LeftX (" this.Parent.LeftX ") + this.LeftNeighborOffsetX (" this.LeftNeighborOffsetX ") And value <= this.Parent.RightX (" this.Parent.RightX ") + this.RightNeighborOffsetX (" this.RightNeighborOffsetX "))"
				Return False
			}
		}
	}
		; Parent Window's coords must be set before Pane's dimensions are so that 
	RightX {
		get {
			Return this._RightX
		}
		set {
			;MsgBox, % "Set RightX received = " value
			if(value = this.RightNeighborObj){
				; Set it this way because it was sent by its neighbor after setting its own value
				;MsgBox % this.Title "RightX(value = this.RightNeighborObj)"
				tmpRNXN := this.RightNeighborXName
				this._RightX := this.RightNeighborObj[tmpRNXN] + this.RightNeighborOffsetX
				;MsgBox, % this.Title "RightX is now " this._RightX
			}
			Else if(value is Number And value >= this.Parent.LeftX + this.LeftNeighborOffsetX And value <= this.Parent.RightX + this.RightNeighborOffsetX){
				; Add Check if value is beyond opposing wall. Maybe add MinWidth?
				;MsgBox % this.Title "RightX(value (" value ") is Number And value >= this.Parent.LeftX (" this.Parent.LeftX ") + this.LeftNeighborOffsetX (" this.LeftNeighborOffsetX ") And value <= this.Parent.RightX (" this.Parent.RightX ") + this.RightNeighborOffsetX (" this.RightNeighborOffsetX ") )"
				this._RightX := value
				;MsgBox, % this.Title "RightX is now " this._RightX
				; Panes cannot change the dimensions of windows
				if(this.RightNeighborObj != this.Parent){
					;MsgBox, % this.Title "RightX is now " this._RightX ". About to update this.RightNeighborObj - " this.RightNeighborObj.Title
					;this.RightNeighborWallX(this)
					tmpRNXN := this.RightNeighborXName
					this.RightNeighborObj[tmpRNXN] := this
				}
				else{
					return False
				}
			}
			else{
				MsgBox, % this.Title "Set RightX Error - Returning False because not this.RightNeighborObj (" this.RightNeighborObj.Title ") or False = (value (" value ") is Number And value >= this.Parent.LeftX (" this.Parent.LeftX ") + this.LeftNeighborOffsetX (" this.LeftNeighborOffsetX ") And value <= this.Parent.RightX (" this.Parent.RightX ") + this.RightNeighborOffsetX (" this.RightNeighborOffsetX "))"
				Return False
			}
		}
	}
	TopY {
		get {
			Return this._TopY
		}
		set {
			;MsgBox, % "Set TopY received = " value
			if(value = this.TopNeighborObj){
				; Set it this way because it was sent by its neighbor after setting its own value
				;MsgBox % this.Title "TopY(value = this.TopNeighborObj)"
				tmpLNXN := this.TopNeighborXName
				this._TopY := this.TopNeighborObj[tmpLNXN] + this.TopNeighborOffsetY
				;MsgBox, % this.Title "TopY is now " this._TopY
			}
			Else if(value is Number And value >= this.Parent.TopY + this.TopNeighborOffsetY And value <= this.Parent.BottomY + this.BottomNeighborOffsetY){
				; Add Check if value is beyond opposing wall. Maybe add MinWidth?
				;MsgBox % this.Title "TopY(value (" value ") is Number And value >= this.Parent.TopY (" this.Parent.TopY ") + this.TopNeighborOffsetY (" this.TopNeighborOffsetY ") And value <= this.Parent.BottomY (" this.Parent.BottomY ") + this.BottomNeighborOffsetY (" this.BottomNeighborOffsetY ") )"
				this._TopY := value
				;MsgBox, % this.Title "TopY is now " this._TopY
				; Panes cannot change the dimensions of Parents
				if(this.TopNeighborObj != this.Parent){
					;MsgBox, % this.Title "TopY is now " this._TopY ". About to update this.TopNeighborObj - " this.TopNeighborObj.Title
					;this.TopNeighborWallX(this)
					tmpLNXN := this.TopNeighborXName
					this.TopNeighborObj[tmpLNXN] := this
				}
				else{
					return False
				}
			}
			else{
				MsgBox, % this.Title "Set TopY Error - Returning False because not this.TopNeighborObj (" this.TopNeighborObj.Title ") or False = (value (" value ") is Number And value >= this.Parent.TopY (" this.Parent.TopY ") + this.TopNeighborOffsetY (" this.TopNeighborOffsetY ") And value <= this.Parent.BottomY (" this.Parent.BottomY ") + this.BottomNeighborOffsetY (" this.BottomNeighborOffsetY "))"
				Return False
			}
		}
	}
		; Parent Window's coords must be set before Pane's dimensions are so that 
	BottomY {
		get {
			Return this._BottomY
		}
		set {
			;MsgBox, % "Set BottomY received = " value
			if(value = this.BottomNeighborObj){
				; Set it this way because it was sent by its neighbor after setting its own value
				;MsgBox % this.Title "BottomY(value = this.BottomNeighborObj)"
				tmpRNXN := this.BottomNeighborXName
				this._BottomY := this.BottomNeighborObj[tmpRNXN] + this.BottomNeighborOffsetY
				;MsgBox, % this.Title "BottomY is now " this._BottomY
			}
			Else if(value is Number And value >= this.Parent.TopY + this.TopNeighborOffsetY And value <= this.Parent.BottomY + this.BottomNeighborOffsetY){
				; Add Check if value is beyond opposing wall. Maybe add MinWidth?
				;MsgBox % this.Title "BottomY(value (" value ") is Number And value >= this.Parent.TopY (" this.Parent.TopY ") + this.TopNeighborOffsetY (" this.TopNeighborOffsetY ") And value <= this.Parent.BottomY (" this.Parent.BottomY ") + this.BottomNeighborOffsetY (" this.BottomNeighborOffsetY ") )"
				this._BottomY := value
				;MsgBox, % this.Title "BottomY is now " this._BottomY
				; Panes cannot change the dimensions of windows
				if(this.BottomNeighborObj != this.Parent){
					;MsgBox, % this.Title "BottomY is now " this._BottomY ". About to update this.BottomNeighborObj - " this.BottomNeighborObj.Title
					;this.BottomNeighborWallX(this)
					tmpRNXN := this.BottomNeighborXName
					this.BottomNeighborObj[tmpRNXN] := this
				}
				else{
					return False
				}
			}
			else{
				MsgBox, % this.Title "Set BottomY Error - Returning False because not this.BottomNeighborObj (" this.BottomNeighborObj.Title ") or False = (value (" value ") is Number And value >= this.Parent.TopY (" this.Parent.TopY ") + this.TopNeighborOffsetY (" this.TopNeighborOffsetY ") And value <= this.Parent.BottomY (" this.Parent.BottomY ") + this.BottomNeighborOffsetY (" this.BottomNeighborOffsetY "))"
				Return False
			}
		}
	}
	Parent :=
	Children := 
	;	 this, "LeftPane", "L", 	 this, 			"LeftX", 				2, 			this.RightPane, 	"LeftX", 				-3, 			this, "			TopY", 			20, 				this, 		"BottomY", 			-2
	__New(parent, title, titleImg, leftNeighborObj, leftNeighborXName, leftNeighborOffsetX, rightNeighborObj, rightNeighborXName, rightNeighborOffsetX, topNeighborObj, topNeighborYName, topNeighborOffsetY, bottomNeighborObj, bottomNeighborYName, bottomNeighborOffsetY){
		;MsgBox, % title
		this.Parent := parent
		this.Title:= title
		this.TitleImg := titleImg
		this.LeftNeighborObj := leftNeighborObj
		this.LeftNeighborXName := leftNeighborXName
		this.LeftNeighborOffsetX := leftNeighborOffsetX
		this.RightNeighborObj := rightNeighborObj
		this.RightNeighborXName := rightNeighborXName
		this.RightNeighborOffsetX := rightNeighborOffsetX
		this.TopNeighborObj := topNeighborObj
		this.TopNeighborYName := topNeighborYName
		this.TopNeighborOffsetY := topNeighborOffsetY
		this.BottomNeighborObj := bottomNeighborObj
		this.BottomNeighborYName := bottomNeighborYName
		this.BottomNeighborOffsetY := bottomNeighborOffsetY
		if(this.LeftNeighborObj = this.Parent){
			this.LeftX := this.Parent.LeftX + leftNeighborOffsetX
		}
		if(this.RightNeighborObj = this.Parent){
			this.RightX := this.Parent.RightX + rightNeighborOffsetX
		}
		if(this.TopNeighborObj = this.Parent){
			this.TopY := this.Parent.TopY + topNeighborOffsetY
		}
		if(this.BottomNeighborObj = this.Parent){
			this.BottomY := this.Parent.BottomY + bottomNeighborOffsetY
		}
	}
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Sarhad and 98 guests