Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "MR_PoseTool"

-- **************************************************
-- General information about this script
-- **************************************************

MR_PoseTool = {}

function MR_PoseTool:Name()
	return self:Localize('UILabel')
end

function MR_PoseTool:Version()
	return '3.2.1'
end

function MR_PoseTool:UILabel()
	return self:Localize('UILabel')
end

function MR_PoseTool:Creator()
	return 'Eugene Babich'
end

function MR_PoseTool:Description()
	return self:Localize('Description')
end

-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function MR_PoseTool:IsRelevant(moho)
	local skel = moho:Skeleton()
	if (skel == nil) and not self.skeletonLayersNavigation then
		return false
	end
	
	if not self.mohoVersion then
		if MR_Utilities then
			local v1, v2, v3 = MR_Utilities:GetMohoVersion(moho)
			self.mohoVersion = v1
		end
	end
	
	return true
end

function MR_PoseTool:IsEnabled(moho)
	return true
end

-- **************************************************
-- Recurring Values
-- **************************************************

MR_PoseTool.relativeKeyframingScale = true
MR_PoseTool.skeletonLayersNavigation = false
MR_PoseTool.quickMenuTooltips = true
MR_PoseTool.moveTargetParent = false
MR_PoseTool.doubleClickToSetKeyframe = true
MR_PoseTool.holdToReset = true
MR_PoseTool.blockOnEvenFrames = true
MR_PoseTool.blockOnOddFrames = false
MR_PoseTool.highlightBones = true
MR_PoseTool.highlightWidth = 3
MR_PoseTool.useHighlightCustomColor = false
MR_PoseTool.highlightOpacity = 1

MR_PoseTool.highlightCustomColorR = 255
MR_PoseTool.highlightCustomColorG = 0
MR_PoseTool.highlightCustomColorB = 0
MR_PoseTool.highlightCustomColorA = 255

MR_PoseTool.alignHandlesAlongBone = false
MR_PoseTool.handlesDistance = 1
MR_PoseTool.handleStrokeOpacity = 1
MR_PoseTool.handleFillOpacity = 1
MR_PoseTool.useCustomColors = false

MR_PoseTool.colorStrokeTranslateHandleR = 255
MR_PoseTool.colorStrokeTranslateHandleG = 0
MR_PoseTool.colorStrokeTranslateHandleB = 0
MR_PoseTool.colorStrokeTranslateHandleA = 255

MR_PoseTool.colorFillTranslateHandleR = 248
MR_PoseTool.colorFillTranslateHandleG = 121
MR_PoseTool.colorFillTranslateHandleB = 114
MR_PoseTool.colorFillTranslateHandleA = 255

MR_PoseTool.colorStrokeScaleHandleR = 255
MR_PoseTool.colorStrokeScaleHandleG = 0
MR_PoseTool.colorStrokeScaleHandleB = 0
MR_PoseTool.colorStrokeScaleHandleA = 255

MR_PoseTool.colorFillScaleHandleR = 248
MR_PoseTool.colorFillScaleHandleG = 121
MR_PoseTool.colorFillScaleHandleB = 114
MR_PoseTool.colorFillScaleHandleA = 255

MR_PoseTool.colorFollowBonesR = 46
MR_PoseTool.colorFollowBonesG = 120
MR_PoseTool.colorFollowBonesB = 255
MR_PoseTool.colorFollowBonesA = 255

MR_PoseTool.colorStrokeMoveJointHandleR = 255
MR_PoseTool.colorStrokeMoveJointHandleG = 63
MR_PoseTool.colorStrokeMoveJointHandleB = 15
MR_PoseTool.colorStrokeMoveJointHandleA = 255

MR_PoseTool.colorFillMoveJointHandleR = 255
MR_PoseTool.colorFillMoveJointHandleG = 189
MR_PoseTool.colorFillMoveJointHandleB = 46
MR_PoseTool.colorFillMoveJointHandleA = 255

MR_PoseTool.colorStrokeManipulateHandleR = 255
MR_PoseTool.colorStrokeManipulateHandleG = 63
MR_PoseTool.colorStrokeManipulateHandleB = 15
MR_PoseTool.colorStrokeManipulateHandleA = 255

MR_PoseTool.colorFillManipulateHandleR = 255
MR_PoseTool.colorFillManipulateHandleG = 189
MR_PoseTool.colorFillManipulateHandleB = 46
MR_PoseTool.colorFillManipulateHandleA = 255

MR_PoseTool.iconColorR = 34
MR_PoseTool.iconColorG = 70
MR_PoseTool.iconColorB = 65
MR_PoseTool.iconColorA = 255

MR_PoseTool.panelSizeShort = false
MR_PoseTool.twosMode = false
MR_PoseTool.keepSelection = false
MR_PoseTool.multiTransform = false
MR_PoseTool.lockHandles = false
MR_PoseTool.bakeAdjacentFrames = false
MR_PoseTool.firstBoneID = -1
MR_PoseTool.firstBonePos = LM.Vector2:new_local()
MR_PoseTool.firstBoneScalePercent = 50
MR_PoseTool.clickOffset = LM.Vector2:new_local()
MR_PoseTool.secondBoneID = -1
MR_PoseTool.isActive = true
MR_PoseTool.firstBoneOffset = 0
MR_PoseTool.secondBoneOffset = 0
MR_PoseTool.interval = 1
MR_PoseTool.showPath = false
MR_PoseTool.range = false
MR_PoseTool.rangeFrames = 10
MR_PoseTool.secondBonePos = LM.Vector2:new_local()
MR_PoseTool.secondBoneTipPos = LM.Vector2:new_local()
MR_PoseTool.firstDist = 0
MR_PoseTool.secondBoneDist = 0
MR_PoseTool.firstBoneParentID = -1
MR_PoseTool.firstBoneParentIBIK = false
MR_PoseTool.firstBoneSizeDelta = 0
MR_PoseTool.secondBoneSizeDelta = 0
MR_PoseTool.firstBoneAngleDelta = 0
MR_PoseTool.secondBoneAngleDelta = 0
MR_PoseTool.selectedBonesList = {}
MR_PoseTool.mousePickedID = -1
MR_PoseTool.mouseHoverID = -1
MR_PoseTool.dragging = false
MR_PoseTool.lastVec = LM.Vector2:new_local()
MR_PoseTool.lastVec2 = LM.Vector2:new_local()
MR_PoseTool.handlesDist = 0.075
MR_PoseTool.handlesDistY = 0.026
MR_PoseTool.handlesDistYMultiplier = 1
MR_PoseTool.additionmarkerDist = 0.05
MR_PoseTool.markerR = 6
MR_PoseTool.markerR2 = 6
MR_PoseTool.additionHandles = false
MR_PoseTool.startBonePos = LM.Vector2:new_local()
MR_PoseTool.startBoneAngleDelta = 0
MR_PoseTool.startBoneDist = 0
MR_PoseTool.TOLERANCE = 10
MR_PoseTool.transformPath = false
MR_PoseTool.drawMode = -1
MR_PoseTool.keepHandles = false
MR_PoseTool.height = 1080
MR_PoseTool.ignoreZeroScaledBones = true
MR_PoseTool.clickToSelect = false
MR_PoseTool.pickWidth = 10
MR_PoseTool.handlesDistanceTreshhold = 0.2
MR_PoseTool.followBonesList = {}
MR_PoseTool.followBonesList.id = {}
MR_PoseTool.followBonesList.names = {}
MR_PoseTool.followBonesList.length = {}
MR_PoseTool.followBonesList.startBone = {}
MR_PoseTool.followBonesList.endBone = {}
MR_PoseTool.ikBonesList = {}
MR_PoseTool.ikBonesList.id = {}
MR_PoseTool.ikBonesList.names = {}
MR_PoseTool.ikBonesList.length = {}
MR_PoseTool.ikBonesList.startBone = {}
MR_PoseTool.ikBonesList.endBone = {}
MR_PoseTool.startFollowBone = -1
MR_PoseTool.endFollowBone = -1
MR_PoseTool.boneStretching = false
MR_PoseTool.boneStretchingIconStatus = false
MR_PoseTool.isMouseDragging = false
MR_PoseTool.selRect = LM.Rect:new_local()
MR_PoseTool.forceFollowBonesGraphics = false
MR_PoseTool.iconsDistance = 0.08
MR_PoseTool.iconsRadius = 18
MR_PoseTool.showQuickMenu = false
MR_PoseTool.graphicsMenuCenter = LM.Vector2:new_local()
MR_PoseTool.mouseHoverIDGraphicMenu = -1
MR_PoseTool.graphicMenuMode = 0
MR_PoseTool.lockAngleList = {}
MR_PoseTool.lockAngleBoneNamesList = {}
MR_PoseTool.lockPosList = {}
MR_PoseTool.lockPosBoneNamesList = {}
MR_PoseTool.bonesReset = false
MR_PoseTool.multiSelectionUnselectedMovement = false
MR_PoseTool.showCross = false
MR_PoseTool.ignoreBonesList = {}
MR_PoseTool.scriptDataName = 'MR_PoseTool_'
MR_PoseTool.bonesDataActive = true
MR_PoseTool.bonesDataActiveF = true
MR_PoseTool.bonesDataActiveIK = true
MR_PoseTool.bonesDataActiveA = true
MR_PoseTool.bonesDataActiveP = true
MR_PoseTool.selBonesList = {}
MR_PoseTool.isBoneHaveAngleKeyList = {}
MR_PoseTool.isBoneHaveScaleKeyList = {}
MR_PoseTool.clickTime = 0
MR_PoseTool.setKeyframe = false
MR_PoseTool.onMMTreshold = false
MR_PoseTool.forceBoneTranslationAlt = false
MR_PoseTool.forceBoneTranslationShift = false
MR_PoseTool.singleFollowBonesMode = false
MR_PoseTool.scriptValidated = nil
MR_PoseTool.buttonPressed = 0
MR_PoseTool.operationFailes = 0
MR_PoseTool.enableFBExpanded = false
MR_PoseTool.ignoreUpdateWidgets = false
MR_PoseTool.blockQuickMenu = false

-- **************************************************
-- Prefs
-- **************************************************

function MR_PoseTool:LoadPrefs(prefs)
	self.relativeKeyframingScale = prefs:GetBool("MR_PoseTool.relativeKeyframingScale", true)
	self.skeletonLayersNavigation = prefs:GetBool("MR_PoseTool.skeletonLayersNavigation", false)
	self.quickMenuTooltips = prefs:GetBool("MR_PoseTool.quickMenuTooltips", true)
	self.doubleClickToSetKeyframe = prefs:GetBool("MR_PoseTool.doubleClickToSetKeyframe", true)
	self.holdToReset = prefs:GetBool("MR_PoseTool.holdToReset", true)
	self.moveTargetParent = prefs:GetBool("MR_PoseTool.moveTargetParent", false)
	self.blockOnEvenFrames = prefs:GetBool("MR_PoseTool.blockOnEvenFrames", true)
	self.blockOnOddFrames = prefs:GetBool("MR_PoseTool.blockOnOddFrames", false)
	self.highlightBones = prefs:GetBool("MR_PoseTool.highlightBones", true)
	self.highlightWidth = prefs:GetInt("MR_PoseTool.highlightWidth", 3)
	self.useHighlightCustomColor = prefs:GetBool("MR_PoseTool.useHighlightCustomColor", false)
	
	self.highlightCustomColorR = prefs:GetInt("MR_PoseTool.highlightCustomColorR", 255)
	self.highlightCustomColorG = prefs:GetInt("MR_PoseTool.highlightCustomColorG", 0)
	self.highlightCustomColorB = prefs:GetInt("MR_PoseTool.highlightCustomColorB", 0)
	self.highlightCustomColorA = prefs:GetInt("MR_PoseTool.highlightCustomColorA", 255)
	
	self.alignHandlesAlongBone = prefs:GetBool("MR_PoseTool.alignHandlesAlongBone", false)
	self.handlesDistance = prefs:GetFloat("MR_PoseTool.handlesDistance", 1)
	self.handleStrokeOpacity = prefs:GetFloat("MR_PoseTool.handleStrokeOpacity", 1)
	self.handleFillOpacity = prefs:GetFloat("MR_PoseTool.handleFillOpacity", 1)
	self.useCustomColors = prefs:GetBool("MR_PoseTool.useCustomColors", false)
	
	self.colorStrokeTranslateHandleR = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleR", 255)
	self.colorStrokeTranslateHandleG = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleG", 0)
	self.colorStrokeTranslateHandleB = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleB", 0)
	self.colorStrokeTranslateHandleA = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleA", 255)
	
	self.colorFillTranslateHandleR = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleR", 248)
	self.colorFillTranslateHandleG = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleG", 121)
	self.colorFillTranslateHandleB = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleB", 114)
	self.colorFillTranslateHandleA = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleA", 255)
	
	self.colorStrokeScaleHandleR = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleR", 255)
	self.colorStrokeScaleHandleG = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleG", 0)
	self.colorStrokeScaleHandleB = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleB", 0)
	self.colorStrokeScaleHandleA = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleA", 255)
	
	self.colorFillScaleHandleR = prefs:GetInt("MR_PoseTool.colorFillScaleHandleR", 248)
	self.colorFillScaleHandleG = prefs:GetInt("MR_PoseTool.colorFillScaleHandleG", 121)
	self.colorFillScaleHandleB = prefs:GetInt("MR_PoseTool.colorFillScaleHandleB", 114)
	self.colorFillScaleHandleA = prefs:GetInt("MR_PoseTool.colorFillScaleHandleA", 255)
	
	self.colorStrokeMoveJointHandleR = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleR", 255)
	self.colorStrokeMoveJointHandleG = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleG", 63)
	self.colorStrokeMoveJointHandleB = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleB", 15)
	self.colorStrokeMoveJointHandleA = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleA", 255)
	
	self.colorFillMoveJointHandleR = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleR", 255)
	self.colorFillMoveJointHandleG = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleG", 189)
	self.colorFillMoveJointHandleB = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleB", 46)
	self.colorFillMoveJointHandleA = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleA", 255)
	
	self.colorStrokeManipulateHandleR = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleR", 255)
	self.colorStrokeManipulateHandleG = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleG", 63)
	self.colorStrokeManipulateHandleB = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleB", 15)
	self.colorStrokeManipulateHandleA = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleA", 255)
	
	self.colorFillManipulateHandleR = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleR", 255)
	self.colorFillManipulateHandleG = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleG", 189)
	self.colorFillManipulateHandleB = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleB", 46)
	self.colorFillManipulateHandleA = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleA", 255)
	
	self.panelSizeShort = prefs:GetBool("MR_PoseTool.panelSizeShort", false)
	self.twosMode = prefs:GetBool("MR_PoseTool.twosMode", false)
	self.keepSelection = prefs:GetBool("MR_PoseTool.keepSelection", false)
	self.multiTransform = prefs:GetBool("MR_PoseTool.multiTransform", false)
	self.lockHandles = prefs:GetBool("MR_PoseTool.lockHandles", false)
	self.bakeAdjacentFrames = prefs:GetBool("MR_PoseTool.bakeAdjacentFrames", false)
	self.interval = prefs:GetInt("MR_PoseTool.interval", 1)
	self.showPath = prefs:GetBool("MR_PoseTool.showPath", false)
	self.range = prefs:GetBool("MR_PoseTool.range", false)
	self.rangeFrames = prefs:GetInt("MR_PoseTool.rangeFrames", 10)
end

function MR_PoseTool:SavePrefs(prefs)
	prefs:SetBool("MR_PoseTool.relativeKeyframingScale", self.relativeKeyframingScale)
	prefs:SetBool("MR_PoseTool.skeletonLayersNavigation", self.skeletonLayersNavigation)
	prefs:SetBool("MR_PoseTool.quickMenuTooltips", self.quickMenuTooltips)
	prefs:SetBool("MR_PoseTool.doubleClickToSetKeyframe", self.doubleClickToSetKeyframe)
	prefs:SetBool("MR_PoseTool.holdToReset", self.holdToReset)
	prefs:SetBool("MR_PoseTool.moveTargetParent", self.moveTargetParent)
	prefs:SetBool("MR_PoseTool.blockOnEvenFrames", self.blockOnEvenFrames)
	prefs:SetBool("MR_PoseTool.blockOnOddFrames", self.blockOnOddFrames)
	prefs:SetBool("MR_PoseTool.highlightBones", self.highlightBones)
	prefs:SetInt("MR_PoseTool.highlightWidth", self.highlightWidth)
	prefs:SetBool("MR_PoseTool.useHighlightCustomColor", self.useHighlightCustomColor)
	
	prefs:SetInt("MR_PoseTool.highlightCustomColorR", self.highlightCustomColorR)
	prefs:SetInt("MR_PoseTool.highlightCustomColorG", self.highlightCustomColorG)
	prefs:SetInt("MR_PoseTool.highlightCustomColorB", self.highlightCustomColorB)
	prefs:SetInt("MR_PoseTool.highlightCustomColorA", self.highlightCustomColorA)
	
	prefs:SetBool("MR_PoseTool.alignHandlesAlongBone", self.alignHandlesAlongBone)
	prefs:SetFloat("MR_PoseTool.handlesDistance", self.handlesDistance)
	prefs:SetFloat("MR_PoseTool.handleStrokeOpacity", self.handleStrokeOpacity)
	prefs:SetFloat("MR_PoseTool.handleFillOpacity", self.handleFillOpacity)
	prefs:SetBool("MR_PoseTool.useCustomColors", self.useCustomColors)
	
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleR", self.colorStrokeTranslateHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleG", self.colorStrokeTranslateHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleB", self.colorStrokeTranslateHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleA", self.colorStrokeTranslateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleR", self.colorFillTranslateHandleR)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleG", self.colorFillTranslateHandleG)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleB", self.colorFillTranslateHandleB)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleA", self.colorFillTranslateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleR", self.colorStrokeScaleHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleG", self.colorStrokeScaleHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleB", self.colorStrokeScaleHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleA", self.colorStrokeScaleHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleR", self.colorFillScaleHandleR)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleG", self.colorFillScaleHandleG)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleB", self.colorFillScaleHandleB)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleA", self.colorFillScaleHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleR", self.colorStrokeMoveJointHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleG", self.colorStrokeMoveJointHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleB", self.colorStrokeMoveJointHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleA", self.colorStrokeMoveJointHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleR", self.colorFillMoveJointHandleR)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleG", self.colorFillMoveJointHandleG)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleB", self.colorFillMoveJointHandleB)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleA", self.colorFillMoveJointHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleR", self.colorStrokeManipulateHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleG", self.colorStrokeManipulateHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleB", self.colorStrokeManipulateHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleA", self.colorStrokeManipulateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleR", self.colorFillManipulateHandleR)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleG", self.colorFillManipulateHandleG)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleB", self.colorFillManipulateHandleB)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleA", self.colorFillManipulateHandleA)
	
	prefs:SetBool("MR_PoseTool.panelSizeShort", self.panelSizeShort)
	prefs:SetBool("MR_PoseTool.twosMode", self.twosMode)
	prefs:SetBool("MR_PoseTool.keepSelection", self.keepSelection)
	prefs:SetBool("MR_PoseTool.multiTransform", self.multiTransform)
	prefs:SetBool("MR_PoseTool.lockHandles", self.lockHandles)
	prefs:SetBool("MR_PoseTool.bakeAdjacentFrames", self.bakeAdjacentFrames)
	prefs:SetInt("MR_PoseTool.interval", self.interval)
	prefs:SetBool("MR_PoseTool.showPath", self.showPath)
	prefs:SetBool("MR_PoseTool.range", self.range)
	prefs:SetInt("MR_PoseTool.rangeFrames", self.rangeFrames)
end

function MR_PoseTool:ResetPrefs()
	self.relativeKeyframingScale = true
	self.skeletonLayersNavigation = false
	self.quickMenuTooltips = true
	self.doubleClickToSetKeyframe = true
	self.holdToReset = true
	self.moveTargetParent = false
	self.blockOnEvenFrames = true
	self.blockOnOddFrames = false
	self.highlightBones = true
	self.highlightWidth = 3
	self.useHighlightCustomColor = false
	
	self.highlightCustomColorR = 255
	self.highlightCustomColorG = 0
	self.highlightCustomColorB = 0
	self.highlightCustomColorA = 255
	
	self.alignHandlesAlongBone = false
	self.handlesDistance = 1
	self.handleFillOpacity = 1
	self.useCustomColors = false
	
	self.colorStrokeTranslateHandleR = 255
	self.colorStrokeTranslateHandleG = 0
	self.colorStrokeTranslateHandleB = 0
	self.colorStrokeTranslateHandleA = 255

	self.colorFillTranslateHandleR = 248
	self.colorFillTranslateHandleG = 121
	self.colorFillTranslateHandleB = 114
	self.colorFillTranslateHandleA = 255

	self.colorStrokeScaleHandleR = 255
	self.colorStrokeScaleHandleG = 0
	self.colorStrokeScaleHandleB = 0
	self.colorStrokeScaleHandleA = 255

	self.colorFillScaleHandleR = 248
	self.colorFillScaleHandleG = 121
	self.colorFillScaleHandleB = 114
	self.colorFillScaleHandleA = 255

	self.colorStrokeMoveJointHandleR = 255
	self.colorStrokeMoveJointHandleG = 63
	self.colorStrokeMoveJointHandleB = 15
	self.colorStrokeMoveJointHandleA = 255

	self.colorFillMoveJointHandleR = 255
	self.colorFillMoveJointHandleG = 189
	self.colorFillMoveJointHandleB = 46
	self.colorFillMoveJointHandleA = 255

	self.colorStrokeManipulateHandleR = 255
	self.colorStrokeManipulateHandleG = 63
	self.colorStrokeManipulateHandleB = 15
	self.colorStrokeManipulateHandleA = 255

	self.colorFillManipulateHandleR = 255
	self.colorFillManipulateHandleG = 189
	self.colorFillManipulateHandleB = 46
	self.colorFillManipulateHandleA = 255
	
	self.panelSizeShort = false
	self.twosMode = false
	self.keepSelection = false
	self.multiTransform = false
	self.lockHandles = false
	self.bakeAdjacentFrames = false
	self.interval = 1
	self.showPath = false
	self.range = false
	self.rangeFrames = 10
end

function MR_PoseTool:NonDragMouseMove()
	return true -- Call MouseMoved() even if the mouse button is not down
end

-- **************************************************
-- MR_PoseToolInfoDialog
-- **************************************************

local MR_PoseToolInfoDialog = {}

MR_PoseToolInfoDialog.INFO = MOHO.MSG_BASE

function MR_PoseToolInfoDialog:new(moho)
    local d = LM.GUI.SimpleDialog(MR_PoseTool:Localize('UILabel'), MR_PoseToolInfoDialog)
    local l = d:GetLayout()

	d.infoButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_pose_tool_cheat_sheet', '', false, self.INFO, false)
	
	l:AddChild(d.infoButton, LM.GUI.ALIGN_FILL, 0)

	return d
end

function MR_PoseToolInfoDialog:UpdateWidgets(moho)
end

function MR_PoseToolInfoDialog:OnOK(moho)
end

-- **************************************************
-- Settings Menu
-- **************************************************

local MR_PoseToolSettingsDialog = {}

MR_PoseToolSettingsDialog.RELATIVE_KEYFRAMING_SCALE = MOHO.MSG_BASE
MR_PoseToolSettingsDialog.SKELETON_LAYERS_NAVIGATION = MOHO.MSG_BASE + 1
MR_PoseToolSettingsDialog.QUICK_MENU_TOOLTIPS = MOHO.MSG_BASE + 2
MR_PoseToolSettingsDialog.DOUBLE_CLICK_TO_SET_KEYFRAME = MOHO.MSG_BASE + 3
MR_PoseToolSettingsDialog.HOLD_TO_RESET = MOHO.MSG_BASE + 4
MR_PoseToolSettingsDialog.MOVE_TARGET_PARENT = MOHO.MSG_BASE + 5
MR_PoseToolSettingsDialog.BLOCK_ON_EVEN_FRAMES = MOHO.MSG_BASE + 6
MR_PoseToolSettingsDialog.BLOCK_ON_ODD_FRAMES = MOHO.MSG_BASE + 7
MR_PoseToolSettingsDialog.HIGHLIGHT_BONES = MOHO.MSG_BASE + 8
MR_PoseToolSettingsDialog.HIGHLIGHT_WIDTH = MOHO.MSG_BASE + 9
MR_PoseToolSettingsDialog.HIGHLIGHT_OPACITY = MOHO.MSG_BASE + 10
MR_PoseToolSettingsDialog.USE_HIGHLIGHT_CUSTOM_COLOR = MOHO.MSG_BASE + 11
MR_PoseToolSettingsDialog.HIGHLIGHT_CUSTOM_COLOR = MOHO.MSG_BASE + 12
MR_PoseToolSettingsDialog.ALIGN_HANDLES_ALONG_BONE = MOHO.MSG_BASE + 13
MR_PoseToolSettingsDialog.HANDLES_DISTANCE = MOHO.MSG_BASE + 14
MR_PoseToolSettingsDialog.HANDLES_STROKE_OPACITY = MOHO.MSG_BASE + 15
MR_PoseToolSettingsDialog.HANDLES_FILL_OPACITY = MOHO.MSG_BASE + 16
MR_PoseToolSettingsDialog.USE_CUSTOM_COLORS = MOHO.MSG_BASE + 17
MR_PoseToolSettingsDialog.COLOR_TRANSLATE_STROKE = MOHO.MSG_BASE + 18
MR_PoseToolSettingsDialog.COLOR_TRANSLATE_FILL = MOHO.MSG_BASE + 19
MR_PoseToolSettingsDialog.COLOR_SCALE_STROKE = MOHO.MSG_BASE + 20
MR_PoseToolSettingsDialog.COLOR_SCALE_FILL = MOHO.MSG_BASE + 21
MR_PoseToolSettingsDialog.COLOR_MOVE_JOINT_STROKE = MOHO.MSG_BASE + 22
MR_PoseToolSettingsDialog.COLOR_MOVE_JOINT_FILL = MOHO.MSG_BASE + 23
MR_PoseToolSettingsDialog.COLOR_MANIPULATE_STROKE = MOHO.MSG_BASE + 24
MR_PoseToolSettingsDialog.COLOR_MANIPULATE_FILL = MOHO.MSG_BASE + 25
MR_PoseToolSettingsDialog.RESET_COLOR = MOHO.MSG_BASE + 26

function MR_PoseToolSettingsDialog:new()
	local d = LM.GUI.SimpleDialog(MR_PoseTool:Localize('UILabel'), MR_PoseToolSettingsDialog)
    local l = d:GetLayout()
	
	d.relativeKeyframingScaleCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Relative keyframing scale'), self.RELATIVE_KEYFRAMING_SCALE)
    l:AddChild(d.relativeKeyframingScaleCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	d.skeletonLayersNavigationCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Skeleton layers navigation'), self.SKELETON_LAYERS_NAVIGATION)
    l:AddChild(d.skeletonLayersNavigationCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	if HV_Font then
		d.quickMenuTooltipsCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Quick menu tooltips'), self.QUICK_MENU_TOOLTIPS)
		l:AddChild(d.quickMenuTooltipsCheck, LM.GUI.ALIGN_LEFT, 0)
	end
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.doubleClickToSetKeyframeCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Double-click to set keyframe'), self.DOUBLE_CLICK_TO_SET_KEYFRAME)
    l:AddChild(d.doubleClickToSetKeyframeCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.holdToResetCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Click and hold to reset'), self.HOLD_TO_RESET)
    l:AddChild(d.holdToResetCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.moveTargetParentCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Move target parent'), self.MOVE_TARGET_PARENT)
    l:AddChild(d.moveTargetParentCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.blockOnEvenFramesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Block on even frames'), self.BLOCK_ON_EVEN_FRAMES)
    l:AddChild(d.blockOnEvenFramesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.blockOnOddFramesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Block on odd frames'), self.BLOCK_ON_ODD_FRAMES)
    l:AddChild(d.blockOnOddFramesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.highlightBonesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Highlight bones'), self.HIGHLIGHT_BONES)
    l:AddChild(d.highlightBonesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.highlightWidthInput = LM.GUI.TextControl(0, '100', self.HIGHLIGHT_WIDTH, LM.GUI.FIELD_INT, MR_PoseTool:Localize('Highlight width:'))
    l:AddChild(d.highlightWidthInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.highlightOpacityInput = LM.GUI.TextControl(0, '100', self.HIGHLIGHT_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Highlight opacity:'))
	d.highlightOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.highlightOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:PushH()
	
		d.useHighlightCustomColorCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Custom'), self.USE_HIGHLIGHT_CUSTOM_COLOR)
		l:AddChild(d.useHighlightCustomColorCheck, LM.GUI.ALIGN_LEFT, 0)
		
		d.highlightCustomColorSwatch = LM.GUI.ShortColorSwatch(true, self.HIGHLIGHT_CUSTOM_COLOR)
		l:AddChild(d.highlightCustomColorSwatch, LM.GUI.ALIGN_LEFT)
	
	l:Pop()
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.alignHandlesAlongBoneCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Align handles along bone'), self.ALIGN_HANDLES_ALONG_BONE)
    l:AddChild(d.alignHandlesAlongBoneCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	d.handlesDistanceInput = LM.GUI.TextControl(0, '100', self.HANDLES_DISTANCE, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles distance:'))
	d.handlesDistanceInput:SetWheelInc(0.01)
    l:AddChild(d.handlesDistanceInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.handlesStrokeOpacityInput = LM.GUI.TextControl(0, '100', self.HANDLES_STROKE_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles stroke opacity:'))
	d.handlesStrokeOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.handlesStrokeOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.handlesFillOpacityInput = LM.GUI.TextControl(0, '100', self.HANDLES_FILL_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles fill opacity:'))
	d.handlesFillOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.handlesFillOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.useCustomColorsInput = LM.GUI.CheckBox(MR_PoseTool:Localize('Use custom colors'), self.USE_CUSTOM_COLORS)
    l:AddChild(d.useCustomColorsInput, LM.GUI.ALIGN_LEFT, 0)
	
	l:PushH()
	
		d.colorTranslateStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_TRANSLATE_STROKE)
		l:AddChild(d.colorTranslateStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorTranslateStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Translate handle stroke color Tooltip'))
		
		d.colorTranslateFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_TRANSLATE_FILL)
		l:AddChild(d.colorTranslateFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorTranslateFillSwatch:SetToolTip(MR_PoseTool:Localize('Translate handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorScaleStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_SCALE_STROKE)
		l:AddChild(d.colorScaleStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorScaleStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Scale handle stroke color Tooltip'))
		
		d.colorScaleFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_SCALE_FILL)
		l:AddChild(d.colorScaleFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorScaleFillSwatch:SetToolTip(MR_PoseTool:Localize('Scale handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorMoveJointStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MOVE_JOINT_STROKE)
		l:AddChild(d.colorMoveJointStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorMoveJointStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Move joint handle stroke color Tooltip'))
		
		d.colorMoveJointFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MOVE_JOINT_FILL)
		l:AddChild(d.colorMoveJointFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorMoveJointFillSwatch:SetToolTip(MR_PoseTool:Localize('Move joint handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorManipulateStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MANIPULATE_STROKE)
		l:AddChild(d.colorManipulateStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorManipulateStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Manipulate handle stroke color Tooltip'))
		
		d.colorManipulatFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MANIPULATE_FILL)
		l:AddChild(d.colorManipulatFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorManipulatFillSwatch:SetToolTip(MR_PoseTool:Localize('Manipulate handle fill color Tooltip'))
	
	l:Pop()
	
	d.resetColorButton = LM.GUI.Button(MR_PoseTool:Localize('Reset colors'), self.RESET_COLOR)
	l:AddChild(d.resetColorButton, LM.GUI.ALIGN_FILL, 0)
	
	return d
end

function MR_PoseToolSettingsDialog:UpdateWidgets(moho)
	if HV_Font then
		self.quickMenuTooltipsCheck:SetValue(MR_PoseTool.quickMenuTooltips)
	end
    self.relativeKeyframingScaleCheck:SetValue(MR_PoseTool.relativeKeyframingScale)
    self.skeletonLayersNavigationCheck:SetValue(MR_PoseTool.skeletonLayersNavigation)
    self.doubleClickToSetKeyframeCheck:SetValue(MR_PoseTool.doubleClickToSetKeyframe)
    self.holdToResetCheck:SetValue(MR_PoseTool.holdToReset)
    self.moveTargetParentCheck:SetValue(MR_PoseTool.moveTargetParent)
    self.blockOnEvenFramesCheck:SetValue(MR_PoseTool.blockOnEvenFrames)
    self.blockOnOddFramesCheck:SetValue(MR_PoseTool.blockOnOddFrames)
    self.highlightBonesCheck:SetValue(MR_PoseTool.highlightBones)
    self.highlightWidthInput:SetValue(MR_PoseTool.highlightWidth)
    self.highlightOpacityInput:SetValue(MR_PoseTool.highlightOpacity)
    self.useHighlightCustomColorCheck:SetValue(MR_PoseTool.useHighlightCustomColor)
    self.alignHandlesAlongBoneCheck:SetValue(MR_PoseTool.alignHandlesAlongBone)
	if MR_PoseTool.alignHandlesAlongBone then
		self.handlesDistanceInput:Enable(false)
	else
		self.handlesDistanceInput:Enable(true)
	end
    self.handlesDistanceInput:SetValue(MR_PoseTool.handlesDistance)
    self.handlesStrokeOpacityInput:SetValue(MR_PoseTool.handleStrokeOpacity)
    self.handlesFillOpacityInput:SetValue(MR_PoseTool.handleFillOpacity)
    self.useCustomColorsInput:SetValue(MR_PoseTool.useCustomColors)
	
	if MR_PoseTool.useCustomColors then
		self.colorTranslateStrokeSwatch:Enable(true)
		self.colorTranslateFillSwatch:Enable(true)
		self.colorScaleStrokeSwatch:Enable(true)
		self.colorScaleFillSwatch:Enable(true)
		self.colorMoveJointStrokeSwatch:Enable(true)
		self.colorMoveJointFillSwatch:Enable(true)
		self.colorManipulateStrokeSwatch:Enable(true)
		self.colorManipulatFillSwatch:Enable(true)
		self.resetColorButton:Enable(true)
	else
		self.colorTranslateStrokeSwatch:Enable(false)
		self.colorTranslateFillSwatch:Enable(false)
		self.colorScaleStrokeSwatch:Enable(false)
		self.colorScaleFillSwatch:Enable(false)
		self.colorMoveJointStrokeSwatch:Enable(false)
		self.colorMoveJointFillSwatch:Enable(false)
		self.colorManipulateStrokeSwatch:Enable(false)
		self.colorManipulatFillSwatch:Enable(false)
		self.resetColorButton:Enable(false)
	end
	
	if MR_PoseTool.highlightBones then
		self.highlightWidthInput:Enable(true)
		self.highlightOpacityInput:Enable(true)
		self.useHighlightCustomColorCheck:Enable(true)
	else
		self.highlightWidthInput:Enable(false)
		self.highlightOpacityInput:Enable(false)
		self.useHighlightCustomColorCheck:Enable(false)
	end
	
	if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
		self.highlightCustomColorSwatch:Enable(true)
	else
		self.highlightCustomColorSwatch:Enable(false)
	end
	
	local highlightCustomColor = LM.rgb_color:new_local()
	highlightCustomColor.r = MR_PoseTool.highlightCustomColorR
	highlightCustomColor.g = MR_PoseTool.highlightCustomColorG
	highlightCustomColor.b = MR_PoseTool.highlightCustomColorB
	highlightCustomColor.a = 255
	
	self.highlightCustomColorSwatch:SetValue(highlightCustomColor)
	
	local colorTranslateStroke = LM.rgb_color:new_local()
	colorTranslateStroke.r = MR_PoseTool.colorStrokeTranslateHandleR
	colorTranslateStroke.g = MR_PoseTool.colorStrokeTranslateHandleG
	colorTranslateStroke.b = MR_PoseTool.colorStrokeTranslateHandleB
	colorTranslateStroke.a = 255
	
	self.colorTranslateStrokeSwatch:SetValue(colorTranslateStroke)
	
	local colorTranslateFill = LM.rgb_color:new_local()
	colorTranslateFill.r = MR_PoseTool.colorFillTranslateHandleR
	colorTranslateFill.g = MR_PoseTool.colorFillTranslateHandleG
	colorTranslateFill.b = MR_PoseTool.colorFillTranslateHandleB
	colorTranslateFill.a = 255
	
	self.colorTranslateFillSwatch:SetValue(colorTranslateFill)
	
	local colorScaleStroke = LM.rgb_color:new_local()
	colorScaleStroke.r = MR_PoseTool.colorStrokeScaleHandleR
	colorScaleStroke.g = MR_PoseTool.colorStrokeScaleHandleG
	colorScaleStroke.b = MR_PoseTool.colorStrokeScaleHandleB
	colorScaleStroke.a = 255

	self.colorScaleStrokeSwatch:SetValue(colorScaleStroke)
	
	local colorScaleFill = LM.rgb_color:new_local()
	colorScaleFill.r = MR_PoseTool.colorFillScaleHandleR
	colorScaleFill.g = MR_PoseTool.colorFillScaleHandleG
	colorScaleFill.b = MR_PoseTool.colorFillScaleHandleB
	colorScaleFill.a = 255

	self.colorScaleFillSwatch:SetValue(colorScaleFill)
	
	local colorMoveJointStroke = LM.rgb_color:new_local()
	colorMoveJointStroke.r = MR_PoseTool.colorStrokeMoveJointHandleR
	colorMoveJointStroke.g = MR_PoseTool.colorStrokeMoveJointHandleG
	colorMoveJointStroke.b = MR_PoseTool.colorStrokeMoveJointHandleB
	colorMoveJointStroke.a = 255

	self.colorMoveJointStrokeSwatch:SetValue(colorMoveJointStroke)
	
	local colorMoveJointFill = LM.rgb_color:new_local()
	colorMoveJointFill.r = MR_PoseTool.colorFillMoveJointHandleR
	colorMoveJointFill.g = MR_PoseTool.colorFillMoveJointHandleG
	colorMoveJointFill.b = MR_PoseTool.colorFillMoveJointHandleB
	colorMoveJointFill.a = 255

	self.colorMoveJointFillSwatch:SetValue(colorMoveJointFill)

	local colorManipulateStroke = LM.rgb_color:new_local()
	colorManipulateStroke.r = MR_PoseTool.colorStrokeManipulateHandleR
	colorManipulateStroke.g = MR_PoseTool.colorStrokeManipulateHandleG
	colorManipulateStroke.b = MR_PoseTool.colorStrokeManipulateHandleB
	colorManipulateStroke.a = 255

	self.colorManipulateStrokeSwatch:SetValue(colorManipulateStroke)
	
	local colorManipulateFill = LM.rgb_color:new_local()
	colorManipulateFill.r = MR_PoseTool.colorFillManipulateHandleR
	colorManipulateFill.g = MR_PoseTool.colorFillManipulateHandleG
	colorManipulateFill.b = MR_PoseTool.colorFillManipulateHandleB
	colorManipulateFill.a = 255

	self.colorManipulatFillSwatch:SetValue(colorManipulateFill)
end

function MR_PoseToolSettingsDialog:OnOK(moho)
	if HV_Font then
		MR_PoseTool.quickMenuTooltips = self.quickMenuTooltipsCheck:Value()
	end
    MR_PoseTool.relativeKeyframingScale = self.relativeKeyframingScaleCheck:Value()
    MR_PoseTool.skeletonLayersNavigation = self.skeletonLayersNavigationCheck:Value()
    MR_PoseTool.doubleClickToSetKeyframe = self.doubleClickToSetKeyframeCheck:Value()
    MR_PoseTool.holdToReset = self.holdToResetCheck:Value()
    MR_PoseTool.moveTargetParent = self.moveTargetParentCheck:Value()
    MR_PoseTool.blockOnEvenFrames = self.blockOnEvenFramesCheck:Value()
    MR_PoseTool.blockOnOddFrames = self.blockOnOddFramesCheck:Value()
    MR_PoseTool.highlightBones = self.highlightBonesCheck:Value()
    MR_PoseTool.highlightWidth = self.highlightWidthInput:Value()
    MR_PoseTool.highlightOpacity = self.highlightOpacityInput:Value()
    MR_PoseTool.useHighlightCustomColor = self.useHighlightCustomColorCheck:Value()
    MR_PoseTool.alignHandlesAlongBone = self.alignHandlesAlongBoneCheck:Value()
    MR_PoseTool.handlesDistance = self.handlesDistanceInput:Value()
    MR_PoseTool.handleFillOpacity = self.handlesFillOpacityInput:Value()
    MR_PoseTool.useCustomColors = self.useCustomColorsInput:Value()
end

function MR_PoseToolSettingsDialog:HandleMessage(msg)
	local needRedraw = false
	if msg == self.RELATIVE_KEYFRAMING_SCALE then
		MR_PoseTool.relativeKeyframingScale = self.relativeKeyframingScaleCheck:Value()
	elseif msg == self.SKELETON_LAYERS_NAVIGATION then
		MR_PoseTool.skeletonLayersNavigation = self.skeletonLayersNavigationCheck:Value()
	elseif msg == self.QUICK_MENU_TOOLTIPS then
		MR_PoseTool.quickMenuTooltips = self.quickMenuTooltipsCheck:Value()
	elseif msg == self.DOUBLE_CLICK_TO_SET_KEYFRAME then
		MR_PoseTool.doubleClickToSetKeyframe = self.doubleClickToSetKeyframeCheck:Value()
	elseif msg == self.HOLD_TO_RESET then
		MR_PoseTool.holdToReset = self.holdToResetCheck:Value()
	elseif msg == self.MOVE_TARGET_PARENT then
		MR_PoseTool.moveTargetParent = self.moveTargetParentCheck:Value()
	elseif msg == self.BLOCK_ON_EVEN_FRAMES then
		MR_PoseTool.blockOnEvenFrames = self.blockOnEvenFramesCheck:Value()
	elseif msg == self.BLOCK_ON_ODD_FRAMES then
		MR_PoseTool.blockOnOddFrames = self.blockOnOddFramesCheck:Value()
	elseif msg == self.HIGHLIGHT_BONES then
		MR_PoseTool.highlightBones = self.highlightBonesCheck:Value()
		if MR_PoseTool.highlightBones then
			self.highlightWidthInput:Enable(true)
			self.highlightOpacityInput:Enable(true)
			self.useHighlightCustomColorCheck:Enable(true)
		else
			self.highlightWidthInput:Enable(false)
			self.highlightOpacityInput:Enable(false)
			self.useHighlightCustomColorCheck:Enable(false)
		end
		
		if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
			self.highlightCustomColorSwatch:Enable(true)
		else
			self.highlightCustomColorSwatch:Enable(false)
		end
		needRedraw = true
	elseif msg == self.HIGHLIGHT_WIDTH then
		MR_PoseTool.highlightWidth = LM.Clamp(self.highlightWidthInput:Value(), 1, 12)
		self.highlightWidthInput:SetValue(MR_PoseTool.highlightWidth)
		needRedraw = true
	elseif msg == self.HIGHLIGHT_OPACITY then
		MR_PoseTool.highlightOpacity = LM.Clamp(self.highlightOpacityInput:Value(), 0, 1)
		self.highlightOpacityInput:SetValue(MR_PoseTool.highlightOpacity)
		needRedraw = true
	elseif msg == self.USE_HIGHLIGHT_CUSTOM_COLOR then
		MR_PoseTool.useHighlightCustomColor = self.useHighlightCustomColorCheck:Value()
		if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
			self.highlightCustomColorSwatch:Enable(true)
		else
			self.highlightCustomColorSwatch:Enable(false)
		end
		needRedraw = true
	elseif msg == self.HIGHLIGHT_CUSTOM_COLOR then
		local colorSwatchValue = self.highlightCustomColorSwatch:Value()
		MR_PoseTool.highlightCustomColorR = colorSwatchValue.r
		MR_PoseTool.highlightCustomColorG = colorSwatchValue.g
		MR_PoseTool.highlightCustomColorB = colorSwatchValue.b
		MR_PoseTool.highlightCustomColorA = 255
		needRedraw = true
	elseif msg == self.ALIGN_HANDLES_ALONG_BONE then
		MR_PoseTool.alignHandlesAlongBone = self.alignHandlesAlongBoneCheck:Value()
		if MR_PoseTool.alignHandlesAlongBone then
		self.handlesDistanceInput:Enable(false)
		else
			self.handlesDistanceInput:Enable(true)
		end
		needRedraw = true
	elseif msg == self.HANDLES_DISTANCE then
		MR_PoseTool.handlesDistance = LM.Clamp(self.handlesDistanceInput:Value(), 0.5, 2)
		self.handlesDistanceInput:SetValue(MR_PoseTool.handlesDistance)
		needRedraw = true
	elseif msg == self.HANDLES_STROKE_OPACITY then
		MR_PoseTool.handleStrokeOpacity = LM.Clamp(self.handlesStrokeOpacityInput:Value(), 0, 1)
		self.handlesStrokeOpacityInput:SetValue(MR_PoseTool.handleStrokeOpacity)
		needRedraw = true
	elseif msg == self.HANDLES_FILL_OPACITY then
		MR_PoseTool.handleFillOpacity = LM.Clamp(self.handlesFillOpacityInput:Value(), 0, 1)
		self.handlesFillOpacityInput:SetValue(MR_PoseTool.handleFillOpacity)
		needRedraw = true
	elseif msg == self.USE_CUSTOM_COLORS then
		MR_PoseTool.useCustomColors = self.useCustomColorsInput:Value()
		if MR_PoseTool.useCustomColors then
			self.colorTranslateStrokeSwatch:Enable(true)
			self.colorTranslateFillSwatch:Enable(true)
			self.colorScaleStrokeSwatch:Enable(true)
			self.colorScaleFillSwatch:Enable(true)
			self.colorMoveJointStrokeSwatch:Enable(true)
			self.colorMoveJointFillSwatch:Enable(true)
			self.colorManipulateStrokeSwatch:Enable(true)
			self.colorManipulatFillSwatch:Enable(true)
			self.resetColorButton:Enable(true)
		else
			self.colorTranslateStrokeSwatch:Enable(false)
			self.colorTranslateFillSwatch:Enable(false)
			self.colorScaleStrokeSwatch:Enable(false)
			self.colorScaleFillSwatch:Enable(false)
			self.colorMoveJointStrokeSwatch:Enable(false)
			self.colorMoveJointFillSwatch:Enable(false)
			self.colorManipulateStrokeSwatch:Enable(false)
			self.colorManipulatFillSwatch:Enable(false)
			self.resetColorButton:Enable(false)
		end
		needRedraw = true
	elseif msg == self.COLOR_TRANSLATE_STROKE then
		local colorSwatchValue = self.colorTranslateStrokeSwatch:Value()
		MR_PoseTool.colorStrokeTranslateHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeTranslateHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeTranslateHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeTranslateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_TRANSLATE_FILL then
		local colorSwatchValue = self.colorTranslateFillSwatch:Value()
		MR_PoseTool.colorFillTranslateHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillTranslateHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillTranslateHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillTranslateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_SCALE_STROKE then
		local colorSwatchValue = self.colorScaleStrokeSwatch:Value()
		MR_PoseTool.colorStrokeScaleHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeScaleHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeScaleHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeScaleHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_SCALE_FILL then
		local colorSwatchValue = self.colorScaleFillSwatch:Value()
		MR_PoseTool.colorFillScaleHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillScaleHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillScaleHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillScaleHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MOVE_JOINT_STROKE then
		local colorSwatchValue = self.colorMoveJointStrokeSwatch:Value()
		MR_PoseTool.colorStrokeMoveJointHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeMoveJointHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeMoveJointHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeMoveJointHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MOVE_JOINT_FILL then
		local colorSwatchValue = self.colorMoveJointFillSwatch:Value()
		MR_PoseTool.colorFillMoveJointHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillMoveJointHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillMoveJointHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillMoveJointHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MANIPULATE_STROKE then
		local colorSwatchValue = self.colorManipulateStrokeSwatch:Value()
		MR_PoseTool.colorStrokeManipulateHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeManipulateHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeManipulateHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeManipulateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MANIPULATE_FILL then
		local colorSwatchValue = self.colorManipulatFillSwatch:Value()
		MR_PoseTool.colorFillManipulateHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillManipulateHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillManipulateHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillManipulateHandleA = 255
		needRedraw = true
	elseif msg == self.RESET_COLOR then
		MR_PoseTool.colorStrokeTranslateHandleR = 255
		MR_PoseTool.colorStrokeTranslateHandleG = 0
		MR_PoseTool.colorStrokeTranslateHandleB = 0
		MR_PoseTool.colorStrokeTranslateHandleA = 255

		MR_PoseTool.colorFillTranslateHandleR = 248
		MR_PoseTool.colorFillTranslateHandleG = 121
		MR_PoseTool.colorFillTranslateHandleB = 114
		MR_PoseTool.colorFillTranslateHandleA = 255

		MR_PoseTool.colorStrokeScaleHandleR = 255
		MR_PoseTool.colorStrokeScaleHandleG = 0
		MR_PoseTool.colorStrokeScaleHandleB = 0
		MR_PoseTool.colorStrokeScaleHandleA = 255

		MR_PoseTool.colorFillScaleHandleR = 248
		MR_PoseTool.colorFillScaleHandleG = 121
		MR_PoseTool.colorFillScaleHandleB = 114
		MR_PoseTool.colorFillScaleHandleA = 255

		MR_PoseTool.colorStrokeMoveJointHandleR = 255
		MR_PoseTool.colorStrokeMoveJointHandleG = 63
		MR_PoseTool.colorStrokeMoveJointHandleB = 15
		MR_PoseTool.colorStrokeMoveJointHandleA = 255

		MR_PoseTool.colorFillMoveJointHandleR = 255
		MR_PoseTool.colorFillMoveJointHandleG = 189
		MR_PoseTool.colorFillMoveJointHandleB = 46
		MR_PoseTool.colorFillMoveJointHandleA = 255

		MR_PoseTool.colorStrokeManipulateHandleR = 255
		MR_PoseTool.colorStrokeManipulateHandleG = 63
		MR_PoseTool.colorStrokeManipulateHandleB = 15
		MR_PoseTool.colorStrokeManipulateHandleA = 255

		MR_PoseTool.colorFillManipulateHandleR = 255
		MR_PoseTool.colorFillManipulateHandleG = 189
		MR_PoseTool.colorFillManipulateHandleB = 46
		MR_PoseTool.colorFillManipulateHandleA = 255
		
		local colorTranslateStroke = LM.rgb_color:new_local()
		colorTranslateStroke.r = MR_PoseTool.colorStrokeTranslateHandleR
		colorTranslateStroke.g = MR_PoseTool.colorStrokeTranslateHandleG
		colorTranslateStroke.b = MR_PoseTool.colorStrokeTranslateHandleB
		colorTranslateStroke.a = MR_PoseTool.colorStrokeTranslateHandleA
		
		self.colorTranslateStrokeSwatch:SetValue(colorTranslateStroke)
		
		local colorTranslateFill = LM.rgb_color:new_local()
		colorTranslateFill.r = MR_PoseTool.colorFillTranslateHandleR
		colorTranslateFill.g = MR_PoseTool.colorFillTranslateHandleG
		colorTranslateFill.b = MR_PoseTool.colorFillTranslateHandleB
		colorTranslateFill.a = MR_PoseTool.colorFillTranslateHandleA
		
		self.colorTranslateFillSwatch:SetValue(colorTranslateFill)
		
		local colorScaleStroke = LM.rgb_color:new_local()
		colorScaleStroke.r = MR_PoseTool.colorStrokeScaleHandleR
		colorScaleStroke.g = MR_PoseTool.colorStrokeScaleHandleG
		colorScaleStroke.b = MR_PoseTool.colorStrokeScaleHandleB
		colorScaleStroke.a = MR_PoseTool.colorStrokeScaleHandleA

		self.colorScaleStrokeSwatch:SetValue(colorScaleStroke)
		
		local colorScaleFill = LM.rgb_color:new_local()
		colorScaleFill.r = MR_PoseTool.colorFillScaleHandleR
		colorScaleFill.g = MR_PoseTool.colorFillScaleHandleG
		colorScaleFill.b = MR_PoseTool.colorFillScaleHandleB
		colorScaleFill.a = MR_PoseTool.colorFillScaleHandleA

		self.colorScaleFillSwatch:SetValue(colorScaleFill)
		
		local colorMoveJointStroke = LM.rgb_color:new_local()
		colorMoveJointStroke.r = MR_PoseTool.colorStrokeMoveJointHandleR
		colorMoveJointStroke.g = MR_PoseTool.colorStrokeMoveJointHandleG
		colorMoveJointStroke.b = MR_PoseTool.colorStrokeMoveJointHandleB
		colorMoveJointStroke.a = MR_PoseTool.colorStrokeMoveJointHandleA

		self.colorMoveJointStrokeSwatch:SetValue(colorMoveJointStroke)
		
		local colorMoveJointFill = LM.rgb_color:new_local()
		colorMoveJointFill.r = MR_PoseTool.colorFillMoveJointHandleR
		colorMoveJointFill.g = MR_PoseTool.colorFillMoveJointHandleG
		colorMoveJointFill.b = MR_PoseTool.colorFillMoveJointHandleB
		colorMoveJointFill.a = MR_PoseTool.colorFillMoveJointHandleA

		colorMoveJointFillSwatch:SetValue(colorMoveJointFill)

		local colorManipulateStroke = LM.rgb_color:new_local()
		colorManipulateStroke.r = MR_PoseTool.colorStrokeManipulateHandleR
		colorManipulateStroke.g = MR_PoseTool.colorStrokeManipulateHandleG
		colorManipulateStroke.b = MR_PoseTool.colorStrokeManipulateHandleB
		colorManipulateStroke.a = MR_PoseTool.colorStrokeManipulateHandleA

		self.colorManipulateStrokeSwatch:SetValue(colorManipulateStroke)
		
		local colorManipulateFill = LM.rgb_color:new_local()
		colorManipulateFill.r = MR_PoseTool.colorFillManipulateHandleR
		colorManipulateFill.g = MR_PoseTool.colorFillManipulateHandleG
		colorManipulateFill.b = MR_PoseTool.colorFillManipulateHandleB
		colorManipulateFill.a = MR_PoseTool.colorFillManipulateHandleA

		self.colorManipulatFillSwatch:SetValue(colorManipulateFill)
		needRedraw = true
	end
	if needRedraw then
		if MR_PoseTool.mohoVersion >= 14 then
			local helper = MOHO.ScriptInterfaceHelper:new_local()
			local moho = helper:MohoObject()
			MR_PoseTool:GenerateColors(moho)
			moho.view:DrawMe()
			helper:delete()
		end
	end	
end

-- **************************************************
-- Keyboard/Mouse Control
-- **************************************************

function MR_PoseTool:OnMouseDown(moho, mouseEvent)
	if self.scriptValidated ~= true then
		return
	end
	self.onMMTreshold = true
	self.clickTime = os.time()
	self.forceFollowBonesGraphics = false
	
	local skel = moho:Skeleton()

	local layer = moho.layer
	local frame = moho.frame
	if self.skeletonLayersNavigation then
		if skel == nil and frame ~= 0 then
			if mouseEvent.ctrlKey then
				layer = mouseEvent.view:PickGlobalLayer(mouseEvent.pt)
			end
		
			self:GoToSkeletonLayer(moho, layer, true)
			skel = moho:LayerAsBone(layer)
		end
	end
	
	if skel == nil or frame == 0 then
		return
	end
	self.blockQuickMenu = false
	local twosModeValid = true
	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) then
			twosModeValid = false
		end
	end
	
	if self.showQuickMenu then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
		if self.graphicMenuMode == 0 and self.skeletonLayersNavigation and twosModeValid then
			local targetLayer = mouseEvent.view:PickGlobalLayer(mouseEvent.pt)
			self:GoToSkeletonLayer(moho, targetLayer, false)
			self.blockQuickMenu = true
			mouseEvent.view:SetCursor(self.mainCursor)
		end
		if self.graphicMenuMode == 1 then
			self.buttonPressed = 1
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:AddToFollowBonesChains(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 2 then
			self.buttonPressed = 2
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:AddToIKBonesChains(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 3 then
			self.buttonPressed = 3
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:AddToLockAngleList(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 4 then
			self.buttonPressed = 4
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:AddToLockPosList(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 5 then
			self.buttonPressed = 5
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:RemoveSelectedBonesFromFollowList(moho)
				self:RemoveSelectedBonesFromIkList(moho)
				self:RemoveFromLockList(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 6 then
			self.buttonPressed = 6
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActive = not self.bonesDataActive
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 7 then
			self.buttonPressed = 7
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActiveF = not self.bonesDataActiveF
			local bonesDataActiveFKey = self.scriptDataName..'bonesDataActiveF '
			scriptInfo:Set(bonesDataActiveFKey, self.bonesDataActiveF)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 8 then
			self.buttonPressed = 8
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActiveIK = not self.bonesDataActiveIK
			local bonesDataActiveIKKey = self.scriptDataName..'bonesDataActiveIK '
			scriptInfo:Set(bonesDataActiveIKKey, self.bonesDataActiveIK)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 9 then
			self.buttonPressed = 9
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActiveA = not self.bonesDataActiveA
			local bonesDataActiveAKey = self.scriptDataName..'bonesDataActiveA '
			scriptInfo:Set(bonesDataActiveAKey, self.bonesDataActiveA)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 10 then
			self.buttonPressed = 10
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActiveP = not self.bonesDataActiveP
			local bonesDataActivePKey = self.scriptDataName..'bonesDataActiveP '
			scriptInfo:Set(bonesDataActivePKey, self.bonesDataActiveP)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 11 then
			self.buttonPressed = 11
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.boneStretching = not self.boneStretching
			local scaleFollowBonesKey = self.scriptDataName..'boneStretching '
			scriptInfo:Set(scaleFollowBonesKey, self.boneStretching)
			mouseEvent.view:DrawMe()
		end
		return
	elseif self.showQuickMenu2 then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
		if self.graphicMenuMode == 0 and self.skeletonLayersNavigation and twosModeValid then
			local targetLayer = mouseEvent.view:PickGlobalLayer(mouseEvent.pt)
			self:GoToSkeletonLayer(moho, targetLayer, false)
			self.blockQuickMenu = true
			mouseEvent.view:SetCursor(self.mainCursor)
		end
		if self.graphicMenuMode == 1 then
			self.buttonPressed = 1
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:AddToFollowBones(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 2 then
			self.buttonPressed = 2
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			self:ReverseIkDirection(moho)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 3 then
			self.buttonPressed = 3
			if not self.singleFollowBonesMode then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				self:SetBoneStretching(moho, false)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 4 then
			self.buttonPressed = 4
			if not self.singleFollowBonesMode then
				self:CleanUpBoneStretching(moho)
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 5 then
			self.buttonPressed = 5
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			self:CleanUpBonesData(moho.layer)
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 6 then
			self.buttonPressed = 6
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.singleFollowBonesMode = not self.singleFollowBonesMode
			local singleFollowBonesModeKey = self.scriptDataName..'singleFollowBonesMode '
			scriptInfo:Set(singleFollowBonesModeKey, self.singleFollowBonesMode)
			mouseEvent.view:DrawMe()
		end
		return	
	elseif self.showQuickMenu3 then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
		if self.graphicMenuMode == 0 and self.skeletonLayersNavigation and twosModeValid then
			local targetLayer = mouseEvent.view:PickGlobalLayer(mouseEvent.pt)
			self:GoToSkeletonLayer(moho, targetLayer, false)
			self.blockQuickMenu = true
			mouseEvent.view:SetCursor(self.mainCursor)
		end
		if self.graphicMenuMode == 1 then
			self.buttonPressed = 1
			if self.keepSelection then
				self.multiTransform = not self.multiTransform
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 2 then	
			self.buttonPressed = 2
			self.keepSelection = not self.keepSelection
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 3 then
			self.buttonPressed = 3
			self.lockHandles = not self.lockHandles
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 4 then
			self.buttonPressed = 4
			if not MOHO.MohoGlobals.EditMultipleKeys then
				self.bakeAdjacentFrames = not self.bakeAdjacentFrames
			end
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 5 then
			self.buttonPressed = 5
			self.showPath = not self.showPath
			mouseEvent.view:DrawMe()
		elseif self.graphicMenuMode == 6 then
			self.buttonPressed = 6
			self.twosMode = not self.twosMode
			mouseEvent.view:DrawMe()
		end
		return
	end

	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) then
			return
		end
	end
	local lockHandles = self.lockHandles
	self.isBoneHaveAngleKeyList = {}
	self.isBoneHavePosKeyList = {}
	self.isBoneHaveScaleKeyList = {}
	local selBoneID = -1
	self.selBones = moho:CountSelectedBones()
	if self.selBones == 1 then
		selBoneID = skel:SelectedBoneID()
	end
	
	self.isLockHandleMouseMoved = false
	self.translationFrame = frame

	if not mouseEvent.doubleClick then
		self.selBonesList = {}
		self.selectedBonesList = {}
		self.multiBoneTranslateList = {}
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if bone.fSelected then
				self.selBonesList[i] = true
				table.insert(self.selectedBonesList, i)
				if not skel:IsAncestorSelected(i) then
					table.insert(self.multiBoneTranslateList, i)
				end
			end
		end
	end
	
	self.setKeyframe = false
	self.trPathBone = nil
	self.keepHandles = false
	self.dragging = true
	self.lastVec:Set(mouseEvent.vec)
	self.ignoreBonesList = {}
	local id = -1
	local mouseHoverID = -1
	local secondId = -1
	
	local pickWidth = self.pickWidth
	
	if lockHandles and self.selBones > 0 then
		local bonesVisibilityList = {}
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not bone.fSelected then
				bonesVisibilityList[i+1] = bone.fHidden
				bone.fHidden = true
			end	
		end

		local boneRegion = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
		id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)

		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not bone.fSelected then
				bone.fHidden = bonesVisibilityList[i+1]
			end
		end
		
		if boneRegion == -1 and not (mouseEvent.altKey and mouseEvent.shiftKey and not mouseEvent.ctrlKey) then
			id = -1
			secondId = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
			boneRegion = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			if boneRegion == -1 then
				secondId = -1
			end
		end
	else
		if mouseEvent.altKey and mouseEvent.shiftKey and not mouseEvent.ctrlKey then
			if self.multiTransform and self.keepSelection then
				local bonesVisibilityList = {}
				for i=0, skel:CountBones()-1 do
					local bone = skel:Bone(i)
					if not bone.fSelected then
						bonesVisibilityList[i+1] = bone.fHidden
						bone.fHidden = true
					end	
				end
				id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
				for i=0, skel:CountBones()-1 do
					local bone = skel:Bone(i)
					if not bone.fSelected then
						bone.fHidden = bonesVisibilityList[i+1]
					end
				end
			else
				id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
			end
		else
			id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
		end
	end

	mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
	local clickToSelect = self.clickToSelect
	local pickID = id
	local firstBone
	local secondBone
	local firstBoneParent
	self.isActive = false
	self.transformPath = false
	self.lockHandlesSelection = false
	if not (mouseEvent.ctrlKey) then
		if lockHandles then
			if selBoneID == -1 and secondId == -1 then
				self.mousePickedID = id
				self.secondBoneID = id
				
				if mouseHoverID > -1 and clickToSelect then
					skel:SelectNone()
					local bone = skel:Bone(id)
					bone.fSelected = true
					self.dragging = false
					return
				end	
			else
				self.mode = self:TestMousePoint(moho, mouseEvent, selBoneID)
				if secondId > -1 and self.mode == 1 then
					id = secondId
					local bone = skel:Bone(id)
					self.mousePickedID = id
					self.secondBoneID = id
					selBoneID = id
					self.dragging = false
					self.lockHandlesSelection = true
					if self.multiTransform and self.keepSelection then
						goto multiTransformSelection
					end
					return
				else
					self.mousePickedID = selBoneID
					self.secondBoneID = selBoneID
				end
			end
		else
			self.mousePickedID = id
			self.secondBoneID = id
		end
	else
		if lockHandles then
			if selBoneID == -1 and secondId == -1 then
				self.mousePickedID = id
				self.secondBoneID = id

				if mouseHoverID > -1 and clickToSelect then
					skel:SelectNone()
					local bone = skel:Bone(id)
					bone.fSelected = true
					self.dragging = false

					return
				end	
			else
				id = selBoneID
				self.mousePickedID = selBoneID
				self.secondBoneID = selBoneID
			end
		else
			id = self.mousePickedID
			self.secondBoneID = id
		end
	end
	
	if id > -1 then
		self.mode = self:TestMousePoint(moho, mouseEvent, id)
	else
		self.mode = self:TestMousePoint(moho, mouseEvent, selBoneID)
	end

	if mouseEvent.doubleClick then	
		local doubleclickMode = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
		if doubleclickMode == -1 then
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActive = not self.bonesDataActive
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
			return
		end
	end
	if self.mode > 1 and mouseHoverID < 0 then
		id = selBoneID
		self.mousePickedID = id
		self.secondBoneID = id
	end

	::multiTransformSelection::
	local multiTransformSelection = false
	if not (mouseEvent.altKey and mouseEvent.shiftKey and not mouseEvent.ctrlKey) then
		self.multiSelectionUnselectedMovement = false
		if self.multiTransform and self.keepSelection and self.selBones > 0 then
			local isBoneWasSelected = false
			for i=1, #self.selectedBonesList do
				if self.selectedBonesList[i] == self.secondBoneID then
					isBoneWasSelected = true
					break
				end
			end
			if not isBoneWasSelected then
				skel:SelectNone()
				for _, id in ipairs(self.selectedBonesList) do
					local bone = skel:Bone(id)
					bone.fSelected = true
				end
				self.multiSelectionUnselectedMovement = true
				if mouseHoverID == -1 then
					multiTransformSelection = true
				else
					return
				end
			end
		end
		
		if mouseHoverID == -1 and self.mode ~= 5 or multiTransformSelection then
			self.isMouseDragging = true
			if not mouseEvent.shiftKey and not mouseEvent.altKey then
				if skel then
					skel:SelectNone()
				elseif mesh then
					mesh:SelectNone()
				end
			end
			
			self.selRect.left = mouseEvent.startPt.x
			self.selRect.top = mouseEvent.startPt.y
			self.selRect.right = mouseEvent.pt.x
			self.selRect.bottom = mouseEvent.pt.y
			mouseEvent.view:Graphics():SelectionRect(self.selRect)
			mouseEvent.view:DrawMe()
			return
		end
	end

	if id < 0 then
		return
	end
	
	if MOHO.MohoGlobals.EditMultipleKeys then
		self:PrepareToEditMultipleKeys(moho)
	end
	
	self.forceBoneTranslationAlt = false
	self.forceBoneTranslationShift = false
	if mouseEvent.altKey and mouseEvent.shiftKey and not mouseEvent.ctrlKey then
		mouseEvent.altKey = false
		mouseEvent.shiftKey = false
		self.forceBoneTranslationAlt = true
		self.forceBoneTranslationShift = true
		self.mode = 0
	end

	moho.document:PrepUndo(moho.layer, true)
	moho.document:SetDirty()
	
	self.isMouseMoved = false
	self.bonesReset = false
	if mouseEvent.doubleClick and self.secondBoneID > -1 and self.doubleClickToSetKeyframe then
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			local secondBone = skel:Bone(self.secondBoneID)
			if secondBone then
				if secondBone.fSelected == self.selBonesList[self.secondBoneID] then
					if self.selBonesList[i] then
						bone.fSelected = true
					end
				end
			end
			if bone.fSelected then
				if self.mode == 0 then
					bone.fAnimPos:AddKey(moho.layerFrame)
				elseif self.mode == 1 then
					bone.fAnimAngle:AddKey(moho.layerFrame)
				elseif self.mode == 2 then
					bone.fAnimScale:AddKey(moho.layerFrame)
				end
			end
		end
		self.setKeyframe = true
		return
	end
	
	self.selBoneIsAncestorSelected = false
	if self.multiTransform and self.keepSelection then
		if self.mode == 0 then
			for i=1, #self.selectedBonesList do
				if skel:IsBoneParent(self.secondBoneID, self.selectedBonesList[i]) and self.secondBoneID ~= self.selectedBonesList[i] then
					self.selBoneIsAncestorSelected = true
					break
				end
			end
			
			self.multiBoneTranslateSBValuesPList = {}
			self.multiBoneTranslateSBValuesNList = {}
			self.multiBoneTranslateBakedList = {}
			for i=1, #self.multiBoneTranslateList do
				local sBone = skel:Bone(self.multiBoneTranslateList[i])
				sBone.fTempPos:Set(sBone.fAnimPos:GetValue(moho.layerFrame))
				self.multiBoneTranslateSBValuesPList[i] = sBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
				self.multiBoneTranslateSBValuesNList[i] = sBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
				self.multiBoneTranslateBakedList[i] = false
			end
		elseif self.mode == 1 then
			self.multiBoneAngleSBValuesPList = {}
			self.multiBoneAngleSBValuesNList = {}
			self.multiBoneAngleBakedList = {}
			local lastVec = LM.Vector2:new_local()
			lastVec:Set(mouseEvent.vec)
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				sBone.fTempAngle = sBone.fAnimAngle:GetValue(moho.layerFrame)
				self.multiBoneAngleSBValuesPList[i] = sBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
				self.multiBoneAngleSBValuesNList[i] = sBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
				self.multiBoneAngleBakedList[i] = false
			end
		elseif self.mode == 2 then
			self.multiBoneScaleSBValuesPList = {}
			self.multiBoneScaleSBValuesNList = {}
			self.multiBoneScaleDeltaList = {}
			self.multiBoneScaleBakedList = {}
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				sBone.fTempScale = sBone.fAnimScale:GetValue(moho.layerFrame)
				self.multiBoneScaleSBValuesPList[i] = sBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
				self.multiBoneScaleSBValuesNList[i] = sBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
				self.multiBoneScaleDeltaList[i] = sBone.fScale - sBone.fAnimScale:GetValue(moho.layerFrame)
				self.multiBoneScaleBakedList[i] = false
			end
		end
	end

	skel:SelectNone()
	self.startAngle = 0
	self.startAngle2 = 0
	secondBone = skel:Bone(self.secondBoneID)
	
	self.isBoneHaveAngleKeyList[self.secondBoneID] = secondBone.fAnimAngle:HasKey(moho.layerFrame)
	self.isBoneHaveScaleKeyList[self.secondBoneID] = secondBone.fAnimScale:HasKey(moho.layerFrame)
	
	self.jointChain = false
	self.firstBoneID = -1
	
	self:PrepareFollowBones(moho)

	if self.mode == 5 then
		local bone = skel:Bone(id)
		bone.fSelected = true
		self.selID = skel:BoneID(self.trPathBone)
		self.secondBoneID = id

		self.isBoneHaveAngleKeyList[self.secondBoneID] = bone.fAnimAngle:HasKey(moho.layerFrame)
		self.isBoneHaveScaleKeyList[self.secondBoneID] = bone.fAnimScale:HasKey(moho.layerFrame)
		
		local boneVec = LM.Vector2:new_local()
		boneVec:Set(0, 0)
		bone.fRestMatrix:Transform(boneVec)
		boneVec = boneVec - mouseEvent.startVec
		local d = boneVec:Mag()
		self.boneEnd = 0
		boneVec:Set(bone.fLength, 0)
		bone.fRestMatrix:Transform(boneVec)
		boneVec = boneVec - mouseEvent.startVec
		if (boneVec:Mag() < d) then
			self.boneEnd = 1
		end

		if (self.translationFrame ~= 0 and bone.fSelected) then
			self.boneChanged = true
			bone.fTempPos = bone.fAnimPos:GetValue(self.translationFrame)
			bone.fAnimPos:SetValue(self.translationFrame, bone.fTempPos)
		end
		
		self.isActive = true
		return
	elseif self.mode == 4 then -- manipulate bones
		self.selID = id
		self.boneBakedA = false
		self.boneBakedP = false
		self.boneBakedS = false
		if self.bakeAdjacentFrames then
			self.boneSAngleP = secondBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
			self.boneSAngleN = secondBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
			self.boneSScaleP = secondBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
			self.boneSScaleN = secondBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
		end
		local bone = skel:Bone(id)
		if id >= 0 then
			self.ignoreBonesList[id + 1] = true
		end
		bone.fTempPos:Set(bone.fAnimPos:GetValue(moho.layerFrame))
		bone.fTempAngle = bone.fAnimAngle:GetValue(moho.layerFrame)
		bone.fTempScale = bone.fScale
		
		self.secondBoneSecondDelta = bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame)
		
		self.secondTarget = skel:TargetOfBoneChain(id, moho.layerFrame)
		
		if self.moveTargetParent then
			for b=0, skel:CountBones()-1 do
				local bone = skel:Bone(b)
				if bone.fParent == -1 and skel:IsBoneParent(self.secondTarget, b) then
					self.secondTarget = b
					break
				end
			end
		end
		
		if self.secondTarget >= 0 then
			self.isChainTargeted = true
			local targetBone = skel:Bone(self.secondTarget)
			targetBone.fTempPos = targetBone.fAnimPos:GetValue(moho.layerFrame)
			
			self.targetBonePosP = targetBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
			
			self.targetBonePosN = targetBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
			
			self.isTargetBonePosPBaked = false
			self.isTargetBonePosNBaked = false
		else
			self.isChainTargeted = false
		end
		
		bone.fSelected = true
		local isSmartBone = moho.layer:IsSmartBoneAction(bone:Name())

		self.isParentBonesBaked = false
		self.lastVec:Set(mouseEvent.vec)
		self.parentBones = {}
		self.parentBonesAngleP = {}
		self.parentBonesAngleN = {}
		self.parentBonesScaleP = {}
		self.parentBonesScaleN = {}
		self.parentBonesScaleDelta = {}
		self.startAngle = 0
		self.boneStartAngles = {}
		self.boneStartActualAngles = {}
		table.insert(self.boneStartAngles, bone.fAnimAngle:GetValue(moho.layerFrame))
		table.insert(self.boneStartActualAngles, bone.fAnimAngle.value)

		while bone.fParent >= 0 do
			local parentBone = skel:Bone(bone.fParent)
			parentBone.fTempAngle = parentBone.fAnimAngle:GetValue(moho.layerFrame)
			parentBone.fTempScale = parentBone.fAnimScale:GetValue(moho.layerFrame)
			if (self:CountBoneChildren(skel, bone.fParent, true) > 1) or parentBone.fIgnoredByIK or parentBone.fFixedAngle then
				break
			end
			local parenBoneID = bone.fParent
			bone = skel:Bone(parenBoneID)
			
			self.ignoreBonesList[parenBoneID + 1] = true
			bone.fTempScale = bone.fScale
			table.insert(self.parentBones, parenBoneID)
			
			table.insert(self.parentBonesScaleDelta, bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame))
			
			if moho.layerFrame - self.interval > 0 then
				table.insert(self.parentBonesAngleP, bone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
				table.insert(self.parentBonesScaleP, bone.fAnimScale:GetValue(moho.layerFrame - self.interval))
			else
				table.insert(self.parentBonesAngleP, 0)
				table.insert(self.parentBonesScaleP, 0)
			end
			
			if moho.layerFrame + self.interval > 0 then
				table.insert(self.parentBonesAngleN, bone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
				table.insert(self.parentBonesScaleN, bone.fAnimScale:GetValue(moho.layerFrame + self.interval))
			else
				table.insert(self.parentBonesAngleN, 0)
				table.insert(self.parentBonesScaleN, 0)
			end
			
			table.insert(self.boneStartAngles, bone.fAnimAngle:GetValue(moho.layerFrame))
			table.insert(self.boneStartActualAngles, bone.fAnimAngle.value)
		end

		local startBoneID = self.parentBones[#self.parentBones]
		local startBone = skel:Bone(startBoneID)
		startBone.fTempAngle = startBone.fAnimAngle:GetValue(moho.layerFrame)

		if startBoneID >= 0 then
			self.ignoreBonesList[startBoneID + 1] = true
		end
		
		local startBonePos = LM.Vector2:new_local()
		startBonePos:Set(0, 0)
		startBone.fMovedMatrix:Transform(startBonePos)
		self.startBonePos:Set(startBonePos)
		self.startBoneDist = MR_Utilities:GetDistance(startBonePos, mouseEvent.vec)
		
		self.isChildBonesBaked = false

		self.childBones = {}
		self.childBonesAngelP = {}
		self.childBonesAngelN = {}

		for i=0, skel:CountBones()-1 do
			local childBone = skel:Bone(i)

			if childBone.fParent == id and not childBone.fFixedAngle and not childBone.fIgnoredByIK then
				local angle = childBone.fAnimAngle:GetValue(moho.layerFrame)
				childBone.fTempAngle = angle
				table.insert(self.childBones, i)
				if moho.layerFrame - self.interval > 0 then
					table.insert(self.childBonesAngelP, childBone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
				else
					table.insert(self.childBonesAngelP, 0)
				end
				
				if moho.layerFrame + self.interval > 0 then
					table.insert(self.childBonesAngelN, childBone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
				else
					table.insert(self.childBonesAngelN, 0)
				end
			end
		end
		
		if self.mode == 4 then
			self.isActive = true
			moho:UpdateBonePointSelection()
			mouseEvent.view:DrawMe()
			moho:UpdateSelectedChannels()
			self.lastVec:Set(mouseEvent.vec)
			return
		end
	end

	if secondBone.fParent > -1 and not secondBone:IsZeroLength() then
		self.firstBoneID = secondBone.fParent
		firstBone = skel:Bone(self.firstBoneID)
		
		self.isBoneHaveAngleKeyList[self.firstBoneID] = firstBone.fAnimAngle:HasKey(moho.layerFrame)
		self.isBoneHaveScaleKeyList[self.firstBoneID] = firstBone.fAnimScale:HasKey(moho.layerFrame)

		local firstBoneChilds = skel:CountBoneChildren(self.firstBoneID, true)
		local secondBonePos = LM.Vector2:new_local()
		secondBonePos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
		if firstBone.fIgnoredByIK == false and not firstBone.fFixedAngle and not secondBone.fFixedAngle and secondBone.fIgnoredByIK == false and firstBoneChilds == 1 and MR_Utilities:Round(secondBone.fPos.y) == 0 
		and not MR_Utilities:IsEqual(secondBonePos.x, 0, 0.0001) and not firstBone:IsZeroLength() then
			self.jointChain = true
		end
	end	
	
	self.secondBoneID = id
	secondBone.fSelected = true
	
	local useFirstBone = self.jointChain and (self.mode == 0 or self.mode == 3)
	
	if self.secondBoneID >= 0 and self.mode ~= 0 then
		self.ignoreBonesList[self.secondBoneID + 1] = true
	end
	
	if self.bakeAdjacentFrames then
		self.boneBakedA = false
		self.boneBakedP = false
		self.boneBakedS = false
		
		if useFirstBone then
			if self.firstBoneID >= 0 then
				self.ignoreBonesList[self.firstBoneID + 1] = true
			end
			self.boneFAngleP = firstBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
			self.boneFAngleN = firstBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
			self.boneFScaleP = firstBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
			self.boneFScaleN = firstBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
		end	
		
		self.boneSAngleP = secondBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
		self.boneSAngleN = secondBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
		
		self.boneSPosP = secondBone.fAnimPos:GetValue(moho.layerFrame - self.interval) 
		self.boneSPosN = secondBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
		
		self.boneSScaleP = secondBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
		self.boneSScaleN = secondBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
	end
	
	moho.layer:UpdateCurFrame()
	self.secondTarget = skel:TargetOfBoneChain(self.secondBoneID, moho.layerFrame)
	if self.moveTargetParent then
		for b=0, skel:CountBones()-1 do
			local bone = skel:Bone(b)
			if bone.fParent == -1 and skel:IsBoneParent(self.secondTarget, b) then
				self.secondTarget = b
				break
			end
		end
	end
	
	if self.secondTarget >= 0 then
		self.isChainTargeted = true
		local targetBone = skel:Bone(self.secondTarget)
		targetBone.fTempPos = targetBone.fAnimPos:GetValue(moho.layerFrame)
		
		self.targetBonePosP = targetBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
		
		self.targetBonePosN = targetBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
		
		self.isTargetBonePosPBaked = false
		self.isTargetBonePosNBaked = false
		
	else
		self.isChainTargeted = false
	end
	
	local firstBoneAngleDelta = 0
	local secondBoneAngleDelta = 0

	if self.isChainTargeted and self.mode ~= 1 then
		local firstBoneStretchDelta
		local firstBoneIKStratching
		if useFirstBone then
			firstBoneStretchDelta = 0
			firstBoneIKStratching = firstBone.fMaxAutoScaling
			firstBone.fMaxAutoScaling = 10000
		end
		
		local secondBoneStretchDelta = 0
		local secondBoneIKStratching = secondBone.fMaxAutoScaling
		
		secondBone.fMaxAutoScaling = 10000
		
		moho.layer:UpdateCurFrame()
		
		local firstBoneFSize
		local firstBoneFAngle
		local isFirstBoneIgnoredByIK
		if useFirstBone then
			firstBoneFSize = firstBone.fScale
			firstBoneFAngle = firstBone.fAngle
			isFirstBoneIgnoredByIK = firstBone.fIgnoredByIK
		end
		
		local secondBoneFSize = secondBone.fScale
		local secondBoneFAngle = secondBone.fAngle
		
		local isSecondBoneIgnoredByIK = secondBone.fIgnoredByIK
		if useFirstBone then
			firstBone.fIgnoredByIK = true
		end
		
		secondBone.fIgnoredByIK = true
		
		moho.layer:UpdateCurFrame()
		
		if useFirstBone then
			firstBoneStretchDelta = firstBoneFSize - firstBone.fScale
			firstBoneAngleDelta = firstBoneFAngle - firstBone.fAngle
		end
		
		secondBoneStretchDelta = secondBoneFSize - secondBone.fScale
		secondBoneAngleDelta = secondBoneFAngle - secondBone.fAngle
		
		if useFirstBone then
			firstBone.fIgnoredByIK = isFirstBoneIgnoredByIK
			firstBone.fMaxAutoScaling = firstBoneIKStratching
		end
		
		secondBone.fIgnoredByIK = isSecondBoneIgnoredByIK
		secondBone.fMaxAutoScaling = secondBoneIKStratching
		if useFirstBone then
			if (self.ignoreZeroScaledBones and MR_Utilities:Round(firstBone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
				firstBone.fAnimScale:SetValue(moho.layerFrame, firstBone.fAnimScale:GetValue(moho.layerFrame) + firstBoneStretchDelta)
			end	
			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAnimAngle:GetValue(moho.layerFrame) + firstBoneAngleDelta)
		end
		if (self.ignoreZeroScaledBones and MR_Utilities:Round(secondBone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondBone.fAnimScale:GetValue(moho.layerFrame) + secondBoneStretchDelta)
		end	
		secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAnimAngle:GetValue(moho.layerFrame) + secondBoneAngleDelta)
		
		moho.layer:UpdateCurFrame()
	end	
	self.isTargetMoved = false
	
	local secondTipVec = LM.Vector2:new_local()
	local firstVec = LM.Vector2:new_local()
	local secondVec = LM.Vector2:new_local()
	secondTipVec:Set(secondBone.fLength, 0)
	firstVec:Set(0, 0)
	secondVec:Set(0, 0)
	secondBone.fMovedMatrix:Transform(secondTipVec)
	secondBone.fMovedMatrix:Transform(secondVec)
	
	self.secondBonePos:Set(secondVec)
	
	if useFirstBone then
		firstBone.fMovedMatrix:Transform(firstVec)
		self.firstBonePos:Set(firstVec)
		self.firstDist = MR_Utilities:GetDistance(self.firstBonePos, self.secondBonePos)
		self.ignoreBonesList[self.firstBoneID + 1] = true
	end
	
	self.secondBoneTipPos:Set(secondTipVec)
	self.secondBoneDist = MR_Utilities:GetDistance(self.secondBonePos, self.secondBoneTipPos)
	local mousePos = mouseEvent.vec
	
	self.clickOffset = self.secondBonePos - mousePos
	
	if self.mode == 2 then
		self.clickOffset = self.secondBoneTipPos - mousePos
	end
	
	if useFirstBone then
		self.firstBoneSizeDelta = firstBone.fScale - firstBone.fAnimScale:GetValue(moho.layerFrame)
	end	
	self.secondBoneSizeDelta = secondBone.fScale - secondBone.fAnimScale:GetValue(moho.layerFrame)
	
	self.isChildBonesBaked = false

	self.childBones = {}
	self.childBonesAngelP = {}
	self.childBonesAngelN = {}
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if  bone.fParent == self.secondBoneID and not bone.fFixedAngle and not bone.fIgnoredByIK then
			local angle = bone.fAnimAngle:GetValue(moho.layerFrame)
			bone.fTempAngle = angle
			table.insert(self.childBones, i)
			
			if moho.layerFrame - self.interval > 0 then
				table.insert(self.childBonesAngelP, bone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
			else
				table.insert(self.childBonesAngelP, 0)
			end
			
			if moho.layerFrame + self.interval > 0 then
				table.insert(self.childBonesAngelN, bone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
			else
				table.insert(self.childBonesAngelN, 0)
			end
		end
	end
	
	local firstBoneActualAngle
	
	if useFirstBone then
		firstBoneActualAngle = firstBone.fAngle
		self.firstBoneAngleDelta = firstBoneActualAngle - firstBone.fAnimAngle:GetValue(moho.layerFrame)
	end
	
	local secondBoneActualAngle = secondBone.fAngle
	self.secondBoneAngleDelta = secondBoneActualAngle - secondBone.fAnimAngle:GetValue(moho.layerFrame)
	
	self.lastVec2:Set(0, 0)
	skel:UpdateBoneMatrix()
	secondBone.fMovedMatrix:Transform(self.lastVec2)
	
	if self.mode > 1 then
		if useFirstBone then
			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAnimAngle:GetValue(moho.layerFrame))
			firstBone.fAnimAngle.value = firstBoneActualAngle
		end
	
		secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAnimAngle:GetValue(moho.layerFrame))
		secondBone.fAnimAngle.value = secondBoneActualAngle
	end	
	
	if useFirstBone then
		firstBone.fTempScale = firstBone.fScale
		firstBone.fTempAngle = firstBone.fAngle
	end

	secondBone.fTempScale = secondBone.fScale
	secondBone.fTempAngle = secondBone.fAngle
	
	if self.mode == 0 then
		secondBone.fTempPos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
	end
	
	self.isActive = true
	
	if useFirstBone then
		self.firstBoneParentID = firstBone.fParent
		if self.firstBoneParentID > -1 then
			firstBoneParent = skel:Bone(self.firstBoneParentID)
			self.firstBoneParentIBIK = firstBoneParent.fIgnoredByIK
			firstBoneParent.fIgnoredByIK = true
		end
	end

	local boneFirstLenght
	local boneFirstScale
	if useFirstBone then
		boneFirstLenght = secondBone.fPos.x
		boneFirstScale = firstBone.fScale
	end
	local boneSecondLenght = secondBone.fLength
	local boneSecondScale = secondBone.fScale
	if useFirstBone then
		self.firstBoneScalePercent = ((boneFirstLenght * boneFirstScale) / ((boneFirstLenght * boneFirstScale) + (boneSecondLenght * boneSecondScale))) * 100
		self.firstBoneOffset = firstBone.fScale - firstBone.fAnimScale:GetValue(moho.layerFrame)
	end
	self.secondBoneOffset = secondBone.fScale - secondBone.fAnimScale:GetValue(moho.layerFrame)
	moho.layer:UpdateCurFrame()
	moho:UpdateBonePointSelection()
	mouseEvent.view:DrawMe()
	self.isMouseMoved = false
end

function MR_PoseTool:OnMouseMoved(moho, mouseEvent)
	if self.scriptValidated ~= true then
		return
	end
	if self.onMMTreshold then
		self.onMMTreshold = false
		return
	end
	local frame = moho.layerFrame
	local skel = moho:Skeleton()

	if skel == nil then
		if self.skeletonLayersNavigation then
			local skelLayer = MR_Utilities:FindSkeletonLayer(moho.layer)
			if (skelLayer or mouseEvent.ctrlKey) and frame ~= 0 then
				mouseEvent.view:SetCursor(self.sblCursor)
			else
				mouseEvent.view:SetCursor(MOHO.disabledCursor)
			end
		end
		return
	end

	if frame == 0 then
		mouseEvent.view:SetCursor(MOHO.disabledCursor)
		return
	end
	
	if not (mouseEvent.ctrlKey) then
		local pos = LM.Vector2:new_local()
		pos:Set(mouseEvent.vec)
		local m = LM.Matrix:new_local()
		moho.layer:GetFullTransform(moho.frame, m, moho.document)
		m:Transform(pos)
		self.graphicsMenuCenter:Set(pos)
	end
	
	if not mouseEvent.ctrlKey then
		self.blockQuickMenu = false
	end
	
	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0)then
			self.showQuickMenu = false
			self.showQuickMenu2 = false
			self.showQuickMenu3 = false
			self.showQuickMenu4 = false
			self.showIcons4 = false
			
			local pickWidth = self.pickWidth
			if not mouseEvent.ctrlKey then
				self.mouseHoverIDGraphicMenu = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
				self.showQuickMenu = false
				self.showQuickMenu2 = false
				self.showQuickMenu3 = false
				self.showIcons4 = false
				mouseEvent.view:SetCursor(MOHO.disabledCursor)
			elseif mouseEvent.ctrlKey and self.mouseHoverIDGraphicMenu == -1 then
				if mouseEvent.shiftKey then
					self.showQuickMenu3 = true
					if self.showQuickMenu or self.showQuickMenu2 or self.showQuickMenu3 then
						self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
					end
					mouseEvent.view:SetCursor(self.mainCursor)
				else
					self.showQuickMenu = false
					self.showQuickMenu2 = false
					mouseEvent.view:SetCursor(MOHO.disabledCursor)
				end
			end
			mouseEvent.view:DrawMe()
			return
		end
	end

	if self.isMouseDragging then
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		self.selRect.right = mouseEvent.pt.x
		self.selRect.bottom = mouseEvent.pt.y
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		mouseEvent.view:RefreshView()
		mouseEvent.view:DrawMe()
		return
	end

	if self.multiSelectionUnselectedMovement then
		self.isMouseMoved = true
		return
	end
		
	if self.lockHandlesSelection then
		self.isLockHandleMouseMoved = true
	end

	local boneID = -1
	local bone
	local lockMousePickedID = -1
	local selectedBones = moho:CountSelectedBones()
	local lockHandles = self.lockHandles
	
	if selectedBones == 1 then
		boneID = skel:SelectedBoneID()
		bone = skel:Bone(boneID)
	end
	self.showQuickMenu = false
	self.showQuickMenu2 = false
	self.showQuickMenu3 = false
	
	local pickWidth = self.pickWidth
	if not self.blockQuickMenu then
		if not mouseEvent.ctrlKey then
			self.mouseHoverIDGraphicMenu = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			self.showQuickMenu = false
			self.showQuickMenu2 = false
			self.showQuickMenu3 = false
			self.showQuickMenu4 = false
		elseif mouseEvent.ctrlKey and self.mouseHoverIDGraphicMenu == -1 then
			if not mouseEvent.shiftKey and not mouseEvent.altKey then
				self.showQuickMenu = true
			elseif mouseEvent.altKey and not mouseEvent.shiftKey then
				self.showQuickMenu2 = true
				self.showQuickMenu4 = false
			elseif mouseEvent.shiftKey and not mouseEvent.altKey then
				self.showQuickMenu3 = true
				self.showQuickMenu4 = false
			end
		end
	end

	if self.showQuickMenu or self.showQuickMenu2 or self.showQuickMenu3 then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
	end
	if self.graphicMenuMode == 6 then
		self.showQuickMenu4 = true
	elseif self.graphicMenuMode >= 1 and self.graphicMenuMode <= 5 then
		self.showQuickMenu4 = false
	end
	
	self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
	local forceBoneTranslation = false
	if mouseEvent.altKey and mouseEvent.shiftKey and not mouseEvent.ctrlKey then
		forceBoneTranslation = true
	end
	
	if (not self.dragging) then
		if forceBoneTranslation then
			mouseEvent.view:SetCursor(MOHO.moveCursor)
		end
	
		if (not mouseEvent.ctrlKey and not lockHandles) or lockHandles then
			if self.multiTransform and self.keepSelection and not lockHandles and selectedBones > 1 then
				local bones = {}
				for i=0, skel:CountBones()-1 do
					local tBone = skel:Bone(i)
					table.insert(bones, tBone.fHidden)
					if not tBone.fSelected then
						tBone.fHidden = true
					end
				end
				self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
				self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
				for i, bool in ipairs(bones) do
					local tBone = skel:Bone(i-1)
					tBone.fHidden = bool
				end
			else
				if (selectedBones ~= 1 and not mouseEvent.ctrlKey) or (not lockHandles and not mouseEvent.ctrlKey) then
					if lockHandles and selectedBones > 1 then
						local bones = {}
						for i=0, skel:CountBones()-1 do
							local tBone = skel:Bone(i)
							table.insert(bones, tBone.fHidden)
							if not tBone.fSelected then
								tBone.fHidden = true
							end
						end

						self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
						lockMousePickedID = self.mousePickedID 
						boneID = self.mousePickedID 
						self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)

						for i, bool in ipairs(bones) do
							local tBone = skel:Bone(i-1)
							tBone.fHidden = bool
						end
					else
						self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
					end
				end
			end
		end
		
		if not (mouseEvent.ctrlKey) then
			if lockHandles and selectedBones >= 1 then
				self.additionHandles = self:CheckBone(moho, boneID)
				lockMousePickedID = self.mousePickedID 
				self.mousePickedID = boneID
			else
				if self.mouseHoverID == -1 then
					self.mousePickedID = -1
				end
				self.additionHandles = self:CheckBone(moho, self.mousePickedID)
			end	
		else
			if lockHandles and selectedBones == 1 then
				self.additionHandles = self:CheckBone(moho, boneID)
				lockMousePickedID = self.mousePickedID 
				self.mousePickedID = boneID
			end
		end
		
		local mode
		
		if self.multiTransform and self.keepSelection and not self.lockHandles then
			if self.mousePickedID > -1 and selectedBones > 0 then
				local tBone = skel:Bone(self.mousePickedID)
				if not tBone.fSelected then
					self.mousePickedID = -1
					if not forceBoneTranslation then
						mouseEvent.view:SetCursor(self.mainCursor)
					end
					mouseEvent.view:DrawMe()
					return
				end
			end
		end
		
		if self.multiTransform and self.keepSelection and selectedBones > 1 then
			self.additionHandles = false
		end
		
		if lockHandles and selectedBones >= 1 then
			if not self.showQuickMenu then
				mode = self:TestMousePoint(moho, mouseEvent, boneID)
				self.drawMode = mode
				if self.mouseHoverID > -1 and not forceBoneTranslation then
					if mode == 0 or mode == 5 then
						mouseEvent.view:SetCursor(MOHO.moveCursor)
					elseif (mode == 1) then
						if lockMousePickedID ~= self.mouseHoverID then
							mouseEvent.view:SetCursor(self.mainCursor)
						else
							mouseEvent.view:SetCursor(MOHO.rotateCursor)
						end
					elseif (mode == 2) then
						mouseEvent.view:SetCursor(MOHO.scaleCursor)
					elseif (mode == 3) then
						mouseEvent.view:SetCursor(self.mjCursor)
					elseif (mode == 4) then
						mouseEvent.view:SetCursor(self.mbCursor)		
					end
				else
					if not forceBoneTranslation then
						mouseEvent.view:SetCursor(self.mainCursor)
					end
				end
			end
		else
			if self.mouseHoverID > -1 or bone ~= nil then
				local isBoneSelected = false
				if self.multiTransform and self.keepSelection then
					if self.mousePickedID > -1 and self.mousePickedID == self.mouseHoverID then
						isBoneSelected = true
					end
				else
					if (not self.multiTransform and self.keepSelection) or (not self.multiTransform and self.keepSelection) and not self.lockHandles then
						isBoneSelected = true
					elseif not self.keepSelection and not self.lockHandles then
						isBoneSelected = true
					else
						if self.mouseHoverID > -1 then
							local selBone = skel:Bone(self.mouseHoverID)
							if selBone.fSelected then
								isBoneSelected = true
							end
						end
					end
				end

				if isBoneSelected then
					if not self.showQuickMenu then
						if self.multiTransform and self.keepSelection then
							mode = self:TestMousePoint(moho, mouseEvent, self.mousePickedID)
						else
							mode = self:TestMousePoint(moho, mouseEvent, boneID)
						end
						
						self.drawMode = mode
						if not (self.mouseHoverID < 0 and mode ~= 5) and not forceBoneTranslation then
							if mode == 0 or mode == 5 then
								mouseEvent.view:SetCursor(MOHO.moveCursor)
							elseif (mode == 1) then
								if self.mousePickedID ~= self.mouseHoverID and mouseEvent.ctrlKey then
									mouseEvent.view:SetCursor(self.mainCursor)
								else
									mouseEvent.view:SetCursor(MOHO.rotateCursor)
								end
							elseif (mode == 2) then
								mouseEvent.view:SetCursor(MOHO.scaleCursor)
							elseif (mode == 3) then
								mouseEvent.view:SetCursor(self.mjCursor)
							elseif (mode == 4) then
								mouseEvent.view:SetCursor(self.mbCursor)		
							end
						else
							if not forceBoneTranslation then
								mouseEvent.view:SetCursor(self.mainCursor)
							end
						end
					end
				else
					if not forceBoneTranslation then
						mouseEvent.view:SetCursor(self.mainCursor)
					end
				end
			else
				if not forceBoneTranslation then
					mouseEvent.view:SetCursor(self.mainCursor)
				end
			end
		end

		if self.skeletonLayersNavigation and mouseEvent.ctrlKey and (self.showQuickMenu or self.showQuickMenu2 or self.showQuickMenu3) then
			if self.graphicMenuMode == 0 and not self.blockQuickMenu then
				mouseEvent.view:SetCursor(self.sblCursor)
			else
				mouseEvent.view:SetCursor(self.mainCursor)
			end
		end
		
		mouseEvent.view:DrawMe()
		return
	end
	
	if self.isActive == false then
		return
	end

	if self.mode == 0 or self.mode == 5 then -- move
		self:OnMouseMovedT(moho, mouseEvent)
	elseif self.mode == 1 then -- rotate
		self:OnMouseMovedR(moho, mouseEvent)
	elseif self.mode == 2 then -- scale rotate
		self:OnMouseMovedS(moho, mouseEvent)
	elseif self.mode == 3 then -- move joint
		if self.jointChain then
			self:OnMouseMovedJ(moho, mouseEvent)
		end
	elseif self.mode == 4 then -- manipulate bones
		self:OnMouseMovedM(moho, mouseEvent)
	end
	self.isMouseMoved = true
end

function MR_PoseTool:OnMouseMovedJ(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	local firstBone = skel:Bone(self.firstBoneID)
	local secondBone = skel:Bone(self.secondBoneID)
	
	if smartBake and not self.boneBakedA then
		self:BakeFrames(moho, secondBone, firstBone, true, false, true)
		self.boneBakedA = true
	end
	
	local vectorMousePos = (mouseEvent.vec + self.clickOffset)

	local firstCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.firstBonePos)

	local firstDelta = (firstCursorDist / self.firstDist)
	firstBone.fAnimScale:SetValue(moho.layerFrame, (firstBone.fTempScale * firstDelta) - self.firstBoneSizeDelta)
	
	if self.isChainTargeted then
		local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)
		local secondDelta = (secondCursorDist / self.secondBoneDist)
		secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
		
		if mouseEvent.shiftKey then
			local totalDist = firstCursorDist + secondCursorDist
			local distP = (totalDist / 100) * self.firstBoneScalePercent
			distP = distP / firstBone.fLength
			local secondDistP = (totalDist / 100) * (100 - self.firstBoneScalePercent)
			secondDistP = secondDistP / secondBone.fLength
			firstBone.fAnimScale:SetValue(moho.layerFrame, distP - self.firstBoneOffset)
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondDistP - self.secondBoneOffset)
		end
		
		skel:IKAngleSolver(self.firstBoneID, vectorMousePos, 1, true, false)
		local firstBoneNewAngle = firstBone.fAngle - self.firstBoneAngleDelta
		
		firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBoneNewAngle)
		firstBone.fAnimAngle.value = firstBone.fAngle

		if not secondBone.fFixedAngle then
			firstBone.fIgnoredByIK = true
			skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 1, true, true)
			
			secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAngle - self.secondBoneAngleDelta)
			secondBone.fAnimAngle.value = secondBone.fAngle

			firstBone.fIgnoredByIK = false

			moho.layer:UpdateCurFrame()

			skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 1, true, true)
			
			local secondBoneNewAngle = secondBone.fAngle - self.secondBoneAngleDelta
			
			secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBoneNewAngle)
			secondBone.fAnimAngle.value = secondBone.fAngle

			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAngle - self.firstBoneAngleDelta)
			firstBone.fAnimAngle.value = firstBone.fAngle
			
			firstBone.fIgnoredByIK = currentIgnoredByIK
		end
	else
		if mouseEvent.shiftKey then
			local firstCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.firstBonePos)
			local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)

			local firstDelta = (firstCursorDist / self.firstDist)
			local secondDelta = (secondCursorDist / self.secondBoneDist)
			firstBone.fAnimScale:SetValue(moho.layerFrame, (firstBone.fTempScale * firstDelta) - self.firstBoneSizeDelta)
			secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
			
			local totalDist = firstCursorDist + secondCursorDist
			local distP = (totalDist / 100) * self.firstBoneScalePercent
			distP = distP / firstBone.fLength
			local secondDistP = (totalDist / 100) * (100 - self.firstBoneScalePercent)
			secondDistP = secondDistP / secondBone.fLength
			firstBone.fAnimScale:SetValue(moho.layerFrame, distP - self.firstBoneOffset)
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondDistP - self.secondBoneOffset)
			
			skel:IKAngleSolver(self.firstBoneID, vectorMousePos, 1, true, false)
			
			local originalAngle = firstBone.fTempAngle
			local correctedAngle = firstBone.fAngle
			local delta = originalAngle - correctedAngle

			while math.abs(delta) > math.rad(180) do
				if delta > math.rad(180) then
					correctedAngle = correctedAngle + math.rad(360)
				elseif delta < math.rad(-180) then
					correctedAngle = correctedAngle - math.rad(360)
				end
				delta = originalAngle - correctedAngle
			end

			local restoredAngle = correctedAngle - self.firstBoneAngleDelta
			
			firstBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
			firstBone.fAnimAngle.value = firstBone.fAngle
			
			secondBone.fAnimScale.value = secondBone.fScale
			local currentIgnoredByIK = firstBone.fIgnoredByIK
			
			if not secondBone.fFixedAngle then
				firstBone.fIgnoredByIK = true
				skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 10, true, true)
				
				secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAngle - self.secondBoneAngleDelta)
				secondBone.fAnimAngle.value = secondBone.fAngle

				firstBone.fIgnoredByIK = false

				moho.layer:UpdateCurFrame()

				skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 10, true, true)
				
				originalAngle = secondBone.fTempAngle
				correctedAngle = secondBone.fAngle
				delta = originalAngle - correctedAngle

				while math.abs(delta) > math.rad(180) do
					if delta > math.rad(180) then
						correctedAngle = correctedAngle + math.rad(360)
					elseif delta < math.rad(-180) then
						correctedAngle = correctedAngle - math.rad(360)
					end
					delta = originalAngle - correctedAngle
				end

				restoredAngle = correctedAngle - self.secondBoneAngleDelta
				
				secondBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
				secondBone.fAnimAngle.value = secondBone.fAngle

				originalAngle = firstBone.fTempAngle
				correctedAngle = firstBone.fAngle
				delta = originalAngle - correctedAngle

				while math.abs(delta) > math.rad(180) do
					if delta > math.rad(180) then
						correctedAngle = correctedAngle + math.rad(360)
					elseif delta < math.rad(-180) then
						correctedAngle = correctedAngle - math.rad(360)
					end
					delta = originalAngle - correctedAngle
				end

				restoredAngle = correctedAngle - self.firstBoneAngleDelta
				
				firstBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
				firstBone.fAnimAngle.value = firstBone.fAngle
				
				firstBone.fIgnoredByIK = currentIgnoredByIK
			end
		else
			local bone = firstBone
			local center = LM.Vector2:new_local()
			center:Set(0, 0)
			skel:UpdateBoneMatrix(self.firstBoneID)
			bone.fMovedMatrix:Transform(center)
			
			local mousePos = mouseEvent.vec
			
			local angle = self.startAngle
			local v1 = self.lastVec - center
			local v2 = mousePos - center
			v2:Rotate(-math.atan2(v1.y, v1.x))
			angle = angle + math.atan2(v2.y, v2.x)
			self.startAngle = angle
			self.lastVec:Set(mousePos)
			local angleSign = 1.0
			if (not bone.fFixedAngle) then
				angleSign = bone:ParentalFlipFactor()
			end

			local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.firstBoneAngleDelta

			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0) - self.firstBoneAngleDelta
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle = LM.Clamp(newAgle, min, max)
				end
			end
			if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
				bone.fAnimAngle.value = bone.fAngle
				if smartBake and not self.boneBakedA then
					self:BakeFrames(moho, firstBone, nil, true, false, false)
					self.boneBakedA = true
				end
			end
			
			moho.layer:UpdateCurFrame()

			local bone = secondBone
			local center = LM.Vector2:new_local()

			center:Set(0, 0)
			skel:UpdateBoneMatrix(self.secondBoneID)
			bone.fMovedMatrix:Transform(center)
			
			local angle2 = self.startAngle2
			local v1 = self.lastVec2 - self.secondBoneTipPos
			local v2 = center - self.secondBoneTipPos
			v2:Rotate(-math.atan2(v1.y, v1.x))
			angle2 = angle2 + math.atan2(v2.y, v2.x)
			self.startAngle2 = angle2
			self.lastVec2:Set(center)
			
			local angleSign2 = 1.0
			if (not bone.fFixedAngle) then
				angleSign2 = bone:ParentalFlipFactor()
			end

			local newAgle2 = (bone.fTempAngle + (angle2 * angleSign2)) - (angle * angleSign2) - self.secondBoneAngleDelta
			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle2 = LM.Clamp(newAgle2, min, max)
				end
			end
			if not MR_Utilities:IsEqual(newAgle2, bone.fAnimAngle:GetValue(moho.layerFrame), 0.0001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle2)
				bone.fAnimAngle.value = bone.fAngle
				if smartBake and not self.boneBakedA then
					self:BakeFrames(moho, secondBone, nil, true, false, false)
					self.boneBakedA = true
				end
			end

			moho.layer:UpdateCurFrame()
		
			local center = LM.Vector2:new_local()
			center:Set(0, 0)
			skel:UpdateBoneMatrix()
			secondBone.fMovedMatrix:Transform(center)
			local secondCursorDist = MR_Utilities:GetDistance(center, self.secondBoneTipPos)
			local secondDelta = (secondCursorDist / self.secondBoneDist)
			secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
		end
		
		local angleSign = 1
		if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
			angleSign = -1
		end
	end
	
	if self.isChainTargeted and self.isTargetMoved then
		local targetBone = skel:Bone(self.secondTarget)
		targetBone.fAnimPos:SetValue(moho.layerFrame, targetBone.fTempPos)
	end
	secondBone.fAnimScale.value = secondBone.fScale
	
	if mouseEvent.altKey then
		local angleSign = 1
		local angleSignS = 1
		if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
			angleSignS = -1
		end
		local angleSignF = 1
		if (firstBone.fFlipH.value and not firstBone.fFlipV.value) or (not firstBone.fFlipH.value and firstBone.fFlipV.value) then
			angleSignF = -1
		end
		
		local angleDelta = 0
		if angleSignF == 1 and angleSignS == -1 then
			angleSign = -1
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)
		elseif angleSignF == 1 and angleSignS == 1 then
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)	
		elseif angleSignF == -1 and angleSignS == -1 then
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
		elseif angleSignF == -1 and angleSignS == 1 then
			angleSign = -1
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
		end
		
		while angleDelta > math.rad(180) do
			angleDelta = angleDelta - math.rad(360)
		end
		
		while angleDelta < math.rad(-180) do
			angleDelta = angleDelta + math.rad(360)
		end

		if not self.isChildBonesBaked and smartBake then
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not self.isChildBonesBaked then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
				end
				if not self.isChildBonesBaked then
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end
			end
			self.isChildBonesBaked = true
		end	
		for i, q in ipairs(self.childBones) do
			local bone = skel:Bone(q)
			local newAngle = bone.fTempAngle - (angleDelta * angleSign)
			bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
		end
	else
		for i, q in ipairs(self.childBones) do
			local firstBone = skel:Bone(q)
			if not MR_Utilities:IsEqual(firstBone.fTempAngle, firstBone.fAnimAngle:GetValue(moho.layerFrame), 0.0001) then
				firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fTempAngle)
			end	
		end
	end
	
	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedT(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end

	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end

	local bone = skel:Bone(self.secondBoneID)
	bone.fPos:Set(bone.fTempPos)

	local offset = mouseEvent.vec - mouseEvent.startVec
	
	local boneVec = LM.Vector2:new_local()
	local inverseM = LM.Matrix:new_local()
	
	local parent = nil
	boneVec:Set(0, 0)
	if (bone.fParent >= 0) then
		parent = skel:Bone(bone.fParent)
		parent.fMovedMatrix:Transform(boneVec)
	end
	boneVec = boneVec + offset
	if (parent) then
		inverseM:Set(parent.fMovedMatrix)
		inverseM:Invert()
		inverseM:Transform(boneVec)
	end
	
	if not mouseEvent.shiftKey then
		self.forceBoneTranslationShift = false
	end
	
	if not mouseEvent.altKey then
		self.forceBoneTranslationAlt = false
	end
	
	if mouseEvent.shiftKey and not self.forceBoneTranslationShift then
		if (math.abs(boneVec.x) > math.abs(boneVec.y)) then
			boneVec.y = 0
		else
			boneVec.x = 0
		end
	end
	local v = nil
	v = bone.fPos + boneVec

	if self.mode == 5 then
		bone.fAnimPos:SetValue(self.translationFrame, v)
	elseif self.mode == 0 then
		local bonePos = bone.fAnimPos:GetValue(moho.layerFrame)
		if not MR_Utilities:IsEqual(v.x, bonePos.x, 0.000001) or not MR_Utilities:IsEqual(v.y, bonePos.y, 0.000001) then
			if (self.multiTransform and self.keepSelection and not self.selBoneIsAncestorSelected) or not(self.multiTransform and self.keepSelection) then
				bone.fAnimPos:SetValue(moho.layerFrame, v)
				if smartBake and not self.boneBakedP then
					self:BakeFrames(moho, bone, nil, false, true, false)
					self.boneBakedP = true
				end
			end
				
			if self.multiTransform and self.keepSelection then
				for i=1, #self.multiBoneTranslateList do
					if self.multiBoneTranslateList[i] ~= self.secondBoneID then
						local sBone = skel:Bone(self.multiBoneTranslateList[i])
						sBone.fPos:Set(sBone.fTempPos)

						local offset = mouseEvent.vec - mouseEvent.startVec
						
						local subBoneVec = LM.Vector2:new_local()
						local inverseM = LM.Matrix:new_local()
						
						local parent = nil
						subBoneVec:Set(0, 0)
						if (sBone.fParent >= 0) then
							parent = skel:Bone(sBone.fParent)
							parent.fMovedMatrix:Transform(subBoneVec)
						end
						subBoneVec = subBoneVec + offset
						if (parent) then
							inverseM:Set(parent.fMovedMatrix)
							inverseM:Invert()
							inverseM:Transform(subBoneVec)
						end
						if mouseEvent.shiftKey and not self.forceBoneTranslationShift then
							if (math.abs(subBoneVec.x) > math.abs(subBoneVec.y)) then
								subBoneVec.y = 0
							else
								subBoneVec.x = 0
							end
						end
						local v = nil
						v = sBone.fPos + subBoneVec

						local bonePos = sBone.fAnimPos:GetValue(moho.layerFrame)
						if not MR_Utilities:IsEqual(v.x, bonePos.x, 0.000001) or not MR_Utilities:IsEqual(v.y, bonePos.y, 0.000001) then
							sBone.fAnimPos:SetValue(moho.layerFrame, v)
							if smartBake and not self.multiBoneTranslateBakedList[i] then
								if moho.layerFrame - self.interval > 0 then
									sBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.multiBoneTranslateSBValuesPList[i])
								end
								if moho.layerFrame + self.interval > 0 then
									sBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.multiBoneTranslateSBValuesNList[i])
								end
								self.multiBoneTranslateBakedList[i] = true
							end
						end
					end
				end
			end
		end	
	end	
	if self.mode == 0 then
		if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
			if mouseEvent.altKey and bone.fLength > 0 and not self.forceBoneTranslationAlt then
				if (self.selBones == 1 and self.multiTransform and self.keepSelection) or (self.keepSelection and not self.multiTransform) or (not self.keepSelection) then
					local vectorMousePos = mouseEvent.vec + self.clickOffset
					local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)
					local secondDelta = (secondCursorDist / self.secondBoneDist)
					local newScale = (bone.fTempScale * secondDelta) - self.secondBoneSizeDelta
					if not MR_Utilities:IsEqual(newScale, bone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
						bone.fAnimScale:SetValue(moho.layerFrame, newScale)
						if smartBake and not self.boneBakedS then
							self:BakeFrames(moho, bone, nil, false, false, true)
							self.boneBakedS = true
						end
					end
					moho.layer:UpdateCurFrame()

					local center = LM.Vector2:new_local()

					center:Set(0, 0)
					skel:UpdateBoneMatrix(self.secondBoneID)
					bone.fMovedMatrix:Transform(center)
					
					local angle = self.startAngle2
					local v1 = self.lastVec2 - self.secondBoneTipPos
					local v2 = center - self.secondBoneTipPos
					v2:Rotate(-math.atan2(v1.y, v1.x))
					angle = angle + math.atan2(v2.y, v2.x)
					self.startAngle2 = angle
					self.lastVec2:Set(center)

					local angleSign = 1.0
					if (not bone.fFixedAngle) then
						angleSign = bone:ParentalFlipFactor()
					end
					
					local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta
					if not bone.fFixedAngle then
						if bone.fConstraints then
							local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
							local max = min + bone.fMaxConstraint
							min = min + bone.fMinConstraint
							newAgle = LM.Clamp(newAgle, min, max)
						end
					end
					if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
						bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
						bone.fAnimAngle.value = bone.fAngle
					end
					if smartBake and not self.boneBakedA then
						self:BakeFrames(moho, bone, nil, true, false, false)
						self.boneBakedA = true
						if not self.isChildBonesBaked then
							for i, q in ipairs(self.childBones) do
								local bone = skel:Bone(q)
								if moho.layerFrame - self.interval > 0 then
									bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
									bone.fAnimAngle.value = bone.fAngle
								end
								if moho.layerFrame + self.interval > 0 then
									bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
									bone.fAnimAngle.value = bone.fAngle
								end
							end
							self.isChildBonesBaked = true
						end
						
					end

					local angleSign = 1
					if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
						angleSign = -1
					end
					
					moho.layer:UpdateCurFrame()
					local angleDelta = bone.fAngle - bone.fTempAngle
					
					for i, q in ipairs(self.childBones) do
						local bone = skel:Bone(q)
						bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle - (angleDelta * angleSign))
						bone.fAnimAngle.value = bone.fAngle
					end
				end
			end	
		else
			if not MR_Utilities:IsEqual(bone.fTempScale - self.secondBoneSizeDelta, bone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimScale:SetValue(moho.layerFrame, bone.fTempScale)
			end
			local newAngle = bone.fTempAngle - self.secondBoneAngleDelta
			if not MR_Utilities:IsEqual(newAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
			end	
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
				end	
			end
		end
	end
	self:AdjustFollowAndLockBones(moho)
	
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedR(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end

	local secondBone = skel:Bone(self.secondBoneID)

	local bone = secondBone
	local center = LM.Vector2:new_local()
	center:Set(0, 0)
	skel:UpdateBoneMatrix()
	bone.fMovedMatrix:Transform(center)
	
	local mousePos = mouseEvent.vec
	local angle = self.startAngle
	local v1 = self.lastVec - center
	local v2 = mousePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.startAngle = angle
	self.lastVec:Set(mousePos)
	local angleSign = 1.0
	if (not bone.fFixedAngle) then
		angleSign = bone:ParentalFlipFactor()
	end

	local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta
	
	if not bone.fFixedAngle then
		if bone.fConstraints then
			local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
			local max = min + bone.fMaxConstraint
			min = min + bone.fMinConstraint
			newAgle = LM.Clamp(newAgle, min, max)
		end
	end
	
	if (mouseEvent.shiftKey) then
		newAgle = newAgle / (math.pi / 4)
		newAgle = (math.pi / 4) * LM.Round(newAgle)
	end
	
	if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
		if smartBake and not self.boneBakedA then
			self:BakeFrames(moho, secondBone, nil, true, false, false)
			self.boneBakedA = true
		end
	end	

	local angleSign = 1
	if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
		angleSign = -1
	end
	
	if self.multiTransform and self.keepSelection then
		for i=1, #self.selectedBonesList do
			if self.selectedBonesList[i] ~= self.secondBoneID then
				local sBone = skel:Bone(self.selectedBonesList[i])
				local center = LM.Vector2:new_local()
				center:Set(0, 0)
				
				sBone.fMovedMatrix:Transform(center)

				local selectedAngleSign = 1.0
				if (not sBone.fFixedAngle) then
					selectedAngleSign = sBone:ParentalFlipFactor()
				end

				local newSelAgle = (sBone.fTempAngle + (angle * selectedAngleSign))

				if not MR_Utilities:IsEqual(newSelAgle, sBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimAngle:SetValue(moho.layerFrame, newSelAgle)
					if smartBake and not self.multiBoneAngleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.multiBoneAngleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.multiBoneAngleSBValuesNList[i])
						end
						self.multiBoneAngleBakedList[i] = true
					end
				end
			end
		end
	end
	
	if not (self.multiTransform and self.keepSelection and self.selBones > 1) then
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			local angleDelta = secondBone.fAngle - secondBone.fTempAngle
			
			if smartBake and not self.isChildBonesBaked then
				for i, q in ipairs(self.childBones) do
					local childBone = skel:Bone(q)
					if moho.layerFrame - self.interval > 0 then
						childBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						childBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end	
				self.isChildBonesBaked = true
			end
			
			for i, q in ipairs(self.childBones) do
				local childBone = skel:Bone(q)
				childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle - (angleDelta * angleSign))
			end
		else
			for i, q in ipairs(self.childBones) do
				local childBone = skel:Bone(q)
				if not MR_Utilities:IsEqual(childBone.fTempAngle, childBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle)
				end	
			end
		end
	end

	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedS(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	local secondBone = skel:Bone(self.secondBoneID)

	if secondBone:IsZeroLength() then
		local scaleFactor = (mouseEvent.pt.x - mouseEvent.startPt.x) / 100
		if (scaleFactor < 0) then
			scaleFactor = 1 / (-scaleFactor + 1)
		else
			scaleFactor = scaleFactor + 1
		end
		local newScale = (secondBone.fTempScale * scaleFactor) - self.secondBoneSizeDelta
		if not MR_Utilities:IsEqual(newScale, secondBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
			secondBone.fAnimScale:SetValue(moho.layerFrame, newScale)
			if smartBake and not self.boneBakedS then
				self:BakeFrames(moho, secondBone, nil, false, false, true)
				self.boneBakedS = true
			end
		end
		
		if self.multiTransform and self.keepSelection then
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				local newSelectedScale = (sBone.fTempScale * scaleFactor) - self.multiBoneScaleDeltaList[i]
				if not MR_Utilities:IsEqual(newSelectedScale, sBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimScale:SetValue(moho.layerFrame, newSelectedScale)
					if smartBake and not self.multiBoneScaleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.multiBoneScaleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.multiBoneScaleSBValuesNList[i])
						end
						self.multiBoneScaleBakedList[i] = true
					end
				end
			end
		end
	else
		local vectorMousePos = mouseEvent.vec + self.clickOffset
		local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBonePos)
		local secondDelta = (secondCursorDist / self.secondBoneDist)
		local newScale = (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta
		if not MR_Utilities:IsEqual(newScale, secondBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
			secondBone.fAnimScale:SetValue(moho.layerFrame, newScale)
			if smartBake and not self.boneBakedS then
				self:BakeFrames(moho, secondBone, nil, false, false, true)
				self.boneBakedS = true
			end
		end
		
		if self.multiTransform and self.keepSelection then
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				local newSelectedScale = (sBone.fTempScale * secondDelta) - self.multiBoneScaleDeltaList[i]
				if not MR_Utilities:IsEqual(newSelectedScale, sBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimScale:SetValue(moho.layerFrame, newSelectedScale)
					if smartBake and not self.multiBoneScaleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.multiBoneScaleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.multiBoneScaleSBValuesNList[i])
						end
						self.multiBoneScaleBakedList[i] = true
					end
				end
			end
		end
		if self.multiTransform and self.keepSelection and self.selBones == 1 or not (self.multiTransform and self.keepSelection) then
			if not mouseEvent.shiftKey then
				local bone = secondBone
				local center = LM.Vector2:new_local()
				center:Set(0, 0)
				skel:UpdateBoneMatrix()
				bone.fMovedMatrix:Transform(center)
				
				local mousePos = mouseEvent.vec
				
				local angle = self.startAngle
				local v1 = self.lastVec - center
				local v2 = mousePos - center
				v2:Rotate(-math.atan2(v1.y, v1.x))
				angle = angle + math.atan2(v2.y, v2.x)
				self.startAngle = angle
				self.lastVec:Set(mousePos)
				local angleSign = 1.0
				if (not bone.fFixedAngle) then
					angleSign = bone:ParentalFlipFactor()
				end

				local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta

				if not bone.fFixedAngle then
					if bone.fConstraints then
						local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
						local max = min + bone.fMaxConstraint
						min = min + bone.fMinConstraint
						newAgle = LM.Clamp(newAgle, min, max)
					end
				end
				if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
					if smartBake and not self.boneBakedA then
						self:BakeFrames(moho, secondBone, nil, true, false, false)
						self.boneBakedA = true
					end
				end	
			else
				local bone = secondBone
				local newAngle = bone.fTempAngle - self.secondBoneAngleDelta
				if not MR_Utilities:IsEqual(newAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
					if smartBake and not self.boneBakedA then
						self:BakeFrames(moho, secondBone, nil, true, false, false)
						self.boneBakedA = true
					end
				end	
			end
		end
	end
	
	local angleSign = 1
	if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
		angleSign = -1
	end
	
	if self.isChainTargeted then
		local targetBone = skel:Bone(self.secondTarget)
		local newTargetPos = targetBone.fTempPos - (mouseEvent.startVec - mouseEvent.vec)
		targetBone.fAnimPos:SetValue(moho.layerFrame, newTargetPos)
		self.isTargetMoved = true
		if smartBake then
			if not self.isTargetBonePosPBaked then
				if moho.layerFrame - self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.targetBonePosP)
				end
				self.isTargetBonePosPBaked = true
			end
			
			if not self.isTargetBonePosNBaked then
				if moho.layerFrame + self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.targetBonePosN)
				end
				self.isTargetBonePosNBaked = true
			end
		end	
	end
	if not (self.multiTransform and self.keepSelection and self.selBones > 1) then
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			if smartBake and not self.isChildBonesBaked then
				for i, q in ipairs(self.childBones) do
					local bone = skel:Bone(q)
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end
				self.isChildBonesBaked = true
			end

			local angleDelta = secondBone.fAngle - secondBone.fTempAngle
			
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle - (angleDelta * angleSign))
			end
		else
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
				end	
			end
		end
	end
	
	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedM(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end

	local riggingFrame = 0
	local bone = skel:Bone(self.selID)
	local secondBone = skel:Bone(self.selID)
	
	if smartBake and not self.boneBakedA then
		self:BakeFrames(moho, secondBone, nil, true, false, false)
		self.boneBakedA = true
	end
	skel:UpdateBoneMatrix(self.selID)

	local tipVec = LM.Vector2:new_local()

	tipVec:Set(bone.fLength, 0)
	bone.fMovedMatrix:Transform(tipVec)
	tipVec = tipVec + (mouseEvent.vec - self.lastVec)
	
	local startBone = skel:Bone(self.parentBones[#self.parentBones])
	local center = LM.Vector2:new_local()
	center:Set(0, 0)
	skel:UpdateBoneMatrix()
	startBone.fMovedMatrix:Transform(center)

	local mousePos = mouseEvent.vec
	
	local angle = self.startAngle
	local v1 = self.lastVec - center
	local v2 = mousePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.startAngle = angle
	self.lastVec:Set(mousePos)
	local angleSign = 1.0
	if (not startBone.fFixedAngle) then
		angleSign = startBone:ParentalFlipFactor()
	end

	local newAgle = (startBone.fTempAngle + (angle * angleSign))
	if mouseEvent.shiftKey then
		if smartBake and not self.boneBakedS then
			self:BakeFrames(moho, secondBone, nil, false, false, true)
			for i, q in ipairs(self.parentBones) do
				local bone = skel:Bone(q)
				if moho.layerFrame - self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.parentBonesScaleP[i])
				end
				if moho.layerFrame + self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.parentBonesScaleN[i])
				end
			end	
			self.boneBakedS = true
		end
	
		if smartBake and not self.boneBakedS then
			self:BakeFrames(moho, secondBone, nil, false, false, true)
			self.boneBakedS = true
		end
		
		local newStartBoneDist = MR_Utilities:GetDistance(self.startBonePos, mouseEvent.vec)
		local startBoneDistDelta = newStartBoneDist / self.startBoneDist
		bone.fAnimScale:SetValue(moho.layerFrame, (bone.fTempScale * startBoneDistDelta) - self.secondBoneSecondDelta)
		
		if not startBone.fFixedAngle then
			if startBone.fConstraints then
				local min = startBone.fAnimAngle:GetValue(0) - self.startBoneAngleDelta
				local max = min + startBone.fMaxConstraint
				min = min + startBone.fMinConstraint
				newAgle = LM.Clamp(newAgle, min, max)
			end
		end

		for i, q in ipairs(self.parentBones) do
			local parentBone = skel:Bone(q)

			parentBone.fAnimScale:SetValue(moho.layerFrame, (parentBone.fTempScale * startBoneDistDelta) - self.parentBonesScaleDelta[i])
			if not MR_Utilities:IsEqual(parentBone.fTempAngle, parentBone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
				parentBone.fAnimAngle:SetValue(moho.layerFrame, parentBone.fTempAngle)
			end	
		end	
		if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
			bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
		end	
		startBone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
	else
		skel:IKAngleSolver(self.selID, tipVec)
		local boneID = 1
		bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - (self.boneStartActualAngles[boneID] - self.boneStartAngles[boneID]))
		bone.fAnimAngle.value = bone.fAngle
		boneID = boneID + 1
		while bone.fParent >= 0 do
			if (self:CountBoneChildren(skel, bone.fParent, true) > 1) then
				break
			end
			local parentBone = skel:Bone(bone.fParent)
			if self.mohoVersion >= 14 then
				if (parentBone.fAngleControlParent >= 0 or
					parentBone.fPosControlParent >= 0 or
					parentBone.fScaleControlParent >= 0 or
					parentBone:AreDynamicsActive() or
					parentBone.fFixedAngle or
					parentBone.fIgnoredByIK) then
					break
				end
			else
				if (parentBone.fAngleControlParent >= 0 or
					parentBone.fPosControlParent >= 0 or
					parentBone.fScaleControlParent >= 0 or
					parentBone.fBoneDynamics.value or
					parentBone.fFixedAngle or
					parentBone.fIgnoredByIK) then
					break
				end
			end	

			bone = skel:Bone(bone.fParent)
			bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - (self.boneStartActualAngles[boneID] - self.boneStartAngles[boneID]))
			bone.fAnimAngle.value = bone.fAngle
			boneID = boneID + 1
		end
	end

	if #self.parentBones == 1 then
		local firstBone = skel:Bone(self.parentBones[1])
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			local angleSign = 1
			local angleSignS = 1
			if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
				angleSignS = -1
			end
			local angleSignF = 1
			if (firstBone.fFlipH.value and not firstBone.fFlipV.value) or (not firstBone.fFlipH.value and firstBone.fFlipV.value) then
				angleSignF = -1
			end
			
			local angleDelta = 0
			if angleSignF == 1 and angleSignS == -1 then
				angleSign = -1
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)
			elseif angleSignF == 1 and angleSignS == 1 then
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)	
			elseif angleSignF == -1 and angleSignS == -1 then
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
			elseif angleSignF == -1 and angleSignS == 1 then
				angleSign = -1
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
			end
		
			moho.layer:UpdateCurFrame()

			if not self.isChildBonesBaked and smartBake then
				for i, q in ipairs(self.childBones) do
					local bone = skel:Bone(q)
					if not self.isChildBonesBaked then
						if moho.layerFrame - self.interval > 0 then
							bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
						end
					end
					if not self.isChildBonesBaked then
						if moho.layerFrame + self.interval > 0 then
							bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
						end
					end
				end
				self.isChildBonesBaked = true
			end	
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				local newAngle = bone.fTempAngle - (angleDelta * angleSign)
				bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
			end
		else
			for i, q in ipairs(self.childBones) do
				local firstBone = skel:Bone(q)
				if not MR_Utilities:IsEqual(firstBone.fTempAngle, firstBone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
					firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fTempAngle)
				end	
			end
		end
	end
	
	if smartBake and not self.isParentBonesBaked then
		for i, q in ipairs(self.parentBones) do
			local bone = skel:Bone(q)
			if moho.layerFrame - self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.parentBonesAngleP[i])
			end
			if moho.layerFrame + self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.parentBonesAngleN[i])
			end
		end	
		self.isParentBonesBaked = true
	end
	
	if self.isChainTargeted then
		local targetBone = skel:Bone(self.secondTarget)
		local newTargetPos = targetBone.fTempPos - (mouseEvent.startVec - mouseEvent.vec)
		targetBone.fAnimPos:SetValue(moho.layerFrame, newTargetPos)
		self.isTargetMoved = true
		if smartBake then
			if not self.isTargetBonePosPBaked then
				if moho.layerFrame - self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.targetBonePosP)
				end
				self.isTargetBonePosPBaked = true
			end
			
			if not self.isTargetBonePosNBaked then
				if moho.layerFrame + self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.targetBonePosN)
				end
				self.isTargetBonePosNBaked = true
			end
		end	
	end
	
	self:AdjustFollowAndLockBones(moho)
	skel:UpdateBoneMatrix()
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
	self.lastVec:Set(mouseEvent.vec)
end	

function MR_PoseTool:OnMouseUp(moho, mouseEvent)
	self.buttonPressed = 0
	self.operationFailes = 0
	if self.scriptValidated ~= true then
		return
	end
	self.ignoreBonesList = {}
	moho:UpdateBonePointSelection()
	local frame = moho.frame
	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) then
			moho:UpdateSelectedChannels()
			moho:UpdateUI()
			return
		end
	end
	
	self.dragging = false
	local skel = moho:Skeleton()
	if skel == nil or frame == 0 then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	if self.showQuickMenu or self.showQuickMenu2 or self.showQuickMenu3 then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end

	if self.lockHandlesSelection and self.isLockHandleMouseMoved then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	if self.setKeyframe then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	self.isLockHandleMouseMoved = false

	if self.multiSelectionUnselectedMovement then
		self.mousePickedID = -1
	end
	self.multiSelectionUnselectedMovement = false

	if not self.isMouseDragging then
		if not self.isMouseMoved or (self.lockHandlesSelection and not (self.multiTransform and self.keepSelection)) then
			if mouseEvent.shiftKey or mouseEvent.altKey then
				skel:SelectNone()
				for i, id in ipairs(self.selectedBonesList) do
					local sBone = skel:Bone(id)
					if sBone then
						sBone.fSelected = true
					end
				end
			end
			
			local bonesVisibilityList = {}
			for i=0, skel:CountBones()-1 do
				local bone = skel:Bone(i)
				if not bone.fSelected then
					bonesVisibilityList[i+1] = bone.fHidden
					bone.fHidden = true
				end	
			end
			
			local pickWidth = self.pickWidth
			
			local id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			
			for i=0, skel:CountBones()-1 do
				local bone = skel:Bone(i)
				if not bone.fSelected then
					bone.fHidden = bonesVisibilityList[i+1]
				end
			end
			
			if id == -1 then
				id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			end
			
			if not mouseEvent.shiftKey and not mouseEvent.altKey then
				skel:SelectNone()
			end	
			if id ~= -1 then
				skel:Bone(id).fSelected = not mouseEvent.altKey
			end
		
			local firstBone = skel:Bone(self.firstBoneID)
			if self.isBoneHaveAngleKeyList[self.firstBoneID] == false then
				firstBone.fAnimAngle:DeleteKey(moho.layerFrame)
			end

			if self.isBoneHaveScaleKeyList[self.firstBoneID] == false then
				firstBone.fAnimScale:DeleteKey(moho.layerFrame)
			end
			
			local secondBone = skel:Bone(self.secondBoneID)
			if self.isBoneHaveAngleKeyList[self.secondBoneID] == false then
				secondBone.fAnimAngle:DeleteKey(moho.layerFrame)
			end

			if self.isBoneHaveScaleKeyList[self.secondBoneID] == false then
				secondBone.fAnimScale:DeleteKey(moho.layerFrame)
			end
			if self.holdToReset then
				local upTime = os.time()
				if upTime - self.clickTime >= 2 then
					if self.selBonesList[self.secondBoneID] then
						local bone = skel:Bone(self.secondBoneID)
						if self.mode == 0 then
							if mouseEvent.altKey then
								bone.fTempScale = bone.fScale
								
								self.childBones = {}
								self.childBonesAngelP = {}
								self.childBonesAngelN = {}
								
								for i=0, skel:CountBones()-1 do
									local childBone = skel:Bone(i)
									if  childBone.fParent == self.secondBoneID and not childBone.fFixedAngle and not childBone.fIgnoredByIK then
										local angle = childBone.fAnimAngle:GetValue(moho.layerFrame)
										childBone.fTempAngle = angle
										table.insert(self.childBones, i)
										
										if moho.layerFrame - self.interval > 0 then
											table.insert(self.childBonesAngelP, childBone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
										else
											table.insert(self.childBonesAngelP, 0)
										end
										
										if moho.layerFrame + self.interval > 0 then
											table.insert(self.childBonesAngelN, childBone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
										else
											table.insert(self.childBonesAngelN, 0)
										end
									end
								end
								
								local secondBoneSizeDelta = bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame)
								local secondBoneAngleDelta = bone.fAngle - bone.fAnimAngle:GetValue(moho.layerFrame)
								
								local secondTipVec = LM.Vector2:new_local()
								secondTipVec:Set(bone.fLength, 0)
								bone.fMovedMatrix:Transform(secondTipVec)
								
								local secondVec = LM.Vector2:new_local()
								secondVec:Set(0, 0)
								bone.fMovedMatrix:Transform(secondVec)
								
								local boneDist = MR_Utilities:GetDistance(secondVec, secondTipVec)
								
								bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
								skel:UpdateBoneMatrix()
								moho.layer:UpdateCurFrame()
								secondVec:Set(0, 0)
								bone.fMovedMatrix:Transform(secondVec)
								
								local NewboneDist = MR_Utilities:GetDistance(secondVec, secondTipVec)
								local secondDelta = (NewboneDist / boneDist)
								local newScale = (bone.fTempScale * secondDelta) - secondBoneSizeDelta
								
								bone.fAnimScale:SetValue(moho.layerFrame, newScale)
								
								local isIgnoredByIK = bone.fIgnoredByIK
								bone.fIgnoredByIK = false
								moho.layer:UpdateCurFrame()
								
								skel:IKAngleSolver(self.secondBoneID, secondTipVec, 1, true, true)

								bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - secondBoneAngleDelta)
								bone.fAnimAngle.value = bone.fAngle
								
								local angleSign = 1
								if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
									angleSign = -1
								end

								local angleDelta = bone.fAngle - bone.fTempAngle
								
								for i, q in ipairs(self.childBones) do
									local childBone = skel:Bone(q)
									childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle - (angleDelta * angleSign))
								end
								
								bone.fIgnoredByIK = isIgnoredByIK
							else	
								for i, b in ipairs(self.selectedBonesList) do
									local bone = skel:Bone(b)
									if bone then
										bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
									end	
								end
							end

							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end
							
							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE_T)
							moho:UpdateUI()
							return
						elseif self.mode == 1 then
							for i, b in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(b)
								if bone then
									bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAnimAngle:GetValue(0))
								end	
							end
							
							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end

							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE)
							moho:UpdateUI()
							return
						elseif self.mode == 2 then
							for i, b in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(b)
								if bone then
									bone.fAnimScale:SetValue(moho.layerFrame, bone.fAnimScale:GetValue(0))
								end	
							end
							
							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end

							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE_S)
							moho:UpdateUI()
							return
						end
					else
						moho.layer:UpdateCurFrame()
						moho:NewKeyframe(CHANNEL_BONE_S)
						moho:UpdateUI()
						return
					end
				end
			end
			
			moho:UpdateSelectedChannels()
			moho:UpdateUI()
			self:OnMouseMoved(moho, mouseEvent)
			return
		end
	end
	
	self.isMouseMoved = false
	self.lockHandlesSelection = false
	if self.isMouseDragging then
		local v = LM.Vector2:new_local()
		local screenPt = LM.Point:new_local()
		local m = LM.Matrix:new_local()
		
		self.selRect:Normalize()
		moho.layer:GetFullTransform(moho.frame, m, moho.document)
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			local boneMatrix = bone.fMovedMatrix
			for j = 0, 10 do
				v:Set(bone.fLength * j / 10.0, 0)
				boneMatrix:Transform(v)
				m:Transform(v)
				mouseEvent.view:Graphics():WorldToScreen(v, screenPt)
				if (self.selRect:Contains(screenPt)) then
					if (mouseEvent.altKey) then
						bone.fSelected = false
					else
						bone.fSelected = true
					end
					break
				end
			end
		end
		self.isMouseDragging = false
		if self.bonesReset then
			skel:SelectNone()
			for i, boneID in ipairs(self.selectedBonesList) do
				local bone = skel:Bone(boneID)
				bone.fSelected = true
			end
		end
		self.bonesReset = false
		moho:UpdateSelectedChannels()
		return
	end

	if self.isActive == false then
		if self.bonesReset then
			skel:SelectNone()
			for i, boneID in ipairs(self.selectedBonesList) do
				local bone = skel:Bone(boneID)
				bone.fSelected = true
			end
		end
		moho:UpdateSelectedChannels()
		self.bonesReset = false
		return
	end
	
	local bone
	if self.firstBoneID > -1 then
		bone = skel:Bone(self.firstBoneID)
	end

	local secondBoneID = skel:Bone(self.secondBoneID)
	
	if self.firstBoneParentID > -1 then
		local firstBoneParent = skel:Bone(self.firstBoneParentID)
		if firstBoneParent then
			firstBoneParent.fIgnoredByIK = self.firstBoneParentIBIK
		end	
	end
	
	self.firstBoneID = -1
	self.firstBoneParentID = -1
	self.firstBoneParentIBIK = -1
	self.secondBoneID = -1
	if self.keepSelection and self.selBones > 0 then
		skel:SelectNone()
		for i, boneID in ipairs(self.selectedBonesList) do
			local bone = skel:Bone(boneID)
			bone.fSelected = true
		end
	end
	
	if MOHO.MohoGlobals.AutoFreezeKeys then
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not (bone.fHidden and not bone.fShy) then
				local frame = moho.layerFrame
				bone.fAnimAngle:SetValue(frame, bone.fAnimAngle:GetValue(frame))
				bone.fAnimPos:SetValue(frame, bone.fAnimPos:GetValue(frame))
				bone.fAnimScale:SetValue(frame, bone.fAnimScale:GetValue(frame))
			end
		end
	end
	
	if MOHO.MohoGlobals.EditMultipleKeys then
		self:EditMultipleKeys(moho)
	end
	
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
	moho:UpdateSelectedChannels()
	moho:UpdateUI()
end

function MR_PoseTool:DrawMe(moho, view)
	local skel = moho:Skeleton()
	if (skel == nil) or moho.frame == 0 then
		return
	end
	
	local markerR = self.markerR
	
	if self.additionHandles then
		markerR = self.markerR2
	end
	local selBones = moho:CountSelectedBones()
	local v = LM.Vector2:new_local()
	local g = view:Graphics()
	local layerMatrix = LM.Matrix:new_local()
	local interp = MOHO.InterpSetting:new_local()
	local center = LM.Vector2:new_local()
	local tip = LM.Vector2:new_local()
	local offset = LM.Vector2:new_local()
	local boneCenterPos = LM.Vector2:new_local()
	local boneHandlePos = LM.Vector2:new_local()
	local angle = 0
	local newAngle = 0
	local offsetAngle = 0
	local alignHandlesAdaptation = false
	local handlesZoomAdaptationVal = 1
	local handlesAdaptation = false

	if self.isMouseDragging then
		local g = view:Graphics()
		g:SelectionRect(self.selRect)
		g:Pop()
		return
	end
	
	local hlDelta = 0
	
	local handlesDistance = self.handlesDistance
	if self.alignHandlesAlongBone then
		handlesDistance = 1
	end
	
	moho.layer:GetFullTransform(moho.frame, layerMatrix, moho.document)
	g:Push()
	g:ApplyMatrix(layerMatrix)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local markerMultiplier = 0.002
	local additionMarker1 = self.additionHandles
	local currentScale = g:CurrentScale(false)
	g:SetSmoothing(true)
	g:SetBezierTolerance(2)

	local wireframe = MOHO.hasbit(moho.view:QualityFlags(), MOHO.bit(MOHO.LDQ_WIREFRAME))
	if self.bonesDataActive and wireframe and not moho:IsPlaying() then
		local isFollowBonesSelected = false
		for i=1, #self.followBonesList do
			local followBone = skel:Bone(self.followBonesList[i])
			if followBone.fSelected then
				isFollowBonesSelected = true
				break
			end
		end

		if #self.lockAngleList > 0 and self.bonesDataActiveA then
			g:SetPenWidth(10)
			g:SetColor(255, 241, 229, 255)
			local radius = 14
			
			for b=1, #self.lockAngleList do
				local boneId = self.lockAngleList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(0, 0)
						lockBoneTip:Set(lockBone.fLength / 3, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if not lockBone:IsZeroLength() then
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			
			g:SetPenWidth(4)
			g:SetColor(self.lockAngleColor)
			
			for b=1, #self.lockAngleList do
				local boneId = self.lockAngleList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(0, 0)
						lockBoneTip:Set(lockBone.fLength / 3, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if lockBone:IsZeroLength() then
							g:SetColor(self.lockAngleColor)
							g:FillCirclePixelRadius(lockBoneCenter, radius)
							g:SetColor(self.iconColorBack)
							g:FrameCirclePixelRadius(lockBoneCenter, radius)
							g:SetColor(self.lockAngleColor)
						else
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			g:SetPenWidth(1)
		end
		
		if #self.lockPosList > 0 and self.bonesDataActiveP then
			g:SetPenWidth(10)
			g:SetColor(self.iconColorBack)
			local radius = 10
			
			for b=1, #self.lockPosList do
				local boneId = self.lockPosList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(lockBone.fLength, 0)
						lockBoneTip:Set(lockBone.fLength / 1.5, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if not lockBone:IsZeroLength() then
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			
			g:SetPenWidth(4)
			g:SetColor(self.lockPosColor)
			
			for b=1, #self.lockPosList do
				local boneId = self.lockPosList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(lockBone.fLength, 0)
						lockBoneTip:Set(lockBone.fLength / 1.5, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if lockBone:IsZeroLength() then
							g:SetColor(self.lockPosColor)
							g:FrameCirclePixelRadius(lockBoneCenter, radius)
						else
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			g:SetPenWidth(1)
		end

		if not isFollowBonesSelected or self.forceFollowBonesGraphics then
			if #self.followBonesList.id > 0 and self.bonesDataActiveF then
				for b=1, #self.followBonesList.id do
					local isBlocked = false
					if self.dragging then
						if self.followBonesDataList.block and self.mode ~= 0 then
							isBlocked = self.followBonesDataList.block[b]
						end
					end

					if not isBlocked then
						g:SetPenWidth(2)
						g:SetColor(self.colorFollowBones)
						for i=1, #self.followBonesList.id[b] do
							local followBone = skel:Bone(self.followBonesList.id[b][i])
							if i + 1 <= #self.followBonesList.id[b] then
								if followBone then
									local nextBone = skel:Bone(self.followBonesList.id[b][i + 1])
									if nextBone then
										local followBoneCenter = LM.Vector2:new_local()
										local nextBoneCenter = LM.Vector2:new_local()
										followBoneCenter:Set(followBone.fLength / 2, 0)
										nextBoneCenter:Set(nextBone.fLength / 2, 0)
										followBone.fMovedMatrix:Transform(followBoneCenter)
										nextBone.fMovedMatrix:Transform(nextBoneCenter)
										g:DrawLine(followBoneCenter.x, followBoneCenter.y, nextBoneCenter.x, nextBoneCenter.y)
									end
								end
							end
						end
						g:SetPenWidth(1)
					end
				end

				for b=1, #self.followBonesList.id do
					local isBlocked = false
					if self.dragging then
						if self.followBonesDataList.block and self.mode ~= 0  then
							isBlocked = self.followBonesDataList.block[b]
						end
					end
					if not isBlocked then
						g:SetPenWidth(10)
						g:SetColor(196, 235, 255, 255)
						for i=1, #self.followBonesList.id[b] do
							local boneId = self.followBonesList.id[b][i]
							local followBone = skel:Bone(boneId)
							if followBone then
								if not self.ignoreBonesList[boneId + 1] then
									local followBoneCenter = LM.Vector2:new_local()
									local followBoneTip = LM.Vector2:new_local()
									followBoneCenter:Set(followBone.fLength / 1.5, 0)
									followBoneTip:Set(followBone.fLength / 3, 0)
									followBone.fMovedMatrix:Transform(followBoneCenter)
									followBone.fMovedMatrix:Transform(followBoneTip)
									g:DrawLine(followBoneCenter.x, followBoneCenter.y, followBoneTip.x, followBoneTip.y)
								end
							end
						end
						g:SetPenWidth(4)
						g:SetColor(self.colorFollowBones)
						for i=1, #self.followBonesList.id[b] do
							local boneId = self.followBonesList.id[b][i]
							local followBone = skel:Bone(boneId)
							if followBone then
								if not self.ignoreBonesList[boneId + 1] then
									local followBoneCenter = LM.Vector2:new_local()
									local followBoneTip = LM.Vector2:new_local()
									followBoneCenter:Set(followBone.fLength / 1.5, 0)
									followBoneTip:Set(followBone.fLength / 3, 0)
									followBone.fMovedMatrix:Transform(followBoneCenter)
									followBone.fMovedMatrix:Transform(followBoneTip)
									g:DrawLine(followBoneCenter.x, followBoneCenter.y, followBoneTip.x, followBoneTip.y)
								end
							end
						end
						if self.dragging then
							g:SetColor(self.colorHighlightBone)
							g:SetPenWidth(3)
							local markersSize = (0.015) / currentScale / height
							local marker1VecCam = self.followBonesDataList.targetPos[b]
							g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
							g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
						elseif self.showCross then
							if MR_TweenMachine and self.followBonesDataList.targetPos[b] then
								g:SetColor(self.colorHighlightBone)
								g:SetPenWidth(3)
								local markersSize = (0.015) / currentScale / height
								local marker1VecCam = self.followBonesDataList.targetPos[b]
								g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
								g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
							end
						end
						g:SetPenWidth(1)
					end
				end
			end
		end
			
		if #self.ikBonesList.id > 0 and self.bonesDataActiveIK then
			for b=1, #self.ikBonesList.id do
				local isBlocked = false
				if self.dragging then
					if self.ikBonesDataList.block and self.mode ~= 0 then
						isBlocked = self.ikBonesDataList.block[b]
					end
				end

				if not isBlocked then
					g:SetPenWidth(2)
					g:SetColor(self.colorIkBones)
					for i=1, #self.ikBonesList.id[b] do
						local followBone = skel:Bone(self.ikBonesList.id[b][i])
						if i + 1 <= #self.ikBonesList.id[b] then
							if followBone then
								local nextBone = skel:Bone(self.ikBonesList.id[b][i + 1])
								if nextBone then
									local ikBoneCenter = LM.Vector2:new_local()
									local nextBoneCenter = LM.Vector2:new_local()
									ikBoneCenter:Set(followBone.fLength / 2, 0)
									nextBoneCenter:Set(nextBone.fLength / 2, 0)
									followBone.fMovedMatrix:Transform(ikBoneCenter)
									nextBone.fMovedMatrix:Transform(nextBoneCenter)
									g:DrawLine(ikBoneCenter.x, ikBoneCenter.y, nextBoneCenter.x, nextBoneCenter.y)
								end
							end
						end
					end
					g:SetPenWidth(1)
				end
			end

			for b=1, #self.ikBonesList.id do
				local isBlocked = false
				if self.dragging then
					if self.ikBonesDataList.block and self.mode ~= 0  then
						isBlocked = self.ikBonesDataList.block[b]
					end
				end
				if not isBlocked then
					g:SetPenWidth(10)
					g:SetColor(196, 235, 255, 255)
					for i=1, #self.ikBonesList.id[b] do
						local boneId = self.ikBonesList.id[b][i]
						local followBone = skel:Bone(boneId)
						if followBone then
							if not self.ignoreBonesList[boneId + 1] then
								local ikBoneCenter = LM.Vector2:new_local()
								local followBoneTip = LM.Vector2:new_local()
								ikBoneCenter:Set(followBone.fLength / 1.5, 0)
								followBoneTip:Set(followBone.fLength / 3, 0)
								followBone.fMovedMatrix:Transform(ikBoneCenter)
								followBone.fMovedMatrix:Transform(followBoneTip)
								g:DrawLine(ikBoneCenter.x, ikBoneCenter.y, followBoneTip.x, followBoneTip.y)
							end
						end
					end
					g:SetPenWidth(4)
					g:SetColor(self.colorIkBones)
					for i=1, #self.ikBonesList.id[b] do
						local boneId = self.ikBonesList.id[b][i]
						local followBone = skel:Bone(boneId)
						if followBone then
							if not self.ignoreBonesList[boneId + 1] then
								local ikBoneCenter = LM.Vector2:new_local()
								local followBoneTip = LM.Vector2:new_local()
								ikBoneCenter:Set(followBone.fLength / 1.5, 0)
								followBoneTip:Set(followBone.fLength / 3, 0)
								followBone.fMovedMatrix:Transform(ikBoneCenter)
								followBone.fMovedMatrix:Transform(followBoneTip)
								g:DrawLine(ikBoneCenter.x, ikBoneCenter.y, followBoneTip.x, followBoneTip.y)
							end
						end
					end
					if self.dragging then
						g:SetColor(self.colorHighlightBone)
						g:SetPenWidth(3)
						local markersSize = (0.015) / currentScale / height
						local marker1VecCam = self.ikBonesDataList.endBoneTipPos[b]
						g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
						g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
					elseif self.showCross then
						if MR_TweenMachine and self.ikBonesDataList.endBoneTipPos[b] then
							g:SetColor(self.colorHighlightBone)
							g:SetPenWidth(3)
							local markersSize = (0.015) / currentScale / height
							local marker1VecCam = self.ikBonesDataList.endBoneTipPos[b]
							g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
							g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
						end
					end
					g:SetPenWidth(1)
				end
			end
		end	
	end
	
	if self.mousePickedID > -1 and not (self.dragging or moho:IsPlaying()) and not self.showQuickMenu then
		local bone = skel:Bone(self.mousePickedID)
		if bone ~= nil then
			local isPin = bone:IsZeroLength()
			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength - bone.fLength * self.handlesDist, 0)
				bone.fMovedMatrix:Transform(v)

				if self.alignHandlesAlongBone then
					v:Set(bone.fLength - bone.fLength, 0)
					bone.fMovedMatrix:Transform(v)
				
					boneCenterPos:Set(bone.fLength - bone.fLength / 2, 0)
					bone.fMovedMatrix:Transform(boneCenterPos)
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					offset:Set(v.x, v.y)
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					
					offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					boneHandlePos:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					layerMatrixNoCam:Transform(boneHandlePos)
					
					local globalBoneCenterPos = LM.Vector2:new_local()
					globalBoneCenterPos:Set(boneCenterPos)
					layerMatrixNoCam:Transform(globalBoneCenterPos)
					
					if MR_Utilities:GetDistance(globalBoneCenterPos, boneHandlePos) * currentScale * height < 0.065 then
						alignHandlesAdaptation = true
					end
					
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				else
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					center:Set(0, 0)
					bone.fMovedMatrix:Transform(center)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				end
		
				v:Set(bone.fLength - bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)

				if selBones < 1 and self.highlightBones then
					center:Set(0, 0)
					tip:Set(bone.fLength, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					g:SetPenWidth(self.highlightWidth)
					g:SetColor(self.colorHighlightBone)
					g:DrawLine(center.x, center.y, tip.x, tip.y)
					g:SetPenWidth(1)
				end
				
				if additionMarker1 then
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x + (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end	
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, angle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					end
				end
				if self.drawMode == 2 then
					if isPin then
						g:SetColor(self.colorScaleFillHL)
					else
						g:SetColor(self.colorScaleFillHL)
					end	
					markerR = self.markerR + hlDelta
				else
					if isPin then
						g:SetColor(self.colorScaleFill)
					else
						g:SetColor(self.colorScaleFill)
					end	
					markerR = self.markerR
				end
				
				if bone.fLength == 0 and self.keepHandles then
					markerR = markerR * 3
				end
				if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
					g:FillCirclePixelRadius(v, markerR)
					g:SetColor(self.colorScaleStroke)
					g:FrameCirclePixelRadius(v, markerR)
				end
				
				markerR = self.markerR
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength - (bone.fLength * (self.handlesDist / handlesZoomAdaptationVal)), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end	
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					if self.drawMode == 4 then
						g:SetColor(self.colorManipulateFillHL)
						markerR = self.markerR + hlDelta
					else
						g:SetColor(self.colorManipulateFill)
						markerR = self.markerR
					end
					g:FillCirclePixelRadius(v, markerR)
					g:SetColor(self.colorManipulateStroke)
					g:FrameCirclePixelRadius(v, markerR)
					markerR = self.markerR
				end	
				
				v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x - (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height)* 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end

				if self.drawMode == 0 or self.drawMode == 5 then
					g:SetColor(self.colorTranslateFillHL)
					markerR = self.markerR + hlDelta
				else
					g:SetColor(self.colorTranslateFill)
					markerR = self.markerR
				end
				
				g:FillCirclePixelRadius(v, markerR)
				g:SetColor(self.colorTranslateStroke)
				g:FrameCirclePixelRadius(v, markerR)
				markerR = self.markerR
				
				if not isPin then
					if additionMarker1 then
						if self.alignHandlesAlongBone then
							offset:Set(v.x  + ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
						else	
							v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
							bone.fMovedMatrix:Transform(v)
							offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
						end
						offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
						newAngle = offsetAngle + (angle - offsetAngle)
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
						
						if self.drawMode == 3 then
							g:SetColor(self.colorMoveJointFillHL)
							markerR = self.markerR + hlDelta
						else
							g:SetColor(self.colorMoveJointFill)
							markerR = self.markerR
						end
						g:FillCirclePixelRadius(v, markerR)
						g:SetColor(self.colorMoveJointStroke)
						g:FrameCirclePixelRadius(v, markerR)
						markerR = self.markerR
					end	
				end
			end
		end
	end
	if selBones == 1 then
		local bone = skel:Bone(skel:SelectedBoneID())
		if bone ~= nil then
			if (bone.fSelected and self.showPath and bone.fParent < 0) then
				-- draw path
				local channelPos = bone.fAnimPos
				local startFrame = channelPos:GetKeyWhen(0)
				local channelDuration = channelPos:Duration()
				local endFrame = channelDuration
				local totalTimingOffset = moho.layer:TotalTimingOffset()

				if (startFrame - totalTimingOffset < 0) then
					startFrame = totalTimingOffset
				end
				channelPos:GetKeyInterp(endFrame, interp)
				if (interp:IsAdditiveCycle()) then
					endFrame = moho.document:EndFrame() + totalTimingOffset
				end

				if (endFrame > startFrame) then
					local vec = LM.Vector2:new_local()
					local oldVec = LM.Vector2:new_local()
					if self.range then
						startFrame = LM.Clamp(moho.layerFrame - self.rangeFrames, 1, channelDuration)
						endFrame = LM.Clamp(moho.layerFrame + self.rangeFrames, 1, channelDuration)
					end
					g:SetColor(102, 152, 203)
					for frame = startFrame, endFrame do
						vec = channelPos:GetValue(frame)
						if (frame > startFrame) then
							g:DrawLine(oldVec.x, oldVec.y, vec.x, vec.y)
						end
						if (channelPos:HasKey(frame)) then
							g:DrawFatMarker(vec.x, vec.y, 5)
						else
							g:DrawMarker(vec.x, vec.y)
						end
						oldVec:Set(vec)
					end
				end
			end
		end	
	end
	
	g:Pop()

	if self.showQuickMenu then
		self:DrawQuickMenu_1(moho, g)
	elseif self.showQuickMenu2 then
		self:DrawQuickMenu_2(moho, g)
	elseif self.showQuickMenu3 then
		self:DrawQuickMenu_3(moho, g)
	end
	if self.showQuickMenu and self.showQuickMenu4 and self.bonesDataActive then
		self:DrawQuickMenu_4(moho, g)
	end
end

-- **************************************************
-- Tool Panel Layout
-- **************************************************

MR_PoseTool.TOGGLE_PANEL = MOHO.MSG_BASE
MR_PoseTool.TWOS_MODE = MOHO.MSG_BASE + 1
MR_PoseTool.KEEP_SELECTION = MOHO.MSG_BASE + 2
MR_PoseTool.MULTI_TRANSFORM = MOHO.MSG_BASE + 3
MR_PoseTool.LOCK_HANDLES = MOHO.MSG_BASE + 4
MR_PoseTool.BAKE_ADJACENT_FRAMES = MOHO.MSG_BASE + 5
MR_PoseTool.INTERVAL_1 = MOHO.MSG_BASE + 6
MR_PoseTool.INTERVAL_2 = MOHO.MSG_BASE + 7
MR_PoseTool.INTERVAL_3 = MOHO.MSG_BASE + 8
MR_PoseTool.INTERVAL_4 = MOHO.MSG_BASE + 9
MR_PoseTool.INTERVAL_5 = MOHO.MSG_BASE + 10
MR_PoseTool.INTERVAL_6 = MOHO.MSG_BASE + 11
MR_PoseTool.SHOW_PATH = MOHO.MSG_BASE + 12
MR_PoseTool.RANGE = MOHO.MSG_BASE + 13
MR_PoseTool.RANGE_FRAMES = MOHO.MSG_BASE + 14
MR_PoseTool.FLIP_H = MOHO.MSG_BASE + 15
MR_PoseTool.FLIP_V = MOHO.MSG_BASE + 16
MR_PoseTool.RESET_A = MOHO.MSG_BASE + 17
MR_PoseTool.RESET_T = MOHO.MSG_BASE + 18
MR_PoseTool.RESET_S = MOHO.MSG_BASE + 19
MR_PoseTool.CHANGE_R = MOHO.MSG_BASE + 20
MR_PoseTool.CHANGE_T_X = MOHO.MSG_BASE + 21
MR_PoseTool.CHANGE_T_Y = MOHO.MSG_BASE + 22
MR_PoseTool.CHANGE_S = MOHO.MSG_BASE + 23
MR_PoseTool.INFO = MOHO.MSG_BASE + 24
MR_PoseTool.COPY_LINK = MOHO.MSG_BASE + 25
MR_PoseTool.SHOW_MORE_INFO = MOHO.MSG_BASE + 26

function MR_PoseTool:DoLayout(moho, layout)
	if self.scriptValidated == nil then
		self:ValidateScriptFiles(moho)
	end
	if self.scriptValidated ~= true then
		self.alertText = LM.GUI.DynamicText('Some script files are missing. Please download the script using the \"Download for Install Script\" button and install all script files.')
		layout:AddChild(self.alertText, LM.GUI.ALIGN_LEFT, 0)
		
		self.copyLinkButton = LM.GUI.ShortButton(self:Localize('Copy link to clipboard'), self.COPY_LINK)
		layout:AddChild(self.copyLinkButton, LM.GUI.ALIGN_FILL, 0)
		
		self.showMoreInfoButton = LM.GUI.ShortButton(self:Localize('Show more info'), self.SHOW_MORE_INFO)
		layout:AddChild(self.showMoreInfoButton, LM.GUI.ALIGN_FILL, 0)
		return
	end
	
	self.dlog = MR_PoseToolSettingsDialog:new()
    self.settingsPopup = LM.GUI.PopupDialog(self:Localize('Settings'), false, 0)
    self.settingsPopup:SetDialog(self.dlog)
    layout:AddChild(self.settingsPopup, LM.GUI.ALIGN_LEFT, 0)
	
	self.togglePanelCheckbox = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_toggle_panel', self:Localize('Toggle panel'), true, self.TOGGLE_PANEL, false)
	layout:AddChild(self.togglePanelCheckbox, LM.GUI.ALIGN_FILL, 0)
	
	if not self.panelSizeShort then
		self.resetText = LM.GUI.DynamicText(self:Localize('Reset:'))
		layout:AddChild(self.resetText, LM.GUI.ALIGN_LEFT, 0)
		
		self.resetAButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_rotate', self:Localize('A'), false, self.RESET_A, false)
		self.resetAButton:SetToolTip(self:Localize('Reset angle'))
		layout:AddChild(self.resetAButton, LM.GUI.ALIGN_FILL, 0)
		
		self.resetPButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_translate', self:Localize('T'), false, self.RESET_T, false)
		self.resetPButton:SetToolTip(self:Localize('Reset translation'))
		layout:AddChild(self.resetPButton, LM.GUI.ALIGN_FILL, 0)
		
		self.resetSButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_scale', self:Localize('S'), false, self.RESET_S, false)
		self.resetSButton:SetToolTip(self:Localize('Reset scale'))
		layout:AddChild(self.resetSButton, LM.GUI.ALIGN_FILL, 0)
	else
		self.resetAButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_rotate', self:Localize('A'), false, self.RESET_A, false)
		self.resetAButton:SetToolTip(self:Localize('Reset angle'))
		layout:AddChild(self.resetAButton, LM.GUI.ALIGN_FILL, 0)
		
		self.angleInput = LM.GUI.TextControl(0, "000.000", self.CHANGE_R, LM.GUI.FIELD_FLOAT, '')
		self.angleInput:SetWheelInc(0.01)
		layout:AddChild(self.angleInput)
		
		self.resetPButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_translate', self:Localize('T'), false, self.RESET_T, false)
		self.resetPButton:SetToolTip(self:Localize('Reset translation'))
		layout:AddChild(self.resetPButton, LM.GUI.ALIGN_FILL, 0)

		self.translationInputX = LM.GUI.TextControl(0, "00.000", self.CHANGE_T_X, LM.GUI.FIELD_FLOAT, self:Localize('X'))
		self.translationInputX:SetWheelInc(0.1)
		layout:AddChild(self.translationInputX)
		
		self.translationInputY = LM.GUI.TextControl(0, "00.000", self.CHANGE_T_Y, LM.GUI.FIELD_FLOAT, self:Localize('Y'))
		self.translationInputY:SetWheelInc(0.1)
		layout:AddChild(self.translationInputY)
		
		self.resetSButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_scale', self:Localize('S'), false, self.RESET_S, false)
		self.resetSButton:SetToolTip(self:Localize('Reset scale'))
		layout:AddChild(self.resetSButton, LM.GUI.ALIGN_FILL, 0)
		
		self.scaleInput = LM.GUI.TextControl(0, "00.000", self.CHANGE_S, LM.GUI.FIELD_FLOAT, '')
		self.scaleInput:SetWheelInc(0.1)
		layout:AddChild(self.scaleInput)
	end
		
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.twosModeCheckbox = LM.GUI.CheckBox(self:Localize('Twos mode'), self.TWOS_MODE)
	layout:AddChild(self.twosModeCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.keepSelectionCheckbox = LM.GUI.CheckBox(self:Localize('Keep selection'), self.KEEP_SELECTION)
	layout:AddChild(self.keepSelectionCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.multiTransformCheckbox = LM.GUI.CheckBox(self:Localize('Multi transform'), self.MULTI_TRANSFORM)
	layout:AddChild(self.multiTransformCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.lockHandlesCheckbox = LM.GUI.CheckBox(self:Localize('Lock handles'), self.LOCK_HANDLES)
	layout:AddChild(self.lockHandlesCheckbox, LM.GUI.ALIGN_LEFT, 0)

	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.bakeAdjacentFramesCheckbox = LM.GUI.CheckBox(self:Localize('Bake Adjacent Frames'), self.BAKE_ADJACENT_FRAMES)
	layout:AddChild(self.bakeAdjacentFramesCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	layout:AddChild(LM.GUI.StaticText(self:Localize("Interval")))

	self.intervalMenu = LM.GUI.Menu(MOHO.Localize("Interval=Interval"))
	self.intervalMenu:AddItem(MOHO.Localize("1=1"), 0, self.INTERVAL_1)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("2=2"), 0, self.INTERVAL_2)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("3=3"), 0, self.INTERVAL_3)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("4=4"), 0, self.INTERVAL_4)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("5=5"), 0, self.INTERVAL_5)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("6=6"), 0, self.INTERVAL_6)

	self.intervalPopup = LM.GUI.PopupMenu(50, true)
	self.intervalPopup:SetMenu(self.intervalMenu)
	layout:AddChild(self.intervalPopup)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.showPathCheckbox = LM.GUI.CheckBox(self:Localize('Show path'), self.SHOW_PATH)
    layout:AddChild(self.showPathCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.rangeCheckbox = LM.GUI.CheckBox(self:Localize('Range'), self.RANGE)
    layout:AddChild(self.rangeCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.rangeFramesInput = LM.GUI.TextControl(0, '1000', self.RANGE_FRAMES, LM.GUI.FIELD_INT, self:Localize('Range frames:'))
    layout:AddChild(self.rangeFramesInput, LM.GUI.ALIGN_LEFT, 0)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.endFlipButton = LM.GUI.ImageButton("ScriptResources/flip_bone_h", self:Localize('End flip'), false, self.FLIP_H, true)
	layout:AddChild(self.endFlipButton )
	
	self.sideFlipButton = LM.GUI.ImageButton("ScriptResources/flip_bone_v", self:Localize('Side flip'), false, self.FLIP_V, true)
	layout:AddChild(self.sideFlipButton)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.infoButton = LM.GUI.ImageButton('ScriptResources/mr_pose_tool/mr_info', self:Localize('A'), false, self.INFO, false)
	self.infoButton:SetToolTip(self:Localize('Info'))
	layout:AddChild(self.infoButton, LM.GUI.ALIGN_FILL, 0)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	layout:AddChild(LM.GUI.StaticText('v'..self:Version()))
end

function MR_PoseTool:UpdateWidgets(moho)
	if not self.colorsGenerated then
		self:GenerateColors(moho)
	end

	if self.scriptValidated ~= true then
		return
	end

	if self.mainCursor == nil then
		self.mainCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/Tool/mr_pose_tool_cursor', 1, 1)
	end	
	if self.mjCursor == nil then
		self.mjCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/ScriptResources/mr_pose_tool/mr_mj_cursor', 1, 1)
	end	
	if self.mbCursor == nil then
		self.mbCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/ScriptResources/mr_pose_tool/mr_mb_cursor', 1, 1)
	end	
	
	if self.sblCursor == nil then
		self.sblCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/ScriptResources/mr_pose_tool/mr_select_bone_layer', 1, 1)
	end
	
	if not self.settingsPopup then
		return
	end
	local skel = moho:Skeleton()

	local layer = moho.layer
	if self.skeletonLayersNavigation then
		if self.ignoreUpdateWidgets then
			return
		end
	end
	
	self.togglePanelCheckbox:SetValue(self.panelSizeShort)
	
	if skel ~= nil and frame ~= 0 then
		self:LoadBonesData(layer)
		self:ValidateFollowList(moho)
		self:ValidateIkList(moho)
		self:ValidateLockList(moho)
		
		if #self.followBonesList.id > 0 or #self.ikBonesList.id > 0 or #self.lockPosList > 0 or #self.lockAngleList > 0 then
			local scriptInfo = layer:ScriptData()
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			if scriptInfo:HasKey(bonesDataActiveKey) then
				self.bonesDataActive = scriptInfo:GetBool(bonesDataActiveKey)
			else
				self.bonesDataActive = true
			end
			
			local bonesDataActiveFKey = self.scriptDataName..'bonesDataActiveF '
			if scriptInfo:HasKey(bonesDataActiveFKey) then
				self.bonesDataActiveF = scriptInfo:GetBool(bonesDataActiveFKey)
			else
				self.bonesDataActiveF = true
			end
			
			local bonesDataActiveIKKey = self.scriptDataName..'bonesDataActiveIK '
			if scriptInfo:HasKey(bonesDataActiveIKKey) then
				self.bonesDataActiveIK = scriptInfo:GetBool(bonesDataActiveIKKey)
			else
				self.bonesDataActiveIK = true
			end
			
			local bonesDataActiveAKey = self.scriptDataName..'bonesDataActiveA '
			if scriptInfo:HasKey(bonesDataActiveAKey) then
				self.bonesDataActiveA = scriptInfo:GetBool(bonesDataActiveAKey)
			else
				self.bonesDataActiveA = true
			end
			
			local bonesDataActivePKey = self.scriptDataName..'bonesDataActiveP '
			if scriptInfo:HasKey(bonesDataActivePKey) then
				self.bonesDataActiveP = scriptInfo:GetBool(bonesDataActivePKey)
			else
				self.bonesDataActiveP = true
			end
			
			local singleFollowBonesModeKey = self.scriptDataName..'singleFollowBonesMode '
			if scriptInfo:HasKey(singleFollowBonesModeKey) then
				self.singleFollowBonesMode = scriptInfo:GetBool(singleFollowBonesModeKey)
			else
				self.singleFollowBonesMode = true
			end
			
			local scaleFollowBonesKey = self.scriptDataName..'boneStretching '
			if scriptInfo:HasKey(scaleFollowBonesKey) then
				self.boneStretching = scriptInfo:GetBool(scaleFollowBonesKey)
			else
				self.boneStretching = true
			end
			if #self.followBonesList.id > 0 or #self.ikBonesList.id > 0 then
				self:SetBoneStretching(moho, true)
			end
		else
			self.bonesDataActive = true
			local scriptInfo = layer:ScriptData()
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			scriptInfo:Set(bonesDataActiveKey, true)
			
			local singleFollowBonesModeKey = self.scriptDataName..'singleFollowBonesMode '
			scriptInfo:Set(singleFollowBonesModeKey, false)
			self.singleFollowBonesMode = false
			self.boneStretchingIconStatus = false
		end
	end
	
	local frame = moho.frame
	
	if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) and self.twosMode then
		moho.view:SetCursor(MOHO.disabledCursor)
	else
		moho.view:SetCursor(self.mainCursor)
	end

	self.twosModeCheckbox:SetValue(self.twosMode)
	self.keepSelectionCheckbox:SetValue(self.keepSelection)
	self.multiTransformCheckbox:SetValue(self.multiTransform)
	self.multiTransformCheckbox:Enable(self.keepSelection)
	self.lockHandlesCheckbox:SetValue(self.lockHandles)
	self.bakeAdjacentFramesCheckbox:SetValue(self.bakeAdjacentFrames)
	
	self.bakeAdjacentFramesCheckbox:Enable(not MOHO.MohoGlobals.EditMultipleKeys)
	
	if self.panelSizeShort then
		self.togglePanelCheckbox:SetToolTip(self:Localize('Show compact panel'))
		if skel and self.angleInput ~= nil then
			local selID = skel:SelectedBoneID()
			local selBones = moho:CountSelectedBones(true)
			
			if selBones > 0 then
				local selCount = 0
				local angle = 0
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						selCount = selCount + 1
						angle = angle + bone.fAngle
					end
				end
				self.angleInput:SetValue(math.deg(angle) / selCount)
			else
				self.angleInput:SetValue("")
			end	
			if (selID >= 0) then
				local bone = skel:Bone(selID)
				self.translationInputX:SetValue(bone.fPos.x)
				self.translationInputY:SetValue(bone.fPos.y)
			else
				self.translationInputX:SetValue("")
				self.translationInputY:SetValue("")
			end
			
			if selBones > 0 then
				local selCount = 0
				local scale = 0
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						selCount = selCount + 1
						scale = scale + bone.fScale
					end
				end
				self.scaleInput:SetValue(scale / selCount)
			else
				self.scaleInput:SetValue("")
			end
		else
			self.angleInput:SetValue("")
			self.translationInputX:SetValue("")
			self.translationInputY:SetValue("")
			self.scaleInput:SetValue("")
		end
	else
		self.togglePanelCheckbox:SetToolTip(self:Localize('Show full panel'))
	end
	
	if self.interval < 1 or self.interval > 6 or self.interval == nil then
		self.interval = 1
	end
	
	self.intervalMenu:SetChecked(self.INTERVAL_1, false)
	self.intervalMenu:SetChecked(self.INTERVAL_2, false)
	self.intervalMenu:SetChecked(self.INTERVAL_3, false)
	self.intervalMenu:SetChecked(self.INTERVAL_4, false)
	self.intervalMenu:SetChecked(self.INTERVAL_5, false)
	self.intervalMenu:SetChecked(self.INTERVAL_6, false)
	if (self.interval == 1) then
		self.intervalMenu:SetChecked(self.INTERVAL_1, true)
	elseif (self.interval == 2) then
		self.intervalMenu:SetChecked(self.INTERVAL_2, true)
	elseif (self.interval == 3) then
		self.intervalMenu:SetChecked(self.INTERVAL_3, true)
	elseif (self.interval == 4) then
		self.intervalMenu:SetChecked(self.INTERVAL_4, true)
	elseif (self.interval == 5) then
		self.intervalMenu:SetChecked(self.INTERVAL_5, true)
	elseif (self.interval == 6) then
		self.intervalMenu:SetChecked(self.INTERVAL_6, true)
	end
	self.intervalPopup:Enable(self.bakeAdjacentFrames)
	self.intervalPopup:Redraw()
	self.showPathCheckbox:SetValue(self.showPath)
	self.rangeCheckbox:SetValue(self.range)
	self.rangeFramesInput:SetValue(self.rangeFrames)
	self.rangeCheckbox:Enable(self.showPath)
	self.rangeFramesInput:Enable(self.range and self.showPath)
end

function MR_PoseTool:HandleMessage(moho, view, msg)
	if msg == self.TOGGLE_PANEL then
		self.panelSizeShort = self.togglePanelCheckbox:Value()
		local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
		if not drawingToolsNonZero then
			MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
		end
		local frame = moho.frame
		local curLayer = moho.layer
		if moho.layer:LayerType() ~= MOHO.LT_BONE and moho.layer:LayerType() ~= MOHO.LT_VECTOR then
			local count = 0
			repeat
				local layer = moho.document:LayerByAbsoluteID(count)
				if layer then
					count = count + 1
					if layer:LayerType() == MOHO.LT_BONE or layer:LayerType() == MOHO.LT_BONE then
						moho:SetSelLayer(layer)
						break
					end	
				end
			until not layer	
		end		
		
		if frame == 0 then
			moho:SetCurFrame(1)
			moho:SetSelLayer(curLayer)
			moho:SetCurFrame(0)
		elseif frame ~= 0 then
			moho:SetCurFrame(0)
			moho:SetSelLayer(curLayer)
			moho:SetCurFrame(frame)
		end

		if not drawingToolsNonZero then
			MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
		end
	elseif msg == self.TWOS_MODE then
        self.twosMode = self.twosModeCheckbox:Value()
	elseif msg == self.KEEP_SELECTION then
        self.keepSelection = self.keepSelectionCheckbox:Value()
		self.multiTransformCheckbox:Enable(self.keepSelection)
	elseif msg == self.MULTI_TRANSFORM then
        self.multiTransform = self.multiTransformCheckbox:Value()
	elseif msg == self.LOCK_HANDLES then
        self.lockHandles = self.lockHandlesCheckbox:Value()
	elseif msg == self.BAKE_ADJACENT_FRAMES then
		if MOHO.MohoGlobals.EditMultipleKeys then
			self.bakeAdjacentFramesCheckbox:SetValue(self.bakeAdjacentFrames)
			self:UpdateWidgets(moho)
		else
			self.bakeAdjacentFrames = self.bakeAdjacentFramesCheckbox:Value()
			self.intervalPopup:Enable(self.bakeAdjacentFrames)
		end
	elseif (msg >= self.INTERVAL_1 and msg <= self.INTERVAL_6) then
		local int = 1
		if (msg == self.INTERVAL_1) then
			int = 1
		elseif (msg == self.INTERVAL_2) then
			int = 2
		elseif (msg == self.INTERVAL_3) then
			int = 3
		elseif (msg == self.INTERVAL_4) then
			int = 4
		elseif (msg == self.INTERVAL_5) then
			int = 5
		elseif (msg == self.INTERVAL_6) then
			int = 6
		end	
		self.interval = int
		self:UpdateWidgets(moho)
	elseif msg == self.SHOW_PATH then
        self.showPath = self.showPathCheckbox:Value()
		self.rangeCheckbox:Enable(self.showPath)
		self.rangeFramesInput:Enable(self.range and self.showPath)
	elseif msg == self.RANGE then
        self.range = self.rangeCheckbox:Value()	
		self.rangeCheckbox:Enable(self.showPath)
		self.rangeFramesInput:Enable(self.range and self.showPath)
	elseif msg == self.RANGE_FRAMES then
        self.rangeFrames = LM.Clamp(self.rangeFramesInput:Value(), 1, 1000)	
		self.rangeFramesInput:SetValue(self.rangeFrames)
	elseif (msg == self.FLIP_H) then
		self:FlipBones(moho, true)
	elseif (msg == self.FLIP_V) then
		self:FlipBones(moho, false)
	elseif (msg == self.RESET_A) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
		
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAnimAngle:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE)
				self:UpdateWidgets(moho)
			end
			
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		end
	elseif (msg == self.RESET_T) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_T)
				self:UpdateWidgets(moho)
			end
			
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		end
	elseif (msg == self.RESET_S) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimScale:SetValue(moho.layerFrame, bone.fAnimScale:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_S)
				self:UpdateWidgets(moho)
			end
			
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		end
	elseif (msg == self.CHANGE_R) then	
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAngle = math.rad(self.angleInput:FloatValue())
						bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle)
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE)
			else
				self.angleInput:SetValue('')
			end
			
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		else
			self.angleInput:SetValue('')
		end
	elseif (msg == self.CHANGE_T_X) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fPos.x = self.translationInputX:FloatValue()
						bone.fAnimPos:SetValue(moho.layerFrame, bone.fPos)
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_T)
			else
				self.translationInputX:SetValue('')
			end
				
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		else
			self.translationInputX:SetValue('')
		end
	elseif (msg == self.CHANGE_T_Y) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fPos.y = self.translationInputY:FloatValue()
						bone.fAnimPos:SetValue(moho.layerFrame, bone.fPos)
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_T)
				
			else
				self.translationInputY:SetValue('')
			end
			
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		else
			self.translationInputY:SetValue('')
		end
	elseif (msg == self.CHANGE_S) then
		local skel = moho:Skeleton()
		if skel then
			if MOHO.MohoGlobals.EditMultipleKeys then
				self:PrepareToEditMultipleKeys(moho)
			end
			
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fScale = self.scaleInput:FloatValue()
						bone.fAnimScale:SetValue(moho.layerFrame, bone.fScale)
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_S)
			else
				self.scaleInput:SetValue('')
			end

			if MOHO.MohoGlobals.EditMultipleKeys then
				self:EditMultipleKeys(moho)
				moho.layer:UpdateCurFrame()
				moho:UpdateSelectedChannels()
			end
		else
			self.scaleInput:SetValue('')
		end
	elseif (msg == self.INFO) then
		local poseToolInfoDlog = MR_PoseToolInfoDialog:new(moho)
		poseToolInfoDlog = MR_PoseToolInfoDialog:new(moho) 
		if poseToolInfoDlog then
			poseToolInfoDlog:DoModal()
		end
	elseif (msg == self.COPY_LINK) then
		local linkText = self:Localize('Script link')
		moho:CopyText(linkText)
	elseif (msg == self.SHOW_MORE_INFO) then
		self:ValidateScriptFiles(moho)
	end	
end

function MR_PoseTool:CheckBone(moho, id)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return false
	end
	if id < 0 or not id then
		return false
	end
	local secondBone = skel:Bone(id)
	if secondBone then
		if secondBone.fParent > -1 and not secondBone:IsZeroLength() and not secondBone.fFixedAngle then
			local firstBoneID = secondBone.fParent
			local firstBone = skel:Bone(firstBoneID)
			local firstBoneChilds = skel:CountBoneChildren(firstBoneID, true)
			local secondBonePos = LM.Vector2:new_local()
			secondBonePos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
			if firstBone.fIgnoredByIK == false and secondBone.fIgnoredByIK == false and firstBoneChilds == 1 and MR_Utilities:Round(secondBone.fPos.y) == 0 
			and not MR_Utilities:IsEqual(secondBonePos.x, 0, 0.0001) and not firstBone:IsZeroLength() and not firstBone.fFixedAngle then
				return true
			end
		end
	end	
	return false
end

function MR_PoseTool:TestMousePoint(moho, mouseEvent, id)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return 1
	end

	local markerR = self.markerR
	if self.additionHandles then
		markerR = self.markerR2
	end
	
	local v = LM.Vector2:new_local()
	local pt = LM.Point:new_local()
	local m = LM.Matrix:new_local()
	local center = LM.Vector2:new_local()
	local tip = LM.Vector2:new_local()
	local offset = LM.Vector2:new_local()
	local boneCenterPos = LM.Vector2:new_local()
	local boneHandlePos = LM.Vector2:new_local()
	local localV = LM.Vector2:new_local()
	local angle = 0
	local newAngle = 0
	local offsetAngle = 0
	local alignHandlesAdaptation = false
	local handlesZoomAdaptationVal = 1
	
	moho.layer:GetFullTransform(moho.frame, m, moho.document)
	local g = mouseEvent.view:Graphics()
	g:Push()
	g:ApplyMatrix(m)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local markerMultiplier = 0.002

	local additionMarker1 = self.additionHandles
	local currentScale = g:CurrentScale(false)
	g:Pop()
	
	self.keepHandles = mouseEvent.ctrlKey

	local handlesDistance = self.handlesDistance
	if self.alignHandlesAlongBone then
		handlesDistance = 1
	end

	if self.mousePickedID > -1 then
		local bone = skel:Bone(self.mousePickedID)
		if bone ~= nil then
			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength * self.handlesDist, 0)
				bone.fMovedMatrix:Transform(v)
				
				if self.alignHandlesAlongBone then
					v:Set(bone.fLength - bone.fLength, 0)
					bone.fMovedMatrix:Transform(v)
				
					boneCenterPos:Set(bone.fLength - bone.fLength / 2, 0)
					bone.fMovedMatrix:Transform(boneCenterPos)
					
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					offset:Set(v.x, v.y)
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					
					offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					boneHandlePos:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					
					layerMatrixNoCam:Transform(boneHandlePos)
					
					local globalBoneCenterPos = LM.Vector2:new_local()
					globalBoneCenterPos:Set(boneCenterPos)
					layerMatrixNoCam:Transform(globalBoneCenterPos)
					
					if MR_Utilities:GetDistance(globalBoneCenterPos, boneHandlePos) * currentScale * height < 0.065 then
						alignHandlesAdaptation = true
					end
					
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				else
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					center:Set(0, 0)
					bone.fMovedMatrix:Transform(center)
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				end
				
				v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x - (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end
				
				localV:Set(v)
				m:Transform(v)
				
				mouseEvent.view:Graphics():WorldToScreen(v, pt)
				if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
					return 0
				end
				
				if additionMarker1 then	
					if self.alignHandlesAlongBone then
						v:Set(localV)
						offset:Set(v.x + ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
				
					local testPos = LM.Vector2:new_local()
					testPos:Set(v)
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					layerMatrixNoCam:Transform(testPos)
					
					m:Transform(v)
					mouseEvent.view:Graphics():WorldToScreen(v, pt)
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
						return 3
					end
				end
			end	

			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength - bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x + (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)

					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end
				
				localV:Set(v)
				
				m:Transform(v)
				mouseEvent.view:Graphics():WorldToScreen(v, pt)
				if bone:IsZeroLength() and mouseEvent.ctrlKey then
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR * 3 and math.abs(pt.y - mouseEvent.pt.y) < markerR * 3) then
						return 2
					end
				else
					if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
						if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
							return 2
						end
					end	
				end	
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						v:Set(localV)
						offset:Set(v.x  - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength - (bone.fLength * (self.handlesDist / handlesZoomAdaptationVal)), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					m:Transform(v)

					mouseEvent.view:Graphics():WorldToScreen(v, pt)
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
						return 4
					end
				end
			end
		end
	end

	if id then
		if id > -1 and self.showPath then
			local bone = skel:Bone(id)
			if bone ~= nil then
				local channelPos = bone.fAnimPos
				local translationWhen = -20000
				local g = mouseEvent.view:Graphics()
				local m = LM.Matrix:new_local()
				local vec = LM.Vector2:new_local()
				local pt = LM.Point:new_local()
				local totalTimingOffset = moho.layer:TotalTimingOffset()
				moho.layer:GetFullTransform(moho.frame, m, moho.document)
				-- First see if any keyframes were picked
				for i = 0, bone.fAnimPos:CountKeys() - 1 do
					local frame = bone.fAnimPos:GetKeyWhen(i)
					if frame > 0 then
						vec = bone.fAnimPos:GetValue(frame)
						m:Transform(vec)
						g:WorldToScreen(vec, pt)
						if (math.abs(pt.x - mouseEvent.pt.x) < self.TOLERANCE and math.abs(pt.y - mouseEvent.pt.y) < self.TOLERANCE) then
							translationWhen = frame
							self.trPathBone = bone
							break
						end
					end	
				end
				-- If no keyframes were picked, try picking a random point along the curve.
				if (translationWhen <= -10000) then
					local startFrame = channelPos:GetKeyWhen(0)
					local channelDuration = channelPos:Duration()
					local endFrame = channelDuration
					if self.range then
						startFrame = LM.Clamp(moho.layerFrame - self.rangeFrames, 1, channelDuration)
						endFrame = LM.Clamp(moho.layerFrame + self.rangeFrames, 1, channelDuration)
					end
					if (endFrame > startFrame) then
						local oldVec = LM.Vector2:new_local()
						g:Clear(0, 0, 0, 0)
						g:SetColor(255, 255, 255)
						g:BeginPicking(mouseEvent.pt, 4)
						for frame = startFrame, endFrame do
							vec = channelPos:GetValue(frame)
							m:Transform(vec)
							if (frame > startFrame) then
								g:DrawLine(oldVec.x, oldVec.y, vec.x, vec.y)
							end
							if (g:Pick()) then
								translationWhen = frame
								self.trPathBone = bone
								break
							end
							oldVec:Set(vec)
						end
					end
				end
				if (translationWhen > -10000) then
					self.translationFrame = translationWhen
					return 5
				end
			end	
		end
	end
	return 1
end

function MR_PoseTool:FlipBones(moho, horizontal)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return 1
	end
	
	if (moho:CountSelectedBones(true) < 1) then
		return
	end

	moho.document:PrepUndo(moho.layer, true)
	moho.document:SetDirty()
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fSelected) then
			if (horizontal) then
				bone.fFlipH:SetValue(moho.layerFrame, not bone.fFlipH.value)
			else
				bone.fFlipV:SetValue(moho.layerFrame, not bone.fFlipV.value)
			end
		end
	end
	moho.layer:UpdateCurFrame()
	if (horizontal) then
		moho:NewKeyframe(CHANNEL_BONE_FLIPH)
	else
		moho:NewKeyframe(CHANNEL_BONE_FLIPV)
	end
end

function MR_PoseTool:BakeFrames(moho, secondBone, firstBone, angle, pos, scale)
	if moho.layerFrame - self.interval > 0 then
		if firstBone then
			if angle and self.boneFAngleP then
				firstBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.boneFAngleP)
			end	
			if pos and self.boneFPosP then
				local channel = firstBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame - self.interval, self.boneFPosP.x)
					channelY:SetValue(moho.layerFrame - self.interval, self.boneFPosP.y)
				else
					firstBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.boneFPosP)
				end	
			end	
			if scale and self.boneFScaleP then
				firstBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.boneFScaleP)
			end	
		end
		if secondBone then
			if angle and self.boneSAngleP then
				secondBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.boneSAngleP)
			end
			if pos and self.boneSPosP then
				local channel = secondBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame - self.interval, self.boneSPosP.x)
					channelY:SetValue(moho.layerFrame - self.interval, self.boneSPosP.y)
				else
					secondBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.boneSPosP)
				end
			end	
			if scale and self.boneSScaleP then
				secondBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.boneSScaleP)
			end	
		end	
	end
	if moho.layerFrame + self.interval > 0 then
		if firstBone then
			if angle and self.boneFAngleN then
				firstBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.boneFAngleN)
			end	
			if pos and self.boneFPosN then
				local channel = firstBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame + self.interval, self.boneFPosN.x)
					channelY:SetValue(moho.layerFrame + self.interval, self.boneFPosN.y)
				else
					firstBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.boneFPosN)
				end
			end
			if scale and self.boneFScaleN then
				firstBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.boneFScaleN)
			end	
		end
		if secondBone then
			if angle and self.boneSAngleN then
				secondBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.boneSAngleN)
			end
			if pos and self.boneSPosN then
				local channel = secondBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame + self.interval, self.boneSPosN.x)
					channelY:SetValue(moho.layerFrame + self.interval, self.boneSPosN.y)
				else
					secondBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.boneSPosN)
				end	
			end	
			if scale and self.boneSScaleN then
				secondBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.boneSScaleN)
			end	
		end	
	end
end

function MR_PoseTool:CountBoneChildren(skel, boneID, ignoreControlledBones)
	local n = 0
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fParent == boneID) then
			n = n + 1
			if (ignoreControlledBones) then
				if self.mohoVersion >= 14 then
					if (bone.fAngleControlParent >= 0 or bone.fPosControlParent >= 0 or bone.fScaleControlParent >= 0 
					or (bone.fBoneDynamics.value and (bone.fAngleDynamics or bone.fPosDynamics or bone.fScaleDynamics)) or bone.fIgnoredByIK) then
						n = n - 1 -- ignore this bone, as it is not free to move by itself
					end
				else
					if (bone.fAngleControlParent >= 0 or bone.fPosControlParent >= 0 or bone.fScaleControlParent >= 0 or bone.fBoneDynamics.value or bone.fIgnoredByIK) then
						n = n - 1 -- ignore this bone, as it is not free to move by itself
					end
				end
			end
		end
	end
	return n
end

function MR_PoseTool:AddToFollowBonesChains(moho)
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end
	
	local selectedBonesId = {}
	local selectedBonesNames = {}
	local isValid = true
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self.bonesDataActiveF = true
	local bonesDataActiveFKey = self.scriptDataName..'bonesDataActiveF '
	scriptInfo:Set(bonesDataActiveFKey, self.bonesDataActiveF)
	
	self:LoadBonesData(moho.layer)
	
	self:ValidateFollowList(moho)
	self:ValidateIkList(moho)
	
	local selectedBonesList = {}
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			table.insert(selectedBonesList, i)
		end
	end
	
	local followBonesChainsList = {}
	local boneParentMap = {}
	local multipleChildrenMap = {}
	local isInGroup = {}
	local selectedBonesSet = {}

	for _, id in ipairs(selectedBonesList) do
		selectedBonesSet[id] = true
	end

	for _, id in ipairs(selectedBonesList) do
		local bone = skel:Bone(id)
		local count = 0
		
		for _, childId in ipairs(selectedBonesList) do
			local childBone = skel:Bone(childId)
			if childBone then
				if childBone.fParent == id then
					count = count + 1
				end
			end
		end
		
		if count > 1 then
			multipleChildrenMap[id] = true
		end
		
		boneParentMap[id] = bone.fParent
	end
		for n, id in ipairs(multipleChildrenMap) do
			local bone = skel:Bone(id)
		end
	local function collectAncestors(boneId, group)
		local parentId = boneParentMap[boneId]
		while parentId and parentId ~= -1 and selectedBonesSet[parentId] and not isInGroup[parentId] do
			if not multipleChildrenMap[parentId] then
				table.insert(group, 1, parentId) 
				isInGroup[parentId] = true
			end
			parentId = boneParentMap[parentId]
		end
	end

	local function addDescendants(boneId, group)
		for _, childId in ipairs(selectedBonesList) do
			if boneParentMap[childId] == boneId and not isInGroup[childId] then
				if not multipleChildrenMap[boneId] then
					table.insert(group, childId)
					isInGroup[childId] = true
					addDescendants(childId, group)
				end
			end
		end
	end

	for _, boneId in ipairs(selectedBonesList) do
		if not isInGroup[boneId] then
			local group = {}

			collectAncestors(boneId, group)

			if not isInGroup[boneId] then
				table.insert(group, boneId)
				isInGroup[boneId] = true

				addDescendants(boneId, group)
			end

			if #group > 0 then
				table.insert(followBonesChainsList, group)
			end
		end
	end
	
	local followBonesChainsNamesList = {}
	
	for i, a in ipairs(followBonesChainsList) do
		local followBonesNamesList = {}
		for n, id in ipairs(followBonesChainsList[i]) do
			local bone = skel:Bone(id)
			table.insert(followBonesNamesList, bone:Name())
		end
		table.insert(followBonesChainsNamesList, followBonesNamesList)
	end
	
	self:RemoveSelectedBonesFromFollowList(moho)
	self:RemoveSelectedBonesFromIkList(moho)

	for c, a in ipairs(followBonesChainsList) do
		local startBone = followBonesChainsList[c][1]
		local endBone = followBonesChainsList[c][#followBonesChainsList[c]]
		
		table.insert(self.followBonesList.id, followBonesChainsList[c])
		table.insert(self.followBonesList.names, followBonesChainsNamesList[c])
		table.insert(self.followBonesList.startBone, startBone)
		table.insert(self.followBonesList.endBone, endBone)
		table.insert(self.followBonesList.stretching, false)

		for _, id in ipairs(followBonesChainsList[c]) do
			local boneID = id
			local existInList = MR_Utilities:ValueExists(self.lockAngleList, boneID)
			if existInList then
				table.remove(self.lockAngleList, existInList)
				table.remove(self.lockAngleBoneNamesList, existInList)
			end
			existInList = MR_Utilities:ValueExists(self.lockPosList, boneID)
			if existInList then
				table.remove(self.lockPosList, existInList)
				table.remove(self.lockPosBoneNamesList, existInList)
			end
		end
	end
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AddToIKBonesChains(moho)
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end

	local selectedBonesId = {}
	local selectedBonesNames = {}
	local isValid = true
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self:LoadBonesData(moho.layer)
	self:ValidateIkList(moho)
	local selectedBonesList = {}
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			table.insert(selectedBonesList, i)
		end
	end

	local ikBonesChainsList = {}
	local boneParentMap = {}
	local multipleChildrenMap = {}
	local isInGroup = {}
	local selectedBonesSet = {}

	for _, id in ipairs(selectedBonesList) do
		selectedBonesSet[id] = true
	end

	for _, id in ipairs(selectedBonesList) do
		local bone = skel:Bone(id)
		local count = 0
		
		for _, childId in ipairs(selectedBonesList) do
			local childBone = skel:Bone(childId)
			if childBone then
				if childBone.fParent == id then
					count = count + 1
				end
			end
		end
		
		if count > 1 then
			multipleChildrenMap[id] = true
		end
		
		boneParentMap[id] = bone.fParent
	end
		for n, id in ipairs(multipleChildrenMap) do
			local bone = skel:Bone(id)
		end
	local function collectAncestors(boneId, group)
		local parentId = boneParentMap[boneId]
		while parentId and parentId ~= -1 and selectedBonesSet[parentId] and not isInGroup[parentId] do
			if not multipleChildrenMap[parentId] then
				table.insert(group, 1, parentId) 
				isInGroup[parentId] = true
			end
			parentId = boneParentMap[parentId]
		end
	end

	local function addDescendants(boneId, group)
		for _, childId in ipairs(selectedBonesList) do
			if boneParentMap[childId] == boneId and not isInGroup[childId] then
				if not multipleChildrenMap[boneId] then
					table.insert(group, childId)
					isInGroup[childId] = true
					addDescendants(childId, group)
				end
			end
		end
	end

	for _, boneId in ipairs(selectedBonesList) do
		if not isInGroup[boneId] then
			local group = {}

			collectAncestors(boneId, group)

			if not isInGroup[boneId] then
				table.insert(group, boneId)
				isInGroup[boneId] = true

				addDescendants(boneId, group)
			end

			if #group > 0 then
				table.insert(ikBonesChainsList, group)
			end
		end
	end
	
	local ikBonesChainsNamesList = {}
	
	for i, a in ipairs(ikBonesChainsList) do
		local ikBonesNamesList = {}
		for n, id in ipairs(ikBonesChainsList[i]) do
			local bone = skel:Bone(id)
			table.insert(ikBonesNamesList, bone:Name())
		end
		table.insert(ikBonesChainsNamesList, ikBonesNamesList)
	end
	local areNewIK = false
	for c, a in ipairs(ikBonesChainsList) do
		local startBone = ikBonesChainsList[c][1]
		local endBone = ikBonesChainsList[c][#ikBonesChainsList[c]]
		local isStartBoneTargeted = skel:TargetOfBoneChain(startBone, moho.layerFrame)
		local isEndBoneTargeted = skel:TargetOfBoneChain(endBone, moho.layerFrame)
		
		local sBone = skel:Bone(startBone)
		local eBone = skel:Bone(endBone)
		if #ikBonesChainsList[c] == 2 and isStartBoneTargeted == -1 and isEndBoneTargeted == -1 and not sBone.fFixedAngle 
		and not eBone.fFixedAngle and not sBone.fIgnoredByIK and not eBone.fIgnoredByIK then
			areNewIK = true
			local existInList
			local removeList = {}
			for i, id in ipairs(self.ikBonesList.id) do
				existInList = MR_Utilities:ValueExists(self.ikBonesList.id[i], startBone)
				if not existInList then
					existInList = MR_Utilities:ValueExists(self.ikBonesList.id[i], endBone)
				end
				if existInList then
					existInList = i
					table.insert(removeList, existInList)
				end
			end

			if #removeList > 0 then
				table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
				for i, v in ipairs(removeList) do
					table.remove(self.ikBonesList.id, v)
					table.remove(self.ikBonesList.names, v)
					table.remove(self.ikBonesList.startBone, v)
					table.remove(self.ikBonesList.endBone, v)
					table.remove(self.ikBonesList.stretching, v)
				end
			end

			removeList = {}
			existInList = nil
			for i, id in ipairs(self.followBonesList.id) do
				existInList = MR_Utilities:ValueExists(self.followBonesList.id[i], startBone)
				if not existInList then
					existInList = MR_Utilities:ValueExists(self.followBonesList.id[i], endBone)
				end
				if existInList then
					existInList = i
					table.insert(removeList, existInList)
				end
			end

			if #removeList > 0 then
			
				table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
				for i, v in ipairs(removeList) do
					table.remove(self.followBonesList.id, v)
					table.remove(self.followBonesList.names, v)
					table.remove(self.followBonesList.startBone, v)
					table.remove(self.followBonesList.endBone, v)
					table.remove(self.followBonesList.stretching, v)
				end
			end
		end
	end
	
	for c, a in ipairs(ikBonesChainsList) do
		local startBone = ikBonesChainsList[c][1]
		local endBone = ikBonesChainsList[c][#ikBonesChainsList[c]]
		local isStartBoneTargeted = skel:TargetOfBoneChain(startBone, moho.layerFrame)
		local isEndBoneTargeted = skel:TargetOfBoneChain(endBone, moho.layerFrame)
		
		local sBone = skel:Bone(startBone)
		local eBone = skel:Bone(endBone)
		if #ikBonesChainsList[c] == 2 and isStartBoneTargeted == -1 and isEndBoneTargeted == -1 and not sBone.fFixedAngle 
		and not eBone.fFixedAngle and not sBone.fIgnoredByIK and not eBone.fIgnoredByIK then
			table.insert(self.ikBonesList.id, ikBonesChainsList[c])
			table.insert(self.ikBonesList.names, ikBonesChainsNamesList[c])
			table.insert(self.ikBonesList.startBone, startBone)
			table.insert(self.ikBonesList.endBone, endBone)
			table.insert(self.ikBonesList.stretching, false)

			for _, id in ipairs(ikBonesChainsList[c]) do
				local boneID = id
				local existInList = MR_Utilities:ValueExists(self.lockAngleList, boneID)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
				existInList = MR_Utilities:ValueExists(self.lockPosList, boneID)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	
	if not areNewIK and moho:CountSelectedBones() > 0 then
		self.operationFailes = 2
		moho.view:DrawMe()
	else
		self.bonesDataActiveIK = true
		local bonesDataActiveIKKey = self.scriptDataName..'bonesDataActiveIK '
		scriptInfo:Set(bonesDataActiveIKKey, self.bonesDataActiveIK)
	end
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AddToFollowBones(moho)
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self.bonesDataActiveF = true
	local bonesDataActiveFKey = self.scriptDataName..'bonesDataActiveF '
	scriptInfo:Set(bonesDataActiveFKey, self.bonesDataActiveF)

	self:LoadBonesData(moho.layer)
	self:ValidateFollowList(moho)
	
	self:RemoveSelectedBonesFromFollowList(moho)
	self:RemoveSelectedBonesFromIkList(moho)
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			local followBonesIdList = {}
			table.insert(followBonesIdList, i)
			table.insert(self.followBonesList.id, followBonesIdList)
			
			local followBonesNameList = {}
			table.insert(followBonesNameList, bone:Name())
			table.insert(self.followBonesList.names, followBonesNameList)
		
			table.insert(self.followBonesList.startBone, i)
			table.insert(self.followBonesList.endBone, i)
			table.insert(self.followBonesList.stretching, false)
			
			for _, id in ipairs(followBonesIdList) do
				local boneID = id
				local existInList = MR_Utilities:ValueExists(self.lockAngleList, boneID)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
				existInList = MR_Utilities:ValueExists(self.lockPosList, boneID)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	
	self.forceFollowBonesGraphics = true
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AdjustFollowBones(moho, index)
	if not self.followBonesList.id or #self.followBonesList.id < 1 then
		return
	end

	local b = index
	local endFollowBoneId = self.followBonesList.endBone[b]
	
	if self.ignoreBonesList[endFollowBoneId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end
	
	if self.followBonesDataList.block[b] and self.mode ~= 0 then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	local startFollowBone = skel:Bone(self.followBonesList.startBone[b])
	local endFollowBone = skel:Bone(self.followBonesList.endBone[b])
	if not startFollowBone or not endFollowBone then
		return
	end
	skel:UpdateBoneMatrix()
	moho.layer:UpdateCurFrame()

	local startBonePos = LM.Vector2:new_local()	
	startBonePos:Set(0, 0)

	if moho.frame == 0 then
		startFollowBone.fRestMatrix:Transform(startBonePos)
	else
		startFollowBone.fMovedMatrix:Transform(startBonePos)
	end

	if self.boneStretching and self.followBonesList.stretching[b] then
		local secondCursorDist = MR_Utilities:GetDistance(startBonePos, self.followBonesDataList.targetPos[b])
		local scaleFactor = (secondCursorDist / self.followBonesDataList.distance[b])
		
		for i=1, #self.followBonesList.id[b] do
			local bone = skel:Bone(self.followBonesList.id[b][i])
			local newScale = (bone.fTempScale * scaleFactor) - self.followBonesDataList.scaleDelta[b][i]
			bone.fAnimScale:SetValue(moho.layerFrame, newScale)
		end
		
		if smartBake and not self.followBonesDataList.sBValuesBakedS[b] then
			for i, q in ipairs(self.followBonesList.id[b]) do
				local bone = skel:Bone(q)
				if moho.layerFrame - self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.followBonesDataList.sBValuesP[b][i])
				end
				if moho.layerFrame + self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.followBonesDataList.sBValuesN[b][i])
				end
			end	
			self.followBonesDataList.sBValuesBakedS[b] = true
		end
	end
	local bone = startFollowBone
	local center = LM.Vector2:new_local()

	center:Set(self.followBonesDataList.targetPos[b])
	local angle = self.followBonesDataList.startAngle[b]
	local v1 = self.followBonesDataList.lastVec[b] - center
	local v2 = startBonePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.followBonesDataList.startAngle[b] = angle
	self.followBonesDataList.lastVec[b] = startBonePos
	local angleSign = 1.0
	if (not bone.fFixedAngle) then
		angleSign = bone:ParentalFlipFactor()
	end

	local parentAngle = 0

	if startFollowBone.fParent > -1 then
		local parentBone = skel:Bone(startFollowBone.fParent)
		local startParentBonePos = LM.Vector2:new_local()	
		local startParentBoneTipPos = LM.Vector2:new_local()	
		startParentBonePos:Set(0, 0)
		
		if parentBone:IsZeroLength() then
			startParentBoneTipPos:Set(0.1, 0)
		else
			startParentBoneTipPos:Set(parentBone.fLength, 0)
		end
		if moho.frame == 0 then
			parentBone.fRestMatrix:Transform(startParentBonePos)
			parentBone.fRestMatrix:Transform(startParentBoneTipPos)
		else
			parentBone.fMovedMatrix:Transform(startParentBonePos)
			parentBone.fMovedMatrix:Transform(startParentBoneTipPos)
		end
		
		local basePosDelta = startParentBonePos - self.followBonesDataList.lastParentBaseVec[b]
		startParentBonePos = startParentBonePos - basePosDelta
		startParentBoneTipPos = startParentBoneTipPos - basePosDelta
		parentAngle = self.followBonesDataList.parentStartAngle[b]
		local v1 = self.followBonesDataList.lastParentTipVec[b] - startParentBonePos
		local v2 = startParentBoneTipPos - startParentBonePos
		v2:Rotate(-math.atan2(v1.y, v1.x))
		parentAngle = parentAngle + math.atan2(v2.y, v2.x)
		self.followBonesDataList.parentStartAngle[b] = parentAngle
		self.followBonesDataList.lastParentTipVec[b] = startParentBoneTipPos
	end

	local newAgle = (bone.fTempAngle + (angle * angleSign)) - (parentAngle * angleSign)

	if not bone.fFixedAngle then
		if bone.fConstraints then
			local min = bone.fAnimAngle:GetValue(0) - self.followBonesDataList.angleDelta[b]
			local max = min + bone.fMaxConstraint
			min = min + bone.fMinConstraint
			newAgle = LM.Clamp(newAgle, min, max)
		end
	end
	
	if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
		if smartBake and not self.followBonesDataList.bakedA[b] then
			if moho.layerFrame - self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.followBonesDataList.FAngleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.followBonesDataList.FAngleN[b])
			end
			self.followBonesDataList.bakedA[b] = true
		end
	end
end

function MR_PoseTool:AdjustIkBones(moho, index)
	if not self.ikBonesList.id or #self.ikBonesList.id < 1 then
		return
	end

	local b = index
	local endIkBoneId = self.ikBonesList.endBone[b]

	if self.ignoreBonesList[endIkBoneId + 1] == true and not self.ikBonesList.reverseList[b] then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end

	if self.ikBonesDataList.block[b] and self.mode ~= 0 and not self.ikBonesList.reverseList[b]  then
		return
	end
	
	local startIkBone = skel:Bone(self.ikBonesList.startBone[b])
	local endIkBone = skel:Bone(self.ikBonesList.endBone[b])
	if not startIkBone or not endIkBone then
		return
	end
	
	if self.boneStretching and self.ikBonesDataList.needKey[b] and self.ikBonesList.stretching[b] then
		startIkBone.fAnimScale:SetValue(moho.layerFrame, endIkBone.fTempScale - self.ikBonesDataList.startBoneScaleDelta[b])
		endIkBone.fAnimScale:SetValue(moho.layerFrame, endIkBone.fTempScale - self.ikBonesDataList.endBoneScaleDelta[b])
	end
	
	skel:UpdateBoneMatrix()
	moho.layer:UpdateCurFrame()
	local base1 = LM.Vector2:new_local()
	local tip1  = LM.Vector2:new_local()
	local base2 = LM.Vector2:new_local()
	local tip2  = LM.Vector2:new_local()
	
	base1:Set(0, 0)
	tip1:Set(startIkBone.fLength, 0)
	base2:Set(0, 0)
	tip2:Set(endIkBone.fLength, 0)
	if moho.frame == 0 then
		startIkBone.fRestMatrix:Transform(base1)
		startIkBone.fRestMatrix:Transform(tip1)
		endIkBone.fRestMatrix:Transform(base2)
		endIkBone.fRestMatrix:Transform(tip2)
	else
		startIkBone.fMovedMatrix:Transform(base1)
		startIkBone.fMovedMatrix:Transform(tip1)
		endIkBone.fMovedMatrix:Transform(base2)
		endIkBone.fMovedMatrix:Transform(tip2)

	end

	local length1 = self.ikBonesDataList.startBoneLength[b]
	local length2 = self.ikBonesDataList.endtBoneLength[b]
	
	local target = self.ikBonesDataList.endBoneTipPos[b]
	local distBase1ToTarget = MR_Utilities:GetDistance(base1, target)
	local newBase2 = LM.Vector2:new_local()
	local newTip2 = LM.Vector2:new_local()
	
	if distBase1ToTarget > (length1 + length2) then
		self.ikBonesDataList.needKey[b] = true
		local directionAngle = MR_Utilities:GetAngle(base1, target)
		if self.boneStretching and self.ikBonesList.stretching[b] then
			local newBoneDistDelta = distBase1ToTarget / (length1 + length2)
			newBase2:Set(base1.x + length1 * newBoneDistDelta * math.cos(directionAngle), base1.y + length1 * newBoneDistDelta * math.sin(directionAngle))
			newTip2:Set(target)
		else	
			newBase2:Set(base1.x + length1 * math.cos(directionAngle), base1.y + length1 * math.sin(directionAngle))
			newTip2:Set(newBase2.x + length2 * (target.x - newBase2.x) / MR_Utilities:GetDistance(newBase2, target), newBase2.y + length2 * (target.y - newBase2.y) / MR_Utilities:GetDistance(newBase2, target))
		end
	else
		local aV = length1
		local bV = length2
		local cV = distBase1ToTarget
		local cosAngle = (aV^2 + cV^2 - bV^2) / (2 * aV * cV)
		local angle = math.acos(cosAngle)
		local directionAngle = MR_Utilities:GetAngle(base1, target)
		local newTip1 = LM.Vector2:new_local()
		
		if self.ikBonesList.reverseList[b] then
			if self.ikBonesDataList.initialDirection[b]  > 0 then
				newTip1:Set(base1.x + length1 * math.cos(directionAngle + angle), base1.y + length1 * math.sin(directionAngle + angle))
			else
				newTip1:Set(base1.x + length1 * math.cos(directionAngle - angle), base1.y + length1 * math.sin(directionAngle - angle))
				
			end
		else
			if self.ikBonesDataList.initialDirection[b] < 0 then
				newTip1:Set(base1.x + length1 * math.cos(directionAngle + angle), base1.y + length1 * math.sin(directionAngle + angle))
			else
				newTip1:Set(base1.x + length1 * math.cos(directionAngle - angle), base1.y + length1 * math.sin(directionAngle - angle))
			end
		end
		
		newBase2 = newTip1
		newTip2:Set(newBase2.x + length2 * math.cos(MR_Utilities:GetAngle(newBase2, target)), newBase2.y + length2 * math.sin(MR_Utilities:GetAngle(newBase2, target)))
		
		if newBase2.x ~= newBase2.x or newBase2.y ~= newBase2.y then
			local directionAngle = MR_Utilities:GetAngle(target, base1)

			newBase2:Set(target.x + length1 * math.cos(directionAngle), target.y + length1 * math.sin(directionAngle))
			local distNewBase2ToTarget = MR_Utilities:GetDistance(newBase2, target)
			newTip2:Set(newBase2.x + length2 * (target.x - newBase2.x) / distNewBase2ToTarget, newBase2.y + length2 * (target.y - newBase2.y) / distNewBase2ToTarget)
		end
	end
	
	skel:IKAngleSolver(self.ikBonesList.startBone[b], newBase2)

	local startBoneNewAngle = startIkBone.fAngle - self.ikBonesDataList.startAngleDelta[b]
	
	if not startIkBone.fFixedAngle then
		if startIkBone.fConstraints then
			local min = startIkBone.fAnimAngle:GetValue(0) - self.ikBonesDataList.startAngleDelta[b]
			local max = min + startIkBone.fMaxConstraint
			min = min + startIkBone.fMinConstraint
			startBoneNewAngle = LM.Clamp(startBoneNewAngle, min, max)
		end
	end
	
	if not MR_Utilities:IsEqual(startBoneNewAngle, startIkBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		startIkBone.fAnimAngle:SetValue(moho.layerFrame, startBoneNewAngle)
		startIkBone.fAnimAngle.value = startIkBone.fAngle
		if smartBake and not self.ikBonesDataList.startBoneBakedA[b] then
			if moho.layerFrame - self.interval > 0 then
				startIkBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.ikBonesDataList.startBoneFAngleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				startIkBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.ikBonesDataList.startBoneFAngleN[b])
			end
			self.ikBonesDataList.startBoneBakedA[b] = true
		end
	end
	
	if self.boneStretching and self.ikBonesDataList.needKey[b] and self.ikBonesList.stretching[b] then
		local newBoneDistDelta = distBase1ToTarget / (length1 + length2)
		if distBase1ToTarget <= (length1 + length2) then
			newBoneDistDelta = 1
		end

		local startBoneNewScale = (startIkBone.fTempScale * newBoneDistDelta) - self.ikBonesDataList.startBoneScaleDelta[b]
		local endBoneNewScale = (endIkBone.fTempScale * newBoneDistDelta) - self.ikBonesDataList.endBoneScaleDelta[b]
		
		startIkBone.fAnimScale:SetValue(moho.layerFrame, startBoneNewScale)
		endIkBone.fAnimScale:SetValue(moho.layerFrame, endBoneNewScale)
		
		skel:UpdateBoneMatrix()
		moho.layer:UpdateCurFrame()
	end
	
	skel:IKAngleSolver(self.ikBonesList.endBone[b], newTip2, 1, false, true)

	local endBoneNewAngle = endIkBone.fAngle - self.ikBonesDataList.endAngleDelta[b]
	
	if not endIkBone.fFixedAngle then
		if endIkBone.fConstraints then
			local min = endIkBone.fAnimAngle:GetValue(0) - self.ikBonesDataList.endAngleDelta[b]
			local max = min + endIkBone.fMaxConstraint
			min = min + endIkBone.fMinConstraint
			endBoneNewAngle = LM.Clamp(endBoneNewAngle, min, max)
		end
	end

	if not MR_Utilities:IsEqual(endBoneNewAngle, endIkBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		endIkBone.fAnimAngle:SetValue(moho.layerFrame, endBoneNewAngle)
		endIkBone.fAnimAngle.value = endIkBone.fAngle
		if smartBake and not self.ikBonesDataList.endBoneBakedA[b] then
			if moho.layerFrame - self.interval > 0 then
				endIkBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.ikBonesDataList.endBoneFAngleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				endIkBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.ikBonesDataList.endBoneFAngleN[b])
			end
			self.ikBonesDataList.endBoneBakedA[b] = true
		end
	end
	
	if self.boneStretching and self.ikBonesDataList.needKey[b] and self.ikBonesList.stretching[b] then
		if smartBake and not self.ikBonesDataList.startBoneBakedS[b] then
			if moho.layerFrame - self.interval > 0 then
				startIkBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.ikBonesDataList.startBoneFScaleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				startIkBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.ikBonesDataList.startBoneFScaleN[b])
			end
			self.ikBonesDataList.startBoneBakedS[b] = true
		end
		
		if smartBake and not self.ikBonesDataList.endBoneBakedS[b] then
			if moho.layerFrame - self.interval > 0 then
				endIkBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.ikBonesDataList.endBoneFScaleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				endIkBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.ikBonesDataList.endBoneFScaleN[b])
			end
			self.ikBonesDataList.startBoneBakedS[b] = true
		end
	end
end

function MR_PoseTool:AdjustLockPos(moho, index)
	if not self.lockPosList or #self.lockPosList < 1 then
		return
	end
	
	local i = index
	local lockPosId = self.lockPosList[i]

	if self.ignoreBonesList[lockPosId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	moho.layer:UpdateCurFrame()

	local bone = skel:Bone(self.lockPosList[i])
	if bone then
		if not bone.fSelected then
			local newPos 
			if bone.fParent >-1 then
				local matrix = LM.Matrix:new_local()
				local bonePos = LM.Vector2:new_local()
				bonePos:Set(self.lockedBonesPos[i])
				if moho.frame == 0 then
					matrix:Set(skel:Bone(bone.fParent).fRestMatrix)
				else
					matrix:Set(skel:Bone(bone.fParent).fMovedMatrix)
				end
				matrix:Invert()
				matrix:Transform(bonePos)
				newPos = bonePos - self.lockedBonesDeltaPos[i]
			else
				newPos = self.lockedBonesPos[i] - self.lockedBonesDeltaPos[i]
			end
			local originalPosVal = bone.fAnimPos:GetValue(moho.layerFrame)
			if not MR_Utilities:IsEqual(newPos.x, originalPosVal.x, 0.000001) or not MR_Utilities:IsEqual(newPos.y, originalPosVal.y, 0.000001) then
				bone.fAnimPos:SetValue(moho.layerFrame, newPos)
				if smartBake and not self.lockPosBaked[i] then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.lockedBonesSBPosValuesP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.lockedBonesSBPosValuesN[i])
					end
					self.lockPosBaked[i] = true
				end
			end	
		end
	end
end

function MR_PoseTool:AdjustLockAngles(moho, index)
	if not self.lockAngleList or #self.lockAngleList < 1 then
		return
	end
	
	local i = index
	local lockAngleId = self.lockAngleList[i]

	if self.ignoreBonesList[lockAngleId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	local smartBake = self.bakeAdjacentFrames
	if MOHO.MohoGlobals.EditMultipleKeys then
		smartBake = false
	end
	
	moho.layer:UpdateCurFrame()
	local bone = skel:Bone(self.lockAngleList[i])
	if bone then
		if not bone.fSelected and not bone.fFixedAngle then
			local parentAngle = 0
			if bone.fParent > -1 then
				local parentBone = skel:Bone(bone.fParent)
				local parentBonePos = LM.Vector2:new_local()	
				local parentBoneTipPos = LM.Vector2:new_local()	
				parentBonePos:Set(0, 0)
				
				if parentBone:IsZeroLength() then
					parentBoneTipPos:Set(0.1, 0)
				else
					if bone:IsZeroLength() then
						parentBoneTipPos:Set(0.1, 0)
					else
						parentBoneTipPos:Set(bone.fLength, 0)
					end
				end
				if moho.frame == 0 then
					parentBone.fRestMatrix:Transform(parentBonePos)
					parentBone.fRestMatrix:Transform(parentBoneTipPos)
				else
					parentBone.fMovedMatrix:Transform(parentBonePos)
					parentBone.fMovedMatrix:Transform(parentBoneTipPos)
				end
				local basePosDelta = parentBonePos - self.lockBonesLastParentBaseVec[i]
				parentBonePos = parentBonePos - basePosDelta
				parentBoneTipPos = parentBoneTipPos - basePosDelta
				parentAngle = self.lockBonesParentStartAngle[i]
				local v1 = self.lockBonesLastParentTipVec[i] - parentBonePos
				local v2 = parentBoneTipPos - parentBonePos
				v2:Rotate(-math.atan2(v1.y, v1.x))
				parentAngle = parentAngle + math.atan2(v2.y, v2.x)
				self.lockBonesParentStartAngle[i] = parentAngle
				self.lockBonesLastParentTipVec[i] = parentBoneTipPos
			end
			
			local angleSign = 1.0
			if (not bone.fFixedAngle) then
				angleSign = bone:ParentalFlipFactor()
			end
			
			local newAgle = (bone.fTempAngle - parentAngle * angleSign)
			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0)
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle = LM.Clamp(newAgle, min, max)
				end
			end

			if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
				if smartBake and not self.lockAngleBaked[i] then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.lockedBonesSBAngleValuesP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.lockedBonesSBAngleValuesN[i])
					end
					self.lockAngleBaked[i] = true
				end
			end	
		end
	end
end

function MR_PoseTool:TestMousePointGraphicMenu(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	local v = LM.Vector2:new_local()
	local pt = LM.Point:new_local()
	local m = LM.Matrix:new_local()
	local localV = LM.Vector2:new_local()
	
	local g = mouseEvent.view:Graphics()
	g:Push()

	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height

	local currentScale = g:CurrentScale(false)
	g:Pop()
	
	local offset = self.iconsDistance / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)

	local radius = self.iconsRadius
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 1 -- set follow bones icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 2 -- scale follow bones icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 3 -- lock angle icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 4 -- lock pos icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 5 -- clear pos icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 6 -- clear pos icon
	end
	
	if self.showQuickMenu and self.showQuickMenu4 and self.bonesDataActive then
		local iconCenter = LM.Vector2:new_local()
		center:Set(self.graphicsMenuCenter)
		center:Set(center.x, center.y - 0.15 / currentScale / height)
		local buttonsWidth = 0.05 / currentScale / height
		v:Set(center.x - buttonsWidth - buttonsWidth, center.y)
		radius = 12
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 7 -- F
		end
		
		v:Set(center.x - buttonsWidth, center.y)
		radius = 12
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 8 -- IK
		end
		
		v:Set(center.x, center.y)
		radius = 12
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 9 -- A
		end
		
		v:Set(center.x + buttonsWidth, center.y)
		radius = 12
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 10 -- P
		end
		
		v:Set(center.x + buttonsWidth * 2, center.y)
		radius = 12
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 11 -- S
		end
		
		if self.skeletonLayersNavigation then
			v:Set(center)
			local radiusX = 120
			local radiusY = 50
			mouseEvent.view:Graphics():WorldToScreen(v, pt)
			if (math.abs(pt.x - mouseEvent.pt.x) < radiusX and math.abs(pt.y - mouseEvent.pt.y) < radiusY) then
				return 100 -- Block skeleton pick
			end
		end
	end
	
	if self.skeletonLayersNavigation then
		center:Set(self.graphicsMenuCenter)
		v:Set(center)
		radius = 110
		mouseEvent.view:Graphics():WorldToScreen(v, pt)
		if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
			return 100 -- Block skeleton pick
		end
	end
	
	return 0
end

function MR_PoseTool:AddToLockAngleList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self.bonesDataActiveA = true
	local bonesDataActiveAKey = self.scriptDataName..'bonesDataActiveA '
	scriptInfo:Set(bonesDataActiveAKey, self.bonesDataActiveA)
	
	self:LoadBonesData(moho.layer)
	self:RemoveSelectedBonesFromFollowList(moho)
	self:RemoveSelectedBonesFromIkList(moho)
	
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList = MR_Utilities:ValueExists(self.lockAngleList, i)
			if not existInList then
				table.insert(self.lockAngleList, i)
				table.insert(self.lockAngleBoneNamesList, bone:Name())
			else
				table.remove(self.lockAngleList, existInList)
				table.remove(self.lockAngleBoneNamesList, existInList)
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AddToLockPosList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self.bonesDataActiveP = true
	local bonesDataActivePKey = self.scriptDataName..'bonesDataActiveP '
	scriptInfo:Set(bonesDataActivePKey, self.bonesDataActiveP)
	
	self:LoadBonesData(moho.layer)
	self:RemoveSelectedBonesFromFollowList(moho)
	self:RemoveSelectedBonesFromIkList(moho)
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList = MR_Utilities:ValueExists(self.lockPosList, i)
			if not existInList then
				table.insert(self.lockPosList, i)
				table.insert(self.lockPosBoneNamesList, bone:Name())
			else
				table.remove(self.lockPosList, existInList)
				table.remove(self.lockPosBoneNamesList, existInList)
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:RemoveFromLockList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	self:LoadBonesData(moho.layer)
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList
			if self.lockAngleList then
				existInList = MR_Utilities:ValueExists(self.lockAngleList, i)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
			end
			if self.lockPosList then
				existInList = MR_Utilities:ValueExists(self.lockPosList, i)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:RemoveFromFollowList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	self:LoadBonesData(moho.layer)
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList
			if self.lockAngleList then
				existInList = MR_Utilities:ValueExists(self.lockAngleList, i)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
			end
			if self.lockPosList then
				existInList = MR_Utilities:ValueExists(self.lockPosList, i)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:ValidateLockList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local removeList = {}
	for b=1, #self.lockAngleList do
		local tBone = skel:Bone(self.lockAngleList[b])
		if tBone then
			if tBone:Name() ~= self.lockAngleBoneNamesList[b] then
				table.insert(removeList, b)
			end
		else
			table.insert(removeList, b)
		end
	end

	if #removeList > 0 then
		table.sort(removeList, function(a, b) return a > b end)
		for i, v in ipairs(removeList) do
			table.remove(self.lockAngleList, v)
			table.remove(self.lockAngleBoneNamesList, v)
		end
	end
	
	removeList = {}
	
	for b=1, #self.lockPosList do
		local tBone = skel:Bone(self.lockPosList[b])
		if tBone then
			if tBone:Name() ~= self.lockPosBoneNamesList[b] then
				table.insert(removeList, b)
			end
		else
			table.insert(removeList, b)
		end
	end

	if #removeList > 0 then
		table.sort(removeList, function(a, b) return a > b end)
		for i, v in ipairs(removeList) do
			table.remove(self.lockPosList, v)
			table.remove(self.lockPosBoneNamesList, v)
		end
	end
end

function MR_PoseTool:ValidateFollowList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	local removeList = {}
	for b=1, #self.followBonesList.id do
		for i=1, #self.followBonesList.id[b] do
			if self.followBonesList.stretching[b] == nil then
				self.followBonesList.stretching[b] = false
			end
			local tBone = skel:Bone(self.followBonesList.id[b][i])
			if tBone then
				if tBone:Name() ~= self.followBonesList.names[b][i] or tBone:IsZeroLength() then
					table.insert(removeList, b)
					break
				end
			else
				table.insert(removeList, b)
				break
			end
		end
	end
	
	if #removeList > 0 then
		table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
		for i, v in ipairs(removeList) do
			table.remove(self.followBonesList.id, v)
			table.remove(self.followBonesList.names, v)
			table.remove(self.followBonesList.length, v)
			table.remove(self.followBonesList.startBone, v)
			table.remove(self.followBonesList.endBone, v)
			table.remove(self.followBonesList.stretching, v)
		end
	end
end

function MR_PoseTool:ValidateIkList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	local removeList = {}
	for b=1, #self.ikBonesList.id do
		for i=1, #self.ikBonesList.id[b] do
			if self.ikBonesList.stretching[b] == nil then
				self.ikBonesList.stretching[b] = false
			end
			local tBone = skel:Bone(self.ikBonesList.id[b][i])
			if tBone then
				if tBone:Name() ~= self.ikBonesList.names[b][i] or tBone:IsZeroLength() then
					table.insert(removeList, b)
					break
				end
			else
				table.insert(removeList, b)
				break
			end
		end
	end
	
	if #removeList > 0 then
		table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
		for i, v in ipairs(removeList) do
			table.remove(self.ikBonesList.id, v)
			table.remove(self.ikBonesList.names, v)
			table.remove(self.ikBonesList.length, v)
			table.remove(self.ikBonesList.startBone, v)
			table.remove(self.ikBonesList.endBone, v)
			table.remove(self.ikBonesList.stretching, v)
		end
	end
end

function MR_PoseTool:AdjustFollowAndLockBones(moho)
	if self.bonesDataActive then
		for i=1, #self.followLockedBonesList.listIndex do
			if self.followLockedBonesList.list[i] == 1 then
				self:AdjustFollowBones(moho, self.followLockedBonesList.listIndex[i])
			elseif self.followLockedBonesList.list[i] == 2 then
				self:AdjustLockAngles(moho, self.followLockedBonesList.listIndex[i])
			elseif self.followLockedBonesList.list[i] == 3 then
				self:AdjustLockPos(moho, self.followLockedBonesList.listIndex[i])
			elseif self.followLockedBonesList.list[i] == 4 then
				self:AdjustIkBones(moho, self.followLockedBonesList.listIndex[i])
			end
		end
	end
end

function MR_PoseTool:RemoveSelectedBonesFromFollowList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	self:LoadBonesData(moho.layer)
	local removeList = {}
	for b=1, #self.followBonesList.id do
		if self.followBonesList.stretching[b] == nil then
			self.followBonesList.stretching[b] = false
		end
		for i=1, #self.followBonesList.id[b] do
			local bone = skel:Bone(self.followBonesList.id[b][i])
			if bone.fSelected then
				table.insert(removeList, b)
				break
			end
		end
	end
	
	if #removeList > 0 then
		table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
		for i, v in ipairs(removeList) do
			table.remove(self.followBonesList.id, v)
			table.remove(self.followBonesList.names, v)
			table.remove(self.followBonesList.startBone, v)
			table.remove(self.followBonesList.endBone, v)
			table.remove(self.followBonesList.stretching, v)
		end
	end
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:RemoveSelectedBonesFromIkList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	self:LoadBonesData(moho.layer)
	local removeList = {}
	for b=1, #self.ikBonesList.id do
		if self.ikBonesList.stretching[b] == nil then
			self.ikBonesList.stretching[b] = false
		end
		for i=1, #self.ikBonesList.id[b] do
			local bone = skel:Bone(self.ikBonesList.id[b][i])
			if bone.fSelected then
				table.insert(removeList, b)
				break
			end
		end
	end

	if #removeList > 0 then
		table.sort(removeList, function(a, b) return MR_Utilities:Compare(a, b) end)
		for i, v in ipairs(removeList) do
			table.remove(self.ikBonesList.id, v)
			table.remove(self.ikBonesList.names, v)
			table.remove(self.ikBonesList.startBone, v)
			table.remove(self.ikBonesList.endBone, v)
			table.remove(self.ikBonesList.stretching, v)
		end
	end
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:LoadBonesData(layer)
	self.followBonesList = {}
	self.followBonesList.id = {}
	self.followBonesList.names = {}
	self.followBonesList.length = {}
	self.followBonesList.startBone = {}
	self.followBonesList.endBone = {}
	self.followBonesList.stretching = {}

	local scriptInfo = layer:ScriptData()
	
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	if scriptInfo:HasKey(followBonesLengthKey) then
		local keyValue = scriptInfo:GetString(followBonesLengthKey)
		MR_Utilities:StringToTable(keyValue, self.followBonesList.length, 'n')
	end
	
	local idList = {}
	local followBonesIdKey = self.scriptDataName..'followBones_id '
	if scriptInfo:HasKey(followBonesIdKey) then
		local keyValue = scriptInfo:GetString(followBonesIdKey)
		MR_Utilities:StringToTable(keyValue, idList, 'n')
	end

	if self.singleFollowBonesMode then
		for i, v in pairs(idList) do
			local group = {}
			table.insert(group, v) 
			self.followBonesList.id[i] = group
			self.followBonesList.startBone[i] = v
			self.followBonesList.endBone[i] = v
		end
	else
		MR_Utilities:DistributeValuesToTables(self.followBonesList.id, idList, self.followBonesList.length)
	end
	
	local namesList = {}
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	if scriptInfo:HasKey(followBonesNamesKey) then
		local keyValue = scriptInfo:GetString(followBonesNamesKey)
		MR_Utilities:StringToTable(keyValue, namesList, 's')
	end
	if self.singleFollowBonesMode then
		for i, v in pairs(namesList) do
			local group = {}
			table.insert(group, v) 
			self.followBonesList.names[i] = group
		end
	else
		MR_Utilities:DistributeValuesToTables(self.followBonesList.names, namesList, self.followBonesList.length)
	end
	
	if not self.singleFollowBonesMode then
		local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
		if scriptInfo:HasKey(followBonesStartBoneKey) then
			local keyValue = scriptInfo:GetString(followBonesStartBoneKey)
			MR_Utilities:StringToTable(keyValue, self.followBonesList.startBone, 'n')
		end
	end
	
	if not self.singleFollowBonesMode then
		local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
		if scriptInfo:HasKey(followBonesEndBoneKey) then
			local keyValue = scriptInfo:GetString(followBonesEndBoneKey)
			
			MR_Utilities:StringToTable(keyValue, self.followBonesList.endBone, 'n')
		end
	end
	if not self.singleFollowBonesMode then
		local followBonesStretchingBoneKey = self.scriptDataName..'followBones_stretching '
		if scriptInfo:HasKey(followBonesStretchingBoneKey) then
			local keyValue = scriptInfo:GetString(followBonesStretchingBoneKey)
				
			MR_Utilities:StringToTable(keyValue, self.followBonesList.stretching, 'b')
		end
	else
		local idList = {}
		local idOutList = {}
		local idSretchingList = {}
		local followBonesStretchingBoneKey = self.scriptDataName..'followBones_stretching '
		if scriptInfo:HasKey(followBonesStretchingBoneKey) then
			local keyValue = scriptInfo:GetString(followBonesStretchingBoneKey)
			MR_Utilities:StringToTable(keyValue, idSretchingList, 'b')
		end
		
		local followBonesIdKey = self.scriptDataName..'followBones_id '
		if scriptInfo:HasKey(followBonesIdKey) then
			local keyValue = scriptInfo:GetString(followBonesIdKey)
			MR_Utilities:StringToTable(keyValue, idList, 'n')
		end
		MR_Utilities:DistributeValuesToTables(idOutList, idList, self.followBonesList.length)
		
		for i=1, #idOutList do
			for b=1, #idOutList[i] do
				table.insert(self.followBonesList.stretching, idSretchingList[i])
			end
		end
	end
	
	self.ikBonesList = {}
	self.ikBonesList.id = {}
	self.ikBonesList.names = {}
	self.ikBonesList.length = {}
	self.ikBonesList.startBone = {}
	self.ikBonesList.endBone = {}
	self.ikBonesList.stretching = {}
	
	local ikBonesLengthKey = self.scriptDataName..'ikBones_length '
	if scriptInfo:HasKey(ikBonesLengthKey) then
		local keyValue = scriptInfo:GetString(ikBonesLengthKey)
		MR_Utilities:StringToTable(keyValue, self.ikBonesList.length, 'n')
	end
	
	idList = {}
	local ikBonesIdKey = self.scriptDataName..'ikBones_id '
	if scriptInfo:HasKey(ikBonesIdKey) then
		local keyValue = scriptInfo:GetString(ikBonesIdKey)
		MR_Utilities:StringToTable(keyValue, idList, 'n')
	end

	MR_Utilities:DistributeValuesToTables(self.ikBonesList.id, idList, self.ikBonesList.length)
	local namesList = {}
	local ikBonesNamesKey = self.scriptDataName..'ikBones_names '
	if scriptInfo:HasKey(ikBonesNamesKey) then
		local keyValue = scriptInfo:GetString(ikBonesNamesKey)
		MR_Utilities:StringToTable(keyValue, namesList, 's')
	end

	MR_Utilities:DistributeValuesToTables(self.ikBonesList.names, namesList, self.ikBonesList.length)
	
	local ikBonesStartBoneKey = self.scriptDataName..'ikBones_startBone '
	if scriptInfo:HasKey(ikBonesStartBoneKey) then
		local keyValue = scriptInfo:GetString(ikBonesStartBoneKey)
		MR_Utilities:StringToTable(keyValue, self.ikBonesList.startBone, 'n')
	end
	
	local ikBonesEndBoneKey = self.scriptDataName..'ikBones_endBone '
	if scriptInfo:HasKey(ikBonesEndBoneKey) then
		local keyValue = scriptInfo:GetString(ikBonesEndBoneKey)
		
		MR_Utilities:StringToTable(keyValue, self.ikBonesList.endBone, 'n')
	end
	
	local ikBonesStretchingBoneKey = self.scriptDataName..'ikBones_stretching '
	if scriptInfo:HasKey(ikBonesStretchingBoneKey) then
		local keyValue = scriptInfo:GetString(ikBonesStretchingBoneKey)
			
		MR_Utilities:StringToTable(keyValue, self.ikBonesList.stretching, 'b')
	end
	
	self.lockAngleList = {}
	self.lockAngleBoneNamesList = {}
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	if scriptInfo:HasKey(lockAngleListKey) then
		local keyValue = scriptInfo:GetString(lockAngleListKey)
		MR_Utilities:StringToTable(keyValue, self.lockAngleList, 'n')
	end
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	if scriptInfo:HasKey(lockAngleBoneNamesListKey) then
		local keyValue = scriptInfo:GetString(lockAngleBoneNamesListKey)
		MR_Utilities:StringToTable(keyValue, self.lockAngleBoneNamesList, 's')
	end
	
	self.lockPosList = {}
	self.lockPosBoneNamesList = {}
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	if scriptInfo:HasKey(lockPosListKey) then
		local keyValue = scriptInfo:GetString(lockPosListKey)
		MR_Utilities:StringToTable(keyValue, self.lockPosList, 'n')
	end
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	if scriptInfo:HasKey(lockPosBoneNamesListKey) then
		local keyValue = scriptInfo:GetString(lockPosBoneNamesListKey)
		MR_Utilities:StringToTable(keyValue, self.lockPosBoneNamesList, 's')
	end
end

function MR_PoseTool:SaveBonesData(layer)
	local scriptInfo = layer:ScriptData()
	local keyValue = ''
	local tblLength = ''
	local followBonesIdKey = self.scriptDataName..'followBones_id '
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	for i, tbl in ipairs(self.followBonesList.id) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
		local length = tostring(#tbl)
		tblLength = tblLength..#length..' '..length..','
	end
	
	scriptInfo:Set(followBonesIdKey, keyValue)
	scriptInfo:Set(followBonesLengthKey, tblLength)
	
	keyValue = ''
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	for i, tbl in ipairs(self.followBonesList.names) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
	end
	scriptInfo:Set(followBonesNamesKey, keyValue)

	local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
	keyValue = MR_Utilities:TableToString(self.followBonesList.startBone)
	scriptInfo:Set(followBonesStartBoneKey, keyValue)
	
	local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
	keyValue = MR_Utilities:TableToString(self.followBonesList.endBone)
	scriptInfo:Set(followBonesEndBoneKey, keyValue)
	
	local followBonesStretchingBoneKey = self.scriptDataName..'followBones_stretching '
	keyValue = MR_Utilities:TableToString(self.followBonesList.stretching)
	scriptInfo:Set(followBonesStretchingBoneKey, keyValue)
	
	keyValue = ''
	tblLength = ''
	local ikBonesIdKey = self.scriptDataName..'ikBones_id '
	local ikBonesLengthKey = self.scriptDataName..'ikBones_length '
	for i, tbl in ipairs(self.ikBonesList.id) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
		local length = tostring(#tbl)
		tblLength = tblLength..#length..' '..length..','
	end

	scriptInfo:Set(ikBonesIdKey, keyValue)
	scriptInfo:Set(ikBonesLengthKey, tblLength)
	
	keyValue = ''
	local ikBonesNamesKey = self.scriptDataName..'ikBones_names '
	for i, tbl in ipairs(self.ikBonesList.names) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
	end
	scriptInfo:Set(ikBonesNamesKey, keyValue)

	local ikBonesStartBoneKey = self.scriptDataName..'ikBones_startBone '
	keyValue = MR_Utilities:TableToString(self.ikBonesList.startBone)
	scriptInfo:Set(ikBonesStartBoneKey, keyValue)
	
	local ikBonesEndBoneKey = self.scriptDataName..'ikBones_endBone '
	keyValue = MR_Utilities:TableToString(self.ikBonesList.endBone)
	scriptInfo:Set(ikBonesEndBoneKey, keyValue)
	
	local ikBonesStretchingBoneKey = self.scriptDataName..'ikBones_stretching '
	keyValue = MR_Utilities:TableToString(self.ikBonesList.stretching)
	scriptInfo:Set(ikBonesStretchingBoneKey, keyValue)
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	keyValue = MR_Utilities:TableToString(self.lockAngleList)
	scriptInfo:Set(lockAngleListKey, keyValue)
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	keyValue = MR_Utilities:TableToString(self.lockAngleBoneNamesList)
	scriptInfo:Set(lockAngleBoneNamesListKey, keyValue)
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	keyValue = MR_Utilities:TableToString(self.lockPosList)
	scriptInfo:Set(lockPosListKey, keyValue)
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	keyValue = MR_Utilities:TableToString(self.lockPosBoneNamesList)
	scriptInfo:Set(lockPosBoneNamesListKey, keyValue)
end

function MR_PoseTool:CleanUpBonesData(layer)
	local scriptInfo = layer:ScriptData()

	local followBonesIdKey = self.scriptDataName..'followBones_id '
	scriptInfo:Remove(followBonesIdKey)
	
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	scriptInfo:Remove(followBonesLengthKey)
	
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	scriptInfo:Remove(followBonesNamesKey)
	
	local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
	scriptInfo:Remove(followBonesStartBoneKey)
	
	local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
	scriptInfo:Remove(followBonesEndBoneKey)
	
	local followBonesStretchingBoneKey = self.scriptDataName..'followBones_stretching '
	scriptInfo:Remove(followBonesStretchingBoneKey)
	
	local ikBonesIdKey = self.scriptDataName..'ikBones_id '
	scriptInfo:Remove(ikBonesIdKey)
	
	local ikBonesLengthKey = self.scriptDataName..'ikBones_length '
	scriptInfo:Remove(ikBonesLengthKey)
	
	local ikBonesNamesKey = self.scriptDataName..'ikBones_names '
	scriptInfo:Remove(ikBonesNamesKey)
	
	local ikBonesStartBoneKey = self.scriptDataName..'ikBones_startBone '
	scriptInfo:Remove(ikBonesStartBoneKey)
	
	local ikBonesEndBoneKey = self.scriptDataName..'ikBones_endBone '
	scriptInfo:Remove(ikBonesEndBoneKey)
	
	local ikBonesStretchingBoneKey = self.scriptDataName..'ikBones_stretching '
	scriptInfo:Remove(ikBonesStretchingBoneKey)
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	scriptInfo:Remove(lockAngleListKey)
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	scriptInfo:Remove(lockAngleBoneNamesListKey)
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	scriptInfo:Remove(lockPosListKey)
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	scriptInfo:Remove(lockPosBoneNamesListKey)
	
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Remove(bonesDataActiveKey)
	
	self.lockAngleList = {}
	self.lockPosList = {}
	self.lockAngleBoneNamesList = {}
	self.lockPosBoneNamesList = {}
	self.followBonesList = {}
	self.followBonesList.id = {}
	self.followBonesList.names  = {}
	self.followBonesList.length  = {}
	self.followBonesList.startBone = {}
	self.followBonesList.endBone = {}
	
	self.ikBonesList = {}
	self.ikBonesList.id = {}
	self.ikBonesList.names  = {}
	self.ikBonesList.length  = {}
	self.ikBonesList.startBone = {}
	self.ikBonesList.endBone = {}

	self.bonesDataActive = true
end

function MR_PoseTool:CleanUpBoneStretching(moho)
	self:ValidateFollowList(moho)
	self:ValidateIkList(moho)
	for i=1, #self.followBonesList.id do
		self.followBonesList.stretching[i] = false
	end
	for i=1, #self.ikBonesList.id do
		self.ikBonesList.stretching[i] = false
	end

	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:ValidateScriptFiles(moho)
	local utilities = true
	local font = true
	local utilitiesVersion = 1
	local mr_mb_cursor
	local mr_mj_cursor
	local mr_select_bone_layer
	local mr_pose_tool_cursor
	local mr_pose_tool
	local mr_rotate
	local mr_scale
	local mr_translate
	local mr_toggle_panel
	local mr_pose_tool_cheat_sheet
	local mr_info
	
	if not MR_Utilities then
		utilities = false
	else
		utilitiesVersion = tonumber(MR_Utilities:Version())
	end
	
	if not HV_Font then
		font = false
	end
	
	local isWindows = (os.getenv("OS") == "Windows_NT")
	local mohoPath = moho:UserContentDir()
	local testPath = mohoPath:sub(1, -10)
	local isPathCorrect = testPath:find("[/\\]") ~= nil

	if mohoPath:find("[^A-Za-z%s%p%d]") ~= nil then
		isPathCorrect = false
	end
	
	if not isPathCorrect then
		if not utilities then
			alertText = 'The file mr_utilities.lua is missing at '..mohoPath..'\\Scripts\\Utility\\'
			if not isWindows then
				alertText = 'The file mr_utilities.lua is missing at '..mohoPath..'/Scripts/Utility/'
			end
			local alert = LM.GUI.Alert(LM.GUI.ALERT_WARNING, alertTitleText, alertText.."\n".."\n"..howToFixText.."\n".."\n", linkText, 'Copy link to clipboard', 'Close')
			self.scriptValidated = false
			if alert == 0 then
				moho:CopyText(linkText)
			end
			self.scriptValidated = false
			return
		end
		if utilitiesVersion < 1.2 then
			if not isWindows then
				alertText = 'The version of mr_utilities.lua is '..utilitiesVersion..'. Version 1.2 or higher required.'.."\n"..'The file mr_utilities.lua is located at '..mohoPath..'/Scripts/Utility/'
			end
			local alert = LM.GUI.Alert(LM.GUI.ALERT_WARNING, alertTitleText, alertText.."\n".."\n"..howToFixText.."\n".."\n", linkText, 'Copy link to clipboard', 'Close')
			self.scriptValidated = false
			if alert == 0 then
				moho:CopyText(linkText)
			end
			self.scriptValidated = false
			return
		end
		self.scriptValidated = true
		return
	end
	
	local filePath = mohoPath..'\\Scripts\\ScriptResources\\mr_pose_tool\\'
	if not isWindows then
		filePath = mohoPath..'/Scripts/ScriptResources/mr_pose_tool/'
	end
	if utilities then
		if isWindows then
			mr_pose_tool_cursor = MR_Utilities:FileExists(mohoPath..'\\Scripts\\Tool\\mr_pose_tool_cursor.png')
			mr_pose_tool = MR_Utilities:FileExists(mohoPath..'\\Scripts\\Tool\\mr_pose_tool.png')
			mr_mb_cursor = MR_Utilities:FileExists(filePath..'mr_mb_cursor.png')
			mr_mj_cursor = MR_Utilities:FileExists(filePath..'mr_mj_cursor.png')
			mr_select_bone_layer = MR_Utilities:FileExists(filePath..'mr_select_bone_layer.png')
			mr_rotate = MR_Utilities:FileExists(filePath..'mr_rotate.png')
			mr_scale = MR_Utilities:FileExists(filePath..'mr_scale.png')
			mr_translate = MR_Utilities:FileExists(filePath..'mr_translate.png')
			mr_toggle_panel = MR_Utilities:FileExists(filePath..'mr_toggle_panel.png')
			mr_pose_tool_cheat_sheet = MR_Utilities:FileExists(filePath..'mr_pose_tool_cheat_sheet.png')
			mr_info = MR_Utilities:FileExists(filePath..'mr_info.png')
		else
			mr_pose_tool_cursor = MR_Utilities:FileExists(mohoPath..'/Scripts/Tool/mr_pose_tool_cursor.png')
			mr_pose_tool = MR_Utilities:FileExists(mohoPath..'/Scripts/Tool/mr_pose_tool.png')
			mr_mb_cursor = MR_Utilities:FileExists(filePath..'mr_mb_cursor.png')
			mr_mj_cursor = MR_Utilities:FileExists(filePath..'mr_mj_cursor.png')
			mr_select_bone_layer = MR_Utilities:FileExists(filePath..'mr_select_bone_layer.png')
			mr_rotate = MR_Utilities:FileExists(filePath..'mr_rotate.png')
			mr_scale = MR_Utilities:FileExists(filePath..'mr_scale.png')
			mr_translate = MR_Utilities:FileExists(filePath..'mr_translate.png')
			mr_toggle_panel = MR_Utilities:FileExists(filePath..'mr_toggle_panel.png')
			mr_pose_tool_cheat_sheet = MR_Utilities:FileExists(filePath..'mr_pose_tool_cheat_sheet.png')
			mr_info = MR_Utilities:FileExists(filePath..'mr_info.png')
		end
	end

	if utilities and font and utilitiesVersion >= 1.1 and mr_mb_cursor and mr_mj_cursor and mr_select_bone_layer and mr_rotate and mr_scale 
	and mr_translate and mr_toggle_panel and mr_pose_tool_cheat_sheet and mr_info and mr_pose_tool_cursor and mr_pose_tool then
		self.scriptValidated = true
	else
		local alertTitleText = 'Some script files are missing'
		local alertText = ''
		local howToFixText = 'Please download the script using the \"Download for Install Script\" button and install all script files.'
		local linkText = self:Localize('Script link')
		if not utilities then
			alertText = 'The file mr_utilities.lua is missing at '..mohoPath..'\\Scripts\\Utility\\'
			if not isWindows then
				alertText = 'The file mr_utilities.lua is missing at '..mohoPath..'/Scripts/Utility/'
			end
			local alert = LM.GUI.Alert(LM.GUI.ALERT_WARNING, alertTitleText, alertText.."\n".."\n"..howToFixText.."\n".."\n", linkText, 'Copy link to clipboard', 'Close')
			self.scriptValidated = false
			if alert == 0 then
				moho:CopyText(linkText)
			end
			self.scriptValidated = false
			return
		end
		if utilitiesVersion < 1.1 then
			if not isWindows then
				alertText = 'The version of mr_utilities.lua is '..utilitiesVersion..'. Version 1.1 or higher required.'.."\n"..'The file mr_utilities.lua is located at '..mohoPath..'/Scripts/Utility/'
			end
			local alert = LM.GUI.Alert(LM.GUI.ALERT_WARNING, alertTitleText, alertText.."\n".."\n"..howToFixText.."\n".."\n", linkText, 'Copy link to clipboard', 'Close')
			self.scriptValidated = false
			if alert == 0 then
				moho:CopyText(linkText)
			end
			self.scriptValidated = false
			return
		end
		
		if isWindows then
			if not font then
				alertText = 'The file hv_font.lua is missing at '..mohoPath..'\\Scripts\\Utility\\'.."\n"
			end
			
			if not mr_pose_tool then
				alertText = alertText..'The file mr_pose_tool.png is missing at '..mohoPath..'\\Scripts\\Tool\\'.."\n"
			end
			if not mr_pose_tool_cursor then
				alertText = alertText..'The file mr_pose_tool_cursor.png is missing at '..mohoPath..'\\Scripts\\Tool\\'.."\n"
			end
		else
			if not font then
				alertText = 'The file hv_font.lua is missing at '..mohoPath..'/Scripts/Utility/'.."\n"
			end
			
			if not mr_pose_tool then
				alertText = alertText..'The file mr_pose_tool.png is missing at '..mohoPath..'/Scripts/Tool/'.."\n"
			end
			if not mr_pose_tool_cursor then
				alertText = alertText..'The file mr_pose_tool_cursor.png is missing at '..mohoPath..'/Scripts/Tool/'.."\n"
			end
		end
		
		if not mr_mb_cursor then
			alertText = alertText..'The file mr_mb_cursor.png is missing at '..filePath.."\n"
		end
		if not mr_mj_cursor then
			alertText = alertText..'The file mr_mj_cursor.png is missing at '..filePath.."\n"
		end
		if not mr_select_bone_layer then
			alertText = alertText..'The file mr_select_bone_layer.png is missing at '..filePath.."\n"
		end
		if not mr_rotate then
			alertText = alertText..'The file mr_rotate.png is missing at '..filePath.."\n"
		end
		if not mr_scale then
			alertText = alertText..'The file mr_scale.png is missing at '..filePath.."\n"
		end
		if not mr_translate then
			alertText = alertText..'The file mr_translate.png is missing at '..filePath.."\n"
		end
		if not mr_toggle_panel then
			alertText = alertText..'The file mr_toggle_panel.png is missing at '..filePath.."\n"
		end
		if not mr_pose_tool_cheat_sheet then
			alertText = alertText..'The file mr_pose_tool_cheat_sheet.png is missing at '..filePath.."\n"
		end
		if not mr_info then
			alertText = alertText..'The file mr_info.png is missing at '..filePath.."\n"
		end

		alertText = alertText.."\n"
		local alert = LM.GUI.Alert(LM.GUI.ALERT_WARNING, alertTitleText, alertText..howToFixText, linkText, 'Copy link to clipboard', 'Close')
		self.scriptValidated = false
		if alert == 0 then
			moho:CopyText(linkText)
		end
		self.scriptValidated = false
		return
	end
end

function MR_PoseTool:ReverseIkDirection(moho)
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	self:PrepareFollowBones(moho)
	self.ikBonesList.reverseList = {}
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			for b=1, #self.ikBonesList.id do
				if self.ikBonesList.startBone[b] == i or self.ikBonesList.endBone[b] == i then
					self.ikBonesList.reverseList[b] = true
				end
			end
		end
	end

	self:AdjustFollowAndLockBones(moho)
	skel:UpdateBoneMatrix()
	moho.layer:UpdateCurFrame()
end

function MR_PoseTool:PrepareFollowBones(moho)
	if self.bonesDataActive then
		local skel = moho:Skeleton()
		if skel == nil then
			return
		end
	
		self.ikBonesList.reverseList = {}
		if #self.lockAngleList > 0 and self.bonesDataActiveA then
			self:ValidateLockList(moho)
			self.lockedBonesSBAngleValuesP = {}
			self.lockedBonesSBAngleValuesN = {}
			self.lockBonesParentStartAngle = {}
			self.lockBonesLastParentTipVec = {}
			self.lockBonesLastParentBaseVec = {}
			self.lockAngleBaked = {}
			
			for l=1, #self.lockAngleList do
				local lBone = skel:Bone(self.lockAngleList[l])
				if lBone then
					if lBone.fParent > -1 then
						local parentBoneTipPos = LM.Vector2:new_local()
						local parentBoneBasePos = LM.Vector2:new_local()
						local parentBone = skel:Bone(lBone.fParent)
						parentBoneBasePos:Set(0, 0)
						
						if (parentBone:IsZeroLength()) then
							parentBoneTipPos:Set(0.1, 0)
						else
							if lBone:IsZeroLength() then
								parentBoneTipPos:Set(0.1, 0)
							else
								parentBoneTipPos:Set(lBone.fLength, 0)
							end
						end
						
						if moho.frame == 0 then
							parentBone.fRestMatrix:Transform(parentBoneBasePos)
							parentBone.fRestMatrix:Transform(parentBoneTipPos)
						else
							parentBone.fMovedMatrix:Transform(parentBoneBasePos)
							parentBone.fMovedMatrix:Transform(parentBoneTipPos)
						end
						
						lBone.fTempAngle = lBone.fAnimAngle:GetValue(moho.layerFrame)
						
						self.lockedBonesSBAngleValuesP[l] = lBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
						self.lockedBonesSBAngleValuesN[l] = lBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
						self.lockBonesLastParentTipVec[l] = parentBoneTipPos
						self.lockBonesLastParentBaseVec[l] = parentBoneBasePos
						self.lockBonesParentStartAngle[l] = 0
						self.lockAngleBaked[l] = false
					end
				end
			end
		end
		
		if #self.lockPosList > 0 and self.bonesDataActiveP then
			self.lockedBonesSBPosValuesP = {}
			self.lockedBonesSBPosValuesN = {}
			self.lockedBonesPos = {}
			self.lockedBonesDeltaPos = {}
			self.lockPosBaked = {}
			for l=1, #self.lockPosList do
				local lBone = skel:Bone(self.lockPosList[l])
				if lBone then
					local bonePos = LM.Vector2:new_local()
					bonePos:Set(0, 0)
					
					if moho.frame == 0 then
						lBone.fRestMatrix:Transform(bonePos)
					else
						lBone.fMovedMatrix:Transform(bonePos)
					end
					
					self.lockPosBaked[l] = false
					self.lockedBonesDeltaPos[l] = lBone.fPos - lBone.fAnimPos:GetValue(moho.layerFrame)
					self.lockedBonesPos[l] = bonePos
					self.lockedBonesSBPosValuesP[l] = lBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
					self.lockedBonesSBPosValuesN[l] = lBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
				end
			end
		end
		
		if #self.followBonesList.id > 0 and self.bonesDataActiveF then
			self:ValidateFollowList(moho)
			self.followBonesDataList = {}
			self.followBonesDataList.sBValuesP = {}
			self.followBonesDataList.sBValuesN = {}
			self.followBonesDataList.sBValuesBakedS = {}
			self.followBonesDataList.scaleDelta = {}
			self.followBonesDataList.targetPos = {}
			self.followBonesDataList.distance = {}
			self.followBonesDataList.startAngle = {}
			self.followBonesDataList.lastVec = {}
			self.followBonesDataList.angleDelta = {}
			self.followBonesDataList.lastParentBaseVec = {}
			self.followBonesDataList.lastParentTipVec = {}
			self.followBonesDataList.parentStartAngle = {}
			self.followBonesDataList.bakedA = {}
			self.followBonesDataList.bakedS = {}
			self.followBonesDataList.FAngleP = {}
			self.followBonesDataList.FAngleN = {}
			self.followBonesDataList.block = {}
			for b=1, #self.followBonesList.id do
				local startFollowBone = skel:Bone(self.followBonesList.startBone[b])
				local endFollowBone = skel:Bone(self.followBonesList.endBone[b])
				if startFollowBone and endFollowBone then
					local boneTipPos = LM.Vector2:new_local()
					local boneBasePos = LM.Vector2:new_local()
					local valuesPLis = {}
					local valuesNLis = {}
					local scaleDeltaList = {}
					local bakedSList = {}
					local block = false
					for i=1, #self.followBonesList.id[b] do
						local fBone = skel:Bone(self.followBonesList.id[b][i])
						if fBone then
							if self.secondBoneID < 0 then
								if fBone.fSelected then
									block = true
								end
							else
								if self.followBonesList.id[b][i] == self.secondBoneID then
									block = true
								end
							end

							fBone.fTempScale = fBone.fScale
							table.insert(valuesPLis, fBone.fAnimScale:GetValue(moho.layerFrame - self.interval))
							table.insert(valuesNLis, fBone.fAnimScale:GetValue(moho.layerFrame + self.interval))
							table.insert(scaleDeltaList, fBone.fScale - fBone.fAnimScale:GetValue(moho.layerFrame))
							table.insert(bakedSList, false)
						end
					end
					
					self.followBonesDataList.sBValuesP[b] = valuesPLis
					self.followBonesDataList.sBValuesN[b] = valuesNLis
					self.followBonesDataList.scaleDelta[b] = scaleDeltaList
					self.followBonesDataList.sBValuesBakedS[b] = bakedSList
					self.followBonesDataList.block[b] = block
					
					boneBasePos:Set(0, 0)
					if (startFollowBone:IsZeroLength()) then
						boneTipPos:Set(0.1, 0)
					else
						boneTipPos:Set(endFollowBone.fLength, 0)
					end
					
					if moho.frame == 0 then
						startFollowBone.fRestMatrix:Transform(boneBasePos)
						endFollowBone.fRestMatrix:Transform(boneTipPos)
					else
						startFollowBone.fMovedMatrix:Transform(boneBasePos)
						endFollowBone.fMovedMatrix:Transform(boneTipPos)
					end
					self.followBonesDataList.targetPos[b] = boneTipPos
					
					self.followBonesDataList.distance[b] = MR_Utilities:GetDistance(boneBasePos, boneTipPos)
					self.followBonesDataList.startAngle[b] = 0
					
					self.followBonesDataList.lastVec[b] = boneBasePos
					startFollowBone.fTempAngle = startFollowBone.fAnimAngle:GetValue(moho.layerFrame)
					local followBoneActualAngle = startFollowBone.fAngle
					self.followBonesDataList.angleDelta[b] = followBoneActualAngle - startFollowBone.fAnimAngle:GetValue(moho.layerFrame)
					
					if startFollowBone.fParent > -1 then
						local parentBoneTipPos = LM.Vector2:new_local()
						local parentBoneBasePos = LM.Vector2:new_local()
						local parentBone = skel:Bone(startFollowBone.fParent)
						parentBoneBasePos:Set(0, 0)
						
						if (parentBone:IsZeroLength()) then
							parentBoneTipPos:Set(0.1, 0)
						else
							parentBoneTipPos:Set(endFollowBone.fLength, 0)
						end
						
						if moho.frame == 0 then
							parentBone.fRestMatrix:Transform(parentBoneBasePos)
							parentBone.fRestMatrix:Transform(parentBoneTipPos)
						else
							parentBone.fMovedMatrix:Transform(parentBoneBasePos)
							parentBone.fMovedMatrix:Transform(parentBoneTipPos)
						end
						self.followBonesDataList.lastParentBaseVec[b] = parentBoneBasePos
						self.followBonesDataList.lastParentTipVec[b] = parentBoneTipPos
						self.followBonesDataList.parentStartAngle[b] = 0
					end
					self.followBonesDataList.bakedA[b] = false
					self.followBonesDataList.bakedS[b] = false
					self.followBonesDataList.FAngleP[b] = startFollowBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
					self.followBonesDataList.FAngleN[b] = startFollowBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
				end
			end
		end
		
		if #self.ikBonesList.id > 0 and self.bonesDataActiveIK then
			self:ValidateIkList(moho)
			self.ikBonesDataList = {}
			self.ikBonesDataList.initialDirection = {}
			
			self.ikBonesDataList.startBoneLength = {}
			self.ikBonesDataList.endtBoneLength = {}

			self.ikBonesDataList.endBoneTipPos = {}

			self.ikBonesDataList.startAngleDelta = {}
			self.ikBonesDataList.endAngleDelta = {}
			
			self.ikBonesDataList.startBoneBakedA = {}
			self.ikBonesDataList.startBoneFAngleP = {}
			self.ikBonesDataList.startBoneFAngleN = {}
			
			self.ikBonesDataList.endBoneBakedA = {}
			self.ikBonesDataList.endBoneFAngleP = {}
			self.ikBonesDataList.endBoneFAngleN = {}
			
			self.ikBonesDataList.startBoneBakedS = {}
			self.ikBonesDataList.startBoneFScaleP = {}
			self.ikBonesDataList.startBoneFScaleN = {}
			
			self.ikBonesDataList.endBoneBakedS = {}
			self.ikBonesDataList.endBoneFScaleP = {}
			self.ikBonesDataList.endBoneFScaleN = {}
			
			self.ikBonesDataList.startBoneScaleDelta = {}
			self.ikBonesDataList.endBoneScaleDelta = {}
			
			self.ikBonesDataList.needKey = {}
			
			self.ikBonesDataList.block = {}
			for b=1, #self.ikBonesList.id do
				local startIkBone = skel:Bone(self.ikBonesList.startBone[b])
				local endIkBone = skel:Bone(self.ikBonesList.endBone[b])
				if startIkBone and endIkBone then
					local endBoneTipPos = LM.Vector2:new_local()
					local startBoneTipPos = LM.Vector2:new_local()
					local startBoneBasePos = LM.Vector2:new_local()
					local endBoneBasePos = LM.Vector2:new_local()
					local valuesPLis = {}
					local valuesNLis = {}
					local scaleDeltaList = {}
					local block = false
					for i=1, #self.ikBonesList.id[b] do
						local fBone = skel:Bone(self.ikBonesList.id[b][i])
						if fBone then
							if self.secondBoneID < 0 then
								if fBone.fSelected then
									block = true
								end
							else
								if self.ikBonesList.id[b][i] == self.secondBoneID then
									block = true
								end
							end
						end
					end
					
					self.ikBonesDataList.block[b] = block
					
					startBoneBasePos:Set(0, 0)
					if (startIkBone:IsZeroLength()) then
						endBoneTipPos:Set(0.1, 0)
					else
						endBoneTipPos:Set(endIkBone.fLength, 0)
					end
					
					startBoneTipPos:Set(startIkBone.fLength, 0)
					endBoneBasePos:Set(0, 0)
					
					if moho.frame == 0 then
						startIkBone.fRestMatrix:Transform(startBoneBasePos)
						endIkBone.fRestMatrix:Transform(endBoneTipPos)
						startIkBone.fRestMatrix:Transform(startBoneTipPos)
						endIkBone.fRestMatrix:Transform(endBoneBasePos)
					else
						startIkBone.fMovedMatrix:Transform(startBoneBasePos)
						endIkBone.fMovedMatrix:Transform(endBoneTipPos)
						startIkBone.fMovedMatrix:Transform(startBoneTipPos)
						endIkBone.fMovedMatrix:Transform(endBoneBasePos)
					end
					
					self.ikBonesDataList.initialDirection[b] = MR_Utilities:GetDirection(startBoneBasePos, endBoneBasePos, endBoneTipPos)
					
					self.ikBonesDataList.endBoneTipPos[b] = endBoneTipPos
					self.ikBonesDataList.startBoneLength[b] = MR_Utilities:GetDistance(startBoneBasePos, endBoneBasePos)
					self.ikBonesDataList.endtBoneLength[b] = MR_Utilities:GetDistance(endBoneBasePos, endBoneTipPos)
					self.ikBonesDataList.needKey[b] = false
					
					startIkBone.fTempAngle = startIkBone.fAnimAngle:GetValue(moho.layerFrame)
					endIkBone.fTempAngle = startIkBone.fAnimAngle:GetValue(moho.layerFrame)
					local ikStartBoneActualAngle = startIkBone.fAngle
					local ikEndBoneActualAngle = endIkBone.fAngle
					self.ikBonesDataList.startAngleDelta[b] = ikStartBoneActualAngle - startIkBone.fAnimAngle:GetValue(moho.layerFrame)
					self.ikBonesDataList.endAngleDelta[b] = ikEndBoneActualAngle - endIkBone.fAnimAngle:GetValue(moho.layerFrame)
					
					self.ikBonesDataList.startBoneBakedA[b] = false
					self.ikBonesDataList.startBoneFAngleP[b] = startIkBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
					self.ikBonesDataList.startBoneFAngleN[b] = startIkBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
					
					self.ikBonesDataList.endBoneBakedA[b] = false
					self.ikBonesDataList.endBoneFAngleP[b] = endIkBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
					self.ikBonesDataList.endBoneFAngleN[b] = endIkBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
					
					if self.boneStretching and self.ikBonesList.stretching[b] then
						self.ikBonesDataList.startBoneBakedS[b] = false
						self.ikBonesDataList.startBoneFScaleP[b] = startIkBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
						self.ikBonesDataList.startBoneFScaleN[b] = startIkBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
						
						self.ikBonesDataList.endBoneBakedS[b] = false
						self.ikBonesDataList.endBoneFScaleP[b] = endIkBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
						self.ikBonesDataList.endBoneFScaleN[b] = endIkBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
					
						startIkBone.fTempScale = startIkBone.fScale
						endIkBone.fTempScale = endIkBone.fScale
						
						self.ikBonesDataList.startBoneScaleDelta[b] = startIkBone.fScale - startIkBone.fAnimScale:GetValue(moho.layerFrame)
						self.ikBonesDataList.endBoneScaleDelta[b] = endIkBone.fScale - endIkBone.fAnimScale:GetValue(moho.layerFrame)
					end
				end
			end
		end
		
		self.followLockedBonesList = {}
		self.followLockedBonesList.id = {}
		self.followLockedBonesList.listIndex = {}
		self.followLockedBonesList.list = {} -- 1 follow, 2 lock angle, 3 lock pos
		
		if self.bonesDataActiveF then
			for b=1, #self.followBonesList.id do
				table.insert(self.followLockedBonesList.id, self.followBonesList.id[b][1])
				table.insert(self.followLockedBonesList.listIndex, b)
				table.insert(self.followLockedBonesList.list, 1)
			end
		end
		
		if self.bonesDataActiveA then
			for b=1, #self.lockAngleList do
				table.insert(self.followLockedBonesList.id, self.lockAngleList[b])
				table.insert(self.followLockedBonesList.listIndex, b)
				table.insert(self.followLockedBonesList.list, 2)
			end
		end
		
		if self.bonesDataActiveP then
			for b=1, #self.lockPosList do
				table.insert(self.followLockedBonesList.id, self.lockPosList[b])
				table.insert(self.followLockedBonesList.listIndex, b)
				table.insert(self.followLockedBonesList.list, 3)
			end
		end
		
		if self.bonesDataActiveIK then
			for b=1, #self.ikBonesList.id do
				table.insert(self.followLockedBonesList.id, self.ikBonesList.id[b][1])
				table.insert(self.followLockedBonesList.listIndex, b)
				table.insert(self.followLockedBonesList.list, 4)
			end
		end
		
		local isChanges = false
		
		repeat
			isChanges = false
			for i, y in ipairs(self.followLockedBonesList.id) do
				local myBone = skel:Bone(self.followLockedBonesList.id[i])
				if myBone.fParent > -1 then
					local newParentId = myBone.fParent
					for a, t in ipairs(self.followLockedBonesList.id) do
						if newParentId == self.followLockedBonesList.id[a] then
							if i < a then
								isChanges = true
								self.followLockedBonesList.id[i], self.followLockedBonesList.id[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.id, i, a)
								self.followLockedBonesList.listIndex[i], self.followLockedBonesList.listIndex[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.listIndex, i, a)
								self.followLockedBonesList.list[i], self.followLockedBonesList.list[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.list, i, a)
								break
							end	
						else
							local nextBone = skel:Bone(newParentId)
							repeat 
								local prevBone = nextBone
								for b, g in ipairs(self.followLockedBonesList.id) do
									if prevBone.fParent == self.followLockedBonesList.id[b] then
										if i < b then
											isChanges = true
											self.followLockedBonesList.id[i], self.followLockedBonesList.id[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.id, i, b)
											self.followLockedBonesList.listIndex[i], self.followLockedBonesList.listIndex[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.listIndex, i, b)
											self.followLockedBonesList.list[i], self.followLockedBonesList.list[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.list, i, b)
										end	
									end		
								end
								if nextBone.fParent > -1 then
									nextBone = skel:Bone(nextBone.fParent)
								end
							until nextBone == prevBone
						end
					end
				end	
			end	
		until isChanges == false
	end
end

function MR_PoseTool:GenerateColors(moho)
	local vc1 = LM.ColorVector:new_local()
	local vc2 = LM.ColorVector:new_local()
	vc1:Set(MOHO.MohoGlobals.SelCol)
	vc2:Set(MOHO.MohoGlobals.BackCol)
	
	local whiteColor = LM.rgb_color:new_local()
	whiteColor.r = 255
	whiteColor.g = 255
	whiteColor.b = 255
	whiteColor.a = 255 * self.handleFillOpacity
	
	vc1 = (vc1 + vc2) / 2
	local fillCol = vc1:AsColorStruct()
	fillCol.a = 255 * self.handleFillOpacity
	
	if self.useCustomColors then
		self.colorTranslateStroke = LM.rgb_color:new_local()
		self.colorTranslateStroke.r = self.colorStrokeTranslateHandleR
		self.colorTranslateStroke.g = self.colorStrokeTranslateHandleG
		self.colorTranslateStroke.b = self.colorStrokeTranslateHandleB
		self.colorTranslateStroke.a = 255 * self.handleStrokeOpacity
		
		self.colorTranslateFill = LM.rgb_color:new_local()
		self.colorTranslateFill.r = self.colorFillTranslateHandleR
		self.colorTranslateFill.g = self.colorFillTranslateHandleG
		self.colorTranslateFill.b = self.colorFillTranslateHandleB
		self.colorTranslateFill.a = 255 * self.handleFillOpacity
		
		self.colorTranslateFillHL = LM.rgb_color:new_local()
		self.colorTranslateFillHL.r = ((self.colorTranslateFill.r * 3) + whiteColor.r) / 4
		self.colorTranslateFillHL.g = ((self.colorTranslateFill.g * 3) + whiteColor.g) / 4
		self.colorTranslateFillHL.b = ((self.colorTranslateFill.b * 3) + whiteColor.b) / 4
		self.colorTranslateFillHL.a = 255 * self.handleFillOpacity
		
		self.colorScaleStroke = LM.rgb_color:new_local()
		self.colorScaleStroke.r = self.colorStrokeScaleHandleR
		self.colorScaleStroke.g = self.colorStrokeScaleHandleG
		self.colorScaleStroke.b = self.colorStrokeScaleHandleB
		self.colorScaleStroke.a = 255 * self.handleStrokeOpacity

		self.colorScaleFill = LM.rgb_color:new_local()
		self.colorScaleFill.r = self.colorFillScaleHandleR
		self.colorScaleFill.g = self.colorFillScaleHandleG
		self.colorScaleFill.b = self.colorFillScaleHandleB
		self.colorScaleFill.a = 255 * self.handleFillOpacity
		
		self.colorScaleFillHL = LM.rgb_color:new_local()
		self.colorScaleFillHL.r = ((self.colorScaleFill.r * 3) + whiteColor.r) / 4
		self.colorScaleFillHL.g = ((self.colorScaleFill.g * 3) + whiteColor.g) / 4
		self.colorScaleFillHL.b = ((self.colorScaleFill.b * 3) + whiteColor.b) / 4
		self.colorScaleFillHL.a = 255 * self.handleFillOpacity

		self.colorMoveJointStroke = LM.rgb_color:new_local()
		self.colorMoveJointStroke.r = self.colorStrokeMoveJointHandleR
		self.colorMoveJointStroke.g = self.colorStrokeMoveJointHandleG
		self.colorMoveJointStroke.b = self.colorStrokeMoveJointHandleB
		self.colorMoveJointStroke.a = 255 * self.handleStrokeOpacity

		self.colorMoveJointFill = LM.rgb_color:new_local()
		self.colorMoveJointFill.r = self.colorFillMoveJointHandleR
		self.colorMoveJointFill.g = self.colorFillMoveJointHandleG
		self.colorMoveJointFill.b = self.colorFillMoveJointHandleB
		self.colorMoveJointFill.a = 255 * self.handleFillOpacity
		
		self.colorMoveJointFillHL = LM.rgb_color:new_local()
		self.colorMoveJointFillHL.r = ((self.colorMoveJointFill.r * 3) + whiteColor.r) / 4
		self.colorMoveJointFillHL.g = ((self.colorMoveJointFill.g * 3) + whiteColor.g) / 4
		self.colorMoveJointFillHL.b = ((self.colorMoveJointFill.b * 3) + whiteColor.b) / 4
		self.colorMoveJointFillHL.a = 255 * self.handleFillOpacity

		self.colorManipulateStroke = LM.rgb_color:new_local()
		self.colorManipulateStroke.r = self.colorStrokeManipulateHandleR
		self.colorManipulateStroke.g = self.colorStrokeManipulateHandleG
		self.colorManipulateStroke.b = self.colorStrokeManipulateHandleB
		self.colorManipulateStroke.a = 255 * self.handleStrokeOpacity

		self.colorManipulateFill = LM.rgb_color:new_local()
		self.colorManipulateFill.r = self.colorFillManipulateHandleR
		self.colorManipulateFill.g = self.colorFillManipulateHandleG
		self.colorManipulateFill.b = self.colorFillManipulateHandleB
		self.colorManipulateFill.a = 255 * self.handleFillOpacity
		
		self.colorManipulateFillHL = LM.rgb_color:new_local()
		self.colorManipulateFillHL.r = ((self.colorManipulateFill.r * 3) + whiteColor.r) / 4
		self.colorManipulateFillHL.g = ((self.colorManipulateFill.g * 3) + whiteColor.g) / 4
		self.colorManipulateFillHL.b = ((self.colorManipulateFill.b * 3) + whiteColor.b) / 4
		self.colorManipulateFillHL.a = 255 * self.handleFillOpacity
	else
		self.colorTranslateStroke = LM.rgb_color:new_local()
		self.colorTranslateStroke.r = MOHO.MohoGlobals.SelCol.r
		self.colorTranslateStroke.g = MOHO.MohoGlobals.SelCol.g
		self.colorTranslateStroke.b = MOHO.MohoGlobals.SelCol.b
		self.colorTranslateStroke.a = 255 * self.handleStrokeOpacity
		
		self.colorTranslateFill = LM.rgb_color:new_local()
		self.colorTranslateFill.r = fillCol.r
		self.colorTranslateFill.g = fillCol.g
		self.colorTranslateFill.b = fillCol.b
		self.colorTranslateFill.a = 255 * self.handleFillOpacity
		
		self.colorTranslateFillHL = LM.rgb_color:new_local()
		self.colorTranslateFillHL.r = ((self.colorTranslateFill.r * 3) + whiteColor.r) / 4
		self.colorTranslateFillHL.g = ((self.colorTranslateFill.g * 3) + whiteColor.g) / 4
		self.colorTranslateFillHL.b = ((self.colorTranslateFill.b * 3) + whiteColor.b) / 4
		self.colorTranslateFillHL.a = 255 * self.handleFillOpacity
		
		self.colorScaleStroke = LM.rgb_color:new_local()
		self.colorScaleStroke.r = MOHO.MohoGlobals.SelCol.r
		self.colorScaleStroke.g = MOHO.MohoGlobals.SelCol.g
		self.colorScaleStroke.b = MOHO.MohoGlobals.SelCol.b
		self.colorScaleStroke.a = 255 * self.handleStrokeOpacity

		self.colorScaleFill = LM.rgb_color:new_local()
		self.colorScaleFill.r = fillCol.r
		self.colorScaleFill.g = fillCol.g
		self.colorScaleFill.b = fillCol.b
		self.colorScaleFill.a = 255 * self.handleFillOpacity
		
		self.colorScaleFillHL = LM.rgb_color:new_local()
		self.colorScaleFillHL.r = ((self.colorScaleFill.r * 3) + whiteColor.r) / 4
		self.colorScaleFillHL.g = ((self.colorScaleFill.g * 3) + whiteColor.g) / 4
		self.colorScaleFillHL.b = ((self.colorScaleFill.b * 3) + whiteColor.b) / 4
		self.colorScaleFillHL.a = 255 * self.handleFillOpacity

		self.colorMoveJointFill = LM.rgb_color:new_local()
		self.colorMoveJointFill.r = 255
		self.colorMoveJointFill.g = 189
		self.colorMoveJointFill.b = 46
		self.colorMoveJointFill.a = 255 * self.handleFillOpacity

		self.colorMoveJointStroke = LM.rgb_color:new_local()
		self.colorMoveJointStroke.r = (self.colorMoveJointFill.r + (MOHO.MohoGlobals.SelCol.r * 2)) / 3
		self.colorMoveJointStroke.g = (self.colorMoveJointFill.g + (MOHO.MohoGlobals.SelCol.g * 2)) / 3
		self.colorMoveJointStroke.b = (self.colorMoveJointFill.b + (MOHO.MohoGlobals.SelCol.b * 2)) / 3
		self.colorMoveJointStroke.a = 255 * self.handleStrokeOpacity
		
		self.colorMoveJointFillHL = LM.rgb_color:new_local()
		self.colorMoveJointFillHL.r = ((self.colorMoveJointFill.r * 3) + whiteColor.r) / 4
		self.colorMoveJointFillHL.g = ((self.colorMoveJointFill.g * 3) + whiteColor.g) / 4
		self.colorMoveJointFillHL.b = ((self.colorMoveJointFill.b * 3) + whiteColor.b) / 4
		self.colorMoveJointFillHL.a = 255 * self.handleFillOpacity

		self.colorManipulateFill = LM.rgb_color:new_local()
		self.colorManipulateFill.r = 255
		self.colorManipulateFill.g = 189
		self.colorManipulateFill.b = 46
		self.colorManipulateFill.a = 255 * self.handleFillOpacity

		self.colorManipulateStroke = LM.rgb_color:new_local()
		self.colorManipulateStroke.r = (self.colorManipulateFill.r + (MOHO.MohoGlobals.SelCol.r * 2)) / 3
		self.colorManipulateStroke.g = (self.colorManipulateFill.g + (MOHO.MohoGlobals.SelCol.g * 2)) / 3
		self.colorManipulateStroke.b = (self.colorManipulateFill.b + (MOHO.MohoGlobals.SelCol.b * 2)) / 3
		self.colorManipulateStroke.a = 255 * self.handleStrokeOpacity
		
		self.colorManipulateFillHL = LM.rgb_color:new_local()
		self.colorManipulateFillHL.r = ((self.colorManipulateFill.r * 3) + whiteColor.r) / 4
		self.colorManipulateFillHL.g = ((self.colorManipulateFill.g * 3) + whiteColor.g) / 4
		self.colorManipulateFillHL.b = ((self.colorManipulateFill.b * 3) + whiteColor.b) / 4
		self.colorManipulateFillHL.a = 255 * self.handleFillOpacity
	end
	
	self.colorHighlightBone = LM.rgb_color:new_local()
	if self.useHighlightCustomColor then
		self.colorHighlightBone.r = self.highlightCustomColorR
		self.colorHighlightBone.g = self.highlightCustomColorG
		self.colorHighlightBone.b = self.highlightCustomColorB
		self.colorHighlightBone.a = 255 * self.highlightOpacity
	else
		self.colorHighlightBone.r = MOHO.MohoGlobals.SelCol.r
		self.colorHighlightBone.g = MOHO.MohoGlobals.SelCol.g
		self.colorHighlightBone.b = MOHO.MohoGlobals.SelCol.b
		self.colorHighlightBone.a = 255 * self.highlightOpacity
	end

	self.colorsGenerated = true
	self.colorFollowBones = LM.rgb_color:new_local()
	self.colorFollowBones.r = self.colorFollowBonesR
	self.colorFollowBones.g = self.colorFollowBonesG
	self.colorFollowBones.b = self.colorFollowBonesB
	self.colorFollowBones.a = self.colorFollowBonesA
	
	self.colorIkBones = LM.rgb_color:new_local()
	self.colorIkBones.r = 146
	self.colorIkBones.g = 31
	self.colorIkBones.b = 131
	self.colorIkBones.a = 255
	
	self.lockAngleColor = LM.rgb_color:new_local()
	self.lockAngleColor.r = 255
	self.lockAngleColor.g = 68 
	self.lockAngleColor.b = 68 
	self.lockAngleColor.a = 255
	
	self.lockPosColor = LM.rgb_color:new_local()
	self.lockPosColor.r = 255
	self.lockPosColor.g = 192
	self.lockPosColor.b = 0  
	self.lockPosColor.a = 255
	
	self.iconColorBack = LM.rgb_color:new_local()
	self.iconColorBack.r = 255
	self.iconColorBack.g = 255
	self.iconColorBack.b = 255
	self.iconColorBack.a = 255
	
	self.iconColor = LM.rgb_color:new_local()
	self.iconColor.r = self.iconColorR
	self.iconColor.g = self.iconColorG
	self.iconColor.b = self.iconColorB
	self.iconColor.a = self.iconColorA
	
	self.disabledIconColor = LM.rgb_color:new_local()
	self.disabledIconColor.r = (self.iconColorR + self.iconColorBack.r) / 2
	self.disabledIconColor.g = (self.iconColorG + self.iconColorBack.g) / 2
	self.disabledIconColor.b = (self.iconColorB + self.iconColorBack.b) / 2
	self.disabledIconColor.a = (self.iconColorA + self.iconColorBack.a) / 2
	
	self.iconHowerColor = LM.rgb_color:new_local()
	self.iconHowerColor.r = (self.iconColorR * 3 + self.iconColorBack.r) / 4 
	self.iconHowerColor.g = (self.iconColorG * 3 + self.iconColorBack.g) / 4
	self.iconHowerColor.b = (self.iconColorB * 3 + self.iconColorBack.b) / 4
	self.iconHowerColor.a = (self.iconColorA * 3 + self.iconColorBack.a) / 4
end

function MR_PoseTool:DrawQuickMenu_1(moho, g)
	local m = LM.Matrix:new_local()
	moho.document:GetCameraMatrix(moho.layerFrame, m)
	g:Push()
	local currentScale = g:CurrentScale(false)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local offset = self.iconsDistance / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)
	local radius = self.iconsRadius
	local howerRadius = 1.1
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	local v1 = LM.Vector2:new_local()
	local v2 = LM.Vector2:new_local()
	local tooltipSizeH = 0.35 / currentScale / height
	local tooltipSizeV = 0.05 / currentScale / height
	local tooltipTextOffsetH = 0.033 / currentScale / height
	local tooltipTextOffsetV = 0.011 / currentScale / height
	local tooltipTextSize = 3 / currentScale / height
	g:SetSmoothing(true)
	
	-- set follow bones icon
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 1 then
		tooltipSizeH = 0.518 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Set follow bones chains'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	if self.graphicMenuMode == 1 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 1 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	if self.graphicMenuMode == 1 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
		
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	local arrowLen = 0.012 / currentScale / height
	local arrowWidth = 0.012 / currentScale / height
	local iconCenter = LM.Vector2:new_local()
	local offsetCenter = -0.01 / currentScale / height
	iconCenter:Set(v.x + offsetCenter, v.y)
	g:BeginShape()
	v1:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth)
	v1:Set(MR_Utilities:RotateVector2(v1, v, math.rad(45)))
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth * 2.0)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen + arrowWidth * 2.0, iconCenter.y)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y - (arrowWidth * 2.0))
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y - arrowWidth)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x-arrowLen, iconCenter.y - arrowWidth )
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	g:EndShape()
	
	-- Set IK bones
	if self.graphicMenuMode == 2 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 2 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 2 then
		tooltipSizeH = 0.316 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Set IK bones'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	
	if self.graphicMenuMode == 2 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.boneStretching then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end

	g:SetColor(self.iconColorBack)		
	
	if self.operationFailes == 2 then
		g:SetColor(255, 57, 57, 255)
	end
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 2 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	if self.operationFailes == 2 then
		g:SetColor(115, 3, 3, 255)
	end

	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end

	offsetCenter = 0.002 / currentScale / height
	iconCenter:Set(v.x + offsetCenter, v.y)
	
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(v1.x, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set((iconCenter.x - symbolWidth) + symbolHeight / 1.2, iconCenter.y + symbolHeight)
	v2:Set(v1.x, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, iconCenter.y)
	v2:Set(v2.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(((iconCenter.x - symbolWidth) + symbolHeight / 1.2), iconCenter.y)
	v2:Set(v1.x + symbolWidth, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- lock angle
	if self.graphicMenuMode == 3 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 3 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	g:SetPenWidth(3)
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 3 then
		tooltipSizeH = 0.275 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.0735 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Lock angle'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 3 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.005 / currentScale / height
	iconCenter:Set(v.x, v.y - offsetCenter)
	local boxSize = 0.015 / currentScale / height
	
	g:BeginShape()
	v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	g:EndShape()
	
	g:SetPenWidth(2)
	v1:Set((iconCenter.x - boxSize) - ((iconCenter.x - boxSize) - iconCenter.x)/3, iconCenter.y + boxSize + (0.0025 / currentScale / height))
	v2:Set(v1.x, v1.y + 0.01 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set((iconCenter.x + boxSize) + ((iconCenter.x - boxSize) - iconCenter.x)/3, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(v1.x, iconCenter.y + boxSize + (0.0025 / currentScale / height))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	local symbolWidth = 0.007 / currentScale / height
	local symbolHeight = 0.01 / currentScale / height
	g:SetColor(self.iconColorBack)
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - symbolWidth / 2, iconCenter.y - symbolHeight / 2)
	v2:Set(iconCenter.x + symbolWidth / 2, iconCenter.y - symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- lock pos
	if self.graphicMenuMode == 4 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 4 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 4 then
		tooltipSizeH = 0.318 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Lock position'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 4 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.005 / currentScale / height
	iconCenter:Set(v.x, v.y - offsetCenter)
	local boxSize = 0.015 / currentScale / height
	
	g:BeginShape()
	v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	g:EndShape()
	
	g:SetPenWidth(2)
	v1:Set((iconCenter.x - boxSize) - ((iconCenter.x - boxSize) - iconCenter.x)/3, iconCenter.y + boxSize + (0.0025 / currentScale / height))
	v2:Set(v1.x, v1.y + 0.01 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set((iconCenter.x + boxSize) + ((iconCenter.x - boxSize) - iconCenter.x)/3, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(v1.x, iconCenter.y + boxSize + (0.0025 / currentScale / height))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	local symbolWidth = 0.007 / currentScale / height
	local symbolHeight = 0.008 / currentScale / height
	g:SetColor(self.iconColorBack)
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(iconCenter.x + symbolWidth, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(v2.x, v2.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2)
	v2:Set(iconCenter.x - symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- clear icon
	if self.graphicMenuMode == 5 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 5 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 5 then
		tooltipSizeH = 0.35 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Clear selection'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 5 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.005 / currentScale / height
	iconCenter:Set(v.x, v.y)
	
	local symbolWidth = 0.008 / currentScale / height
	local symbolHeight = 0.008 / currentScale / height
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- enable icon
	local iconRadius = self.iconsRadius
	if self.graphicMenuMode == 6 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 6 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 6 then
		tooltipSizeH = 0.19 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Enable'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 6 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end

	g:FrameCirclePixelRadius(v, radius)
	
	if self.bonesDataActive then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x, v.y)
	
	g:FrameCirclePixelRadius(v, iconRadius * 0.55)
	
	g:SetColor(self.iconColorBack)	
	
	offsetCenter = 0.014 / currentScale / height
	iconCenter:Set(v.x, v.y + offsetCenter)
	local boxSize = 0.008 / currentScale / height
	
	g:BeginShape()
	v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
	g:AddLine(v1, v2)
	g:EndShape()
	
	if self.bonesDataActive then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	local symbolHeight = 0.008 / currentScale / height
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	g:Pop()
end

function MR_PoseTool:DrawQuickMenu_2(moho, g)
	local m = LM.Matrix:new_local()
	moho.document:GetCameraMatrix(moho.layerFrame, m)
	g:Push()
	local currentScale = g:CurrentScale(false)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local offset = self.iconsDistance / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)
	local radius = self.iconsRadius
	local howerRadius = 1.1
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	local v1 = LM.Vector2:new_local()
	local v2 = LM.Vector2:new_local()
	local tooltipSizeH = 0.35 / currentScale / height
	local tooltipSizeV = 0.05 / currentScale / height
	local tooltipTextOffsetH = 0.033 / currentScale / height
	local tooltipTextOffsetV = 0.011 / currentScale / height
	local tooltipTextSize = 3 / currentScale / height
	g:SetSmoothing(true)
	
	-- set single follow bones icon
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 1 then
		tooltipSizeH = 0.506 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Set single follow bones'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	if self.graphicMenuMode == 1 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 1 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	if self.graphicMenuMode == 1 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
		
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	local arrowLen = 0.012 / currentScale / height
	local arrowWidth = 0.012 / currentScale / height
	local iconCenter = LM.Vector2:new_local()
	local offsetCenter = -0.01 / currentScale / height
	iconCenter:Set(v.x + offsetCenter, v.y)
	g:BeginShape()
	v1:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth)
	v1:Set(MR_Utilities:RotateVector2(v1, v, math.rad(45)))
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth * 2.0)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen + arrowWidth * 2.0, iconCenter.y)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y - (arrowWidth * 2.0))
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x + arrowLen, iconCenter.y - arrowWidth)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x-arrowLen, iconCenter.y - arrowWidth )
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	v1:Set(v2)
	v2:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
	v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
	g:AddLine(v1, v2)
	g:EndShape()
	
	g:SetColor(self.iconColorBack)	
	
	local offsetLine = 0.003 / currentScale / height
	
	v1:Set(iconCenter.x - offsetLine * 3, iconCenter.y + offsetLine * 0.6)
	v2:Set(iconCenter.x + offsetLine * 4, iconCenter.y - offsetLine * 6)

	local markersSize = (0.004) / currentScale / height
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	-- reverse IK direction icon
	if self.graphicMenuMode == 2 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 2 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 2 then
		tooltipSizeH = 0.46 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Reverse IK direction'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 2 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	
	if self.bonesDataActive and #self.ikBonesList.id > 0 then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end

	offsetCenter = 0.002 / currentScale / height
	iconCenter:Set(v.x - offsetCenter, v.y - offsetCenter)
	
	local symbolWidth = 0.013 / currentScale / height
	local offsetS = 1.3
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolWidth)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolWidth * offsetS)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	v1:Set(iconCenter.x - symbolWidth * offsetS, iconCenter.y + symbolWidth)
	v2:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolWidth)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	iconCenter:Set(v.x + offsetCenter, v.y + offsetCenter)

	v1:Set(iconCenter.x + symbolWidth * offsetS, iconCenter.y - symbolWidth)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolWidth)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolWidth)
	v2:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolWidth * offsetS)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- set stretch bones icon
	if self.graphicMenuMode == 3 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 3 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	g:SetPenWidth(3)
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 3 then
		tooltipSizeH = 0.44 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.0735 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Set bone stretching'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 3 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 3 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end

	g:FrameCirclePixelRadius(v, radius)
	
	if self.boneStretchingIconStatus then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.0 / currentScale / height
	iconCenter:Set(v.x + offsetCenter, v.y)
	
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(v1.x, v1.y + symbolHeight * 0.8)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(v1.x + symbolHeight * 0.8, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(v1.x, v1.y - symbolHeight * 0.8)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(v1.x - symbolHeight * 0.8, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- turn off scale for all bones
	if self.graphicMenuMode == 4 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 4 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 4 then
		tooltipSizeH = 0.537 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Clear all bone stretching'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 4 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 4 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end

	g:FrameCirclePixelRadius(v, radius)
	
	g:SetColor(self.iconColor)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.0045 / currentScale / height
	iconCenter:Set(v.x - offsetCenter, v.y + offsetCenter)
	
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(v1.x, v1.y + symbolHeight * 0.8)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(v1.x + symbolHeight * 0.8, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(v1.x, v1.y - symbolHeight * 0.8)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(v1.x - symbolHeight * 0.8, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	g:SetPenWidth(2)
	
	offsetCenter = 0.009 / currentScale / height
	iconCenter:Set(v.x + offsetCenter, v.y - offsetCenter)
	
	local symbolWidth = 0.006 / currentScale / height
	local symbolHeight = 0.006 / currentScale / height
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	g:SetPenWidth(3)
	
	-- clear all icon
	if self.graphicMenuMode == 5 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 5 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 5 then
		tooltipSizeH = 0.22 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Clear all'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end

	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 5 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	g:SetColor(self.iconColor)
	
	offsetCenter = 0.005 / currentScale / height
	iconCenter:Set(v.x, v.y)
	
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
	v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	-- single bone mode icon
	local iconRadius = self.iconsRadius
	if self.graphicMenuMode == 6 then
		radius = self.iconsRadius * howerRadius
	else
		radius = self.iconsRadius
	end
	
	if self.buttonPressed == 6 then
		radius = self.iconsRadius / (howerRadius / 1.1)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 6 then
		tooltipSizeH = 0.396 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Single bone mode'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 6 then
		g:SetColor(self.iconHowerColor)
	else
		g:SetColor(self.iconColor)
	end

	g:FrameCirclePixelRadius(v, radius)
	
	if self.singleFollowBonesMode then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	offsetCenter = 0.005 / currentScale / height
	iconCenter:Set(v.x, v.y)
	
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	v1:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
	v2:Set(iconCenter.x - symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2.x, v2.y)
	v2:Set(iconCenter.x + symbolWidth, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - symbolHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	v1:Set(v2.x, v2.y)
	v2:Set(iconCenter.x - symbolWidth, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	g:Pop()
end

function MR_PoseTool:DrawQuickMenu_3(moho, g)
	local m = LM.Matrix:new_local()
	moho.document:GetCameraMatrix(moho.layerFrame, m)
	g:Push()
	currentScale = g:CurrentScale(false)
	height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local offset = self.iconsDistance * 1.05 / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)
	local radius = self.iconsRadius
	local radiusMultiplier = 1.1
	local howerRadius = 1.1
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	local v1 = LM.Vector2:new_local()
	local v2 = LM.Vector2:new_local()
	local tooltipSizeH = 0.35 / currentScale / height
	local tooltipSizeV = 0.05 / currentScale / height
	local tooltipTextOffsetH = 0.033 / currentScale / height
	local tooltipTextOffsetV = 0.011 / currentScale / height
	local tooltipTextSize = 3 / currentScale / height
	g:SetSmoothing(true)
	
	-- Multi Transform icon
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 1 then
		tooltipSizeH = 0.34 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Multi transform'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	if self.graphicMenuMode == 1 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end

	if self.buttonPressed == 1 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	local arrowLen = 0.012 / currentScale / height
	local arrowWidth = 0.012 / currentScale / height
	
	local iconCenter = LM.Vector2:new_local()
	iconCenter:Set(v.x - 0.0011 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	if self.graphicMenuMode == 1 then
		g:SetColor(255, 222, 120, 255)
	else
		g:SetColor(255, 195, 52, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	
	if self.multiTransform and self.keepSelection then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	g:SetPenWidth(2)
	
	v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.007 / currentScale / height, v1.y - 0.012 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.007 / currentScale / height, v1.y + 0.012 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	v1:Set(iconCenter.x + 0.012 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.02 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x - 0.007 / currentScale / height, v2.y)
	v2:Set(v2.x + 0.007 / currentScale / height, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	-- Keep Selection icon
	if self.graphicMenuMode == 2 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end
	
	if self.buttonPressed == 2 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 2 then
		tooltipSizeH = 0.35 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Keep selection'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 2 then
		g:SetColor(70, 148, 255, 255)
	else
		g:SetColor(14, 116, 255, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.keepSelection then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + 0.0012 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetPenWidth(2)

	v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, iconCenter.y - 0.005 / currentScale / height)
	v2:Set(v1.x + 0.01 / currentScale / height , v1.y + 0.0105 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v1.x, iconCenter.y - 0.005 / currentScale / height)
	v2:Set(v1.x + 0.01 / currentScale / height , v1.y - 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + 0.001 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
	v2:Set(v1.x  + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- lock Handle icon
	if self.graphicMenuMode == 3 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end
	
	if self.buttonPressed == 3 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	g:SetPenWidth(3)
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 3 then
		tooltipSizeH = 0.325 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.0735 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Lock handles'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 3 then
		g:SetColor(45, 243, 54, 255)
	else
		g:SetColor(19, 223, 29, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.lockHandles then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x - 0.0007 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetPenWidth(2)
	
	v1:Set(iconCenter.x - 0.0145 / currentScale / height, iconCenter.y + 0.007 / currentScale / height)
	v2:Set(v1.x, iconCenter.y - 0.013 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.010 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	v1:Set(iconCenter.x + 0.0013 / currentScale / height, iconCenter.y + 0.007 / currentScale / height)
	v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, iconCenter.y - 0.0035 / currentScale / height)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, iconCenter.y + 0.007 / currentScale / height)
	v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- Smart Bake icon
	if self.graphicMenuMode == 4 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end
	
	if self.buttonPressed == 4 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 4 then
		tooltipSizeH = 0.27 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Bake Adjacent Frames'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 4 then
		g:SetColor(211, 94, 255, 255)
	else
		g:SetColor(202, 60, 255, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.bakeAdjacentFrames then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	if MOHO.MohoGlobals.EditMultipleKeys then
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + 0.0008 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetPenWidth(2)
	
	v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	v1:Set(iconCenter.x + 0.0045 / currentScale / height, iconCenter.y - 0.0126 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.020 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y - 0.001 / currentScale / height)
	v2:Set(v1.x + 0.008 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y - 0.0075 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x + 0.011 / currentScale / height, v2.y)
	v2:Set(v1.x, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y - 0.008 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- Show Path icon
	if self.graphicMenuMode == 5 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end
	
	if self.buttonPressed == 5 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 5 then
		tooltipSizeH = 0.256 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.072 / currentScale / height
		tooltipTextOffsetV = 0.012 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x + tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Show path'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 5 then
		g:SetColor(86, 225, 255, 255)
	else
		g:SetColor(27, 203, 241, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.showPath then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + 0.00045 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetPenWidth(2)
	
	v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + 0.0045 / currentScale / height, iconCenter.y - 0.014 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.021 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y - 0.001 / currentScale / height)
	v2:Set(v1.x + 0.01 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, v1.y - 0.0075 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- Twos Mode icon
	if self.graphicMenuMode == 6 then
		radius = self.iconsRadius * radiusMultiplier * howerRadius
	else
		radius = self.iconsRadius * radiusMultiplier
	end
	
	if self.buttonPressed == 6 then
		radius = self.iconsRadius * radiusMultiplier / (howerRadius / 1.15)
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))
	
	if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 6 then
		tooltipSizeH = 0.275 / currentScale / height
		tooltipSizeV = 0.05 / currentScale / height
		tooltipTextOffsetH = 0.033 / currentScale / height
		tooltipTextOffsetV = 0.011 / currentScale / height
		tooltipTextSize = 3 / currentScale / height
		
		g:SetPenWidth(1)
		g:SetColor(255, 255, 255, 255)	
		g:BeginShape()
		v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
		v2:Set(v.x, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y + tooltipSizeV)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x - tooltipSizeH, v1.y)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(v1.x, v1.y -tooltipSizeV)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetColor(0, 0, 0, 255)	
		v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
		
		HV_Font:DrawLetters(moho, g, self:Localize('Twos mode'), tooltipTextSize, v1.x, v1.y, 0, 0)
	end
	
	g:SetColor(0, 0, 0, 75)		
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	g:FillCirclePixelRadius(v + shadowOffset, radius)
	g:SetColor(self.iconColorBack)		
	g:FillCirclePixelRadius(v, radius)
	g:SetPenWidth(3)
	
	if self.graphicMenuMode == 6 then
		g:SetColor(255, 100, 100, 255)
	else
		g:SetColor(255, 70, 70, 255)
	end
	
	g:FrameCirclePixelRadius(v, radius)
	if self.twosMode then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + 0.0018 / currentScale / height, v.y + 0.003 / currentScale / height)
	
	g:SetPenWidth(2)

	v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.02 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x - 0.007 / currentScale / height, v2.y)
	v2:Set(v2.x + 0.007 / currentScale / height, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x - 0.002 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
	v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.007 / currentScale / height, v1.y - 0.012 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x + 0.007 / currentScale / height, v1.y + 0.012 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2)
	v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	g:Pop()
end

function MR_PoseTool:DrawQuickMenu_4(moho, g)
	local m = LM.Matrix:new_local()
	moho.document:GetCameraMatrix(moho.layerFrame, m)
	g:Push()
	local currentScale = g:CurrentScale(false)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local offset = self.iconsDistance / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)
	center:Set(center.x, center.y - 0.15 / currentScale / height)
	
	local shadowCenter = LM.Vector2:new_local()
	shadowCenter:Set(self.graphicsMenuCenter)
	shadowCenter:Set(center.x, center.y - 0.008 / currentScale / height)
	
	local buttonsWidth = 0.05 / currentScale / height
	local buttonsHeight = 0.05 / currentScale / height
	local buttonHeight
	local buttonsRound = 0.02 / currentScale / height
	local howerRadius = 1.1
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	local v1 = LM.Vector2:new_local()
	local v2 = LM.Vector2:new_local()
	local tooltipSizeH = 0.35 / currentScale / height
	local tooltipSizeV = 0.05 / currentScale / height
	local tooltipTextOffsetH = 0.033 / currentScale / height
	local tooltipTextOffsetV = 0.011 / currentScale / height
	local tooltipTextSize = 3 / currentScale / height
	local symbolWidth = 0.015 / currentScale / height
	local symbolHeight = 0.015 / currentScale / height
	local offsetVec
	local iconCenter = LM.Vector2:new_local()
	local tempVec = LM.Vector2:new_local()
	
	g:SetSmoothing(true)
	
	-- shadow
	
	v:Set(shadowCenter.x - buttonsWidth - buttonsWidth / 2, shadowCenter.y)
	local cornerCenter = LM.Vector2:new_local()

	g:SetPenWidth(1)
	g:SetColor(0, 0, 0, 75)	
	
	g:BeginShape()
	v1:Set(v.x, v.y - buttonsHeight / 2)
	v2:Set(v1.x - buttonsWidth + buttonsRound / 1, v1.y)
	g:AddLine(v1, v2)

	v1:Set(v.x - buttonsWidth + buttonsRound / 1, v.y - buttonsHeight / 2)
	v2:Set(v1.x, v1.y + buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + buttonsHeight - buttonsRound * 2)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x + buttonsWidth * 4 - buttonsRound, v2.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonsHeight + buttonsRound * 2)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x - buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y)
	g:AddLine(v1, v2)
	
	g:EndShape()
	
	-- button 1
		
	if self.graphicMenuMode == 7 then
		buttonHeight = buttonsHeight * howerRadius
	else
		buttonHeight = buttonsHeight
	end
	
	if self.buttonPressed == 7 then
		buttonHeight = buttonsHeight / (howerRadius * 0.8)
	end
	
	-- fill

	v:Set(center.x - buttonsWidth - buttonsWidth / 2, center.y)
	local cornerCenter = LM.Vector2:new_local()
	
	g:SetPenWidth(1)
	g:SetColor(self.iconColorBack)	
	
	g:BeginShape()
	v1:Set(v.x, v.y - buttonHeight / 2)
	v2:Set(v1.x - buttonsWidth + buttonsRound / 1, v1.y)
	g:AddLine(v1, v2)

	v1:Set(v.x - buttonsWidth + buttonsRound / 1, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + buttonHeight - buttonsRound * 2)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y - buttonHeight)
	g:AddLine(v1, v2)
	g:EndShape()
	
	-- stroke
	
	local cornerCenter = LM.Vector2:new_local()
	
	g:SetPenWidth(3)
	g:SetColor(self.iconColor)	
	
	v1:Set(v.x, v.y - buttonHeight / 2)
	v2:Set(v1.x - buttonsWidth + buttonsRound / 1, v1.y)
	g:AddLine(v1, v2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v.x - buttonsWidth + buttonsRound / 1, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + buttonHeight - buttonsRound * 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(-22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y - buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- symbol
	
	if self.bonesDataActiveF then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x - buttonsWidth / 2, v.y)
	g:SetPenWidth(2)
	
	symbolWidth = 0.015 / currentScale / height
	symbolHeight = 0.028 / currentScale / height
	
	offsetVec = 0.0009 / currentScale / height
	iconCenter:Set(iconCenter.x - symbolWidth / 2 + offsetVec * 2, iconCenter.y - offsetVec)
	
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x, iconCenter.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y - symbolHeight / 2.5)
	v2:Set(v1.x - symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)

	-- button 2
	
	if self.graphicMenuMode == 8 then
		buttonHeight = buttonsHeight * howerRadius
	else
		buttonHeight = buttonsHeight
	end
	
	if self.buttonPressed == 8 then
		buttonHeight = buttonsHeight / (howerRadius * 0.8)
	end
	
	-- fill 2
	
	v:Set(center.x - buttonsWidth / 2, center.y)
	
	g:SetPenWidth(1)
	g:SetColor(self.iconColorBack)
	
	g:BeginShape()
	v1:Set(v.x - buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x + buttonsWidth, v1.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x - buttonsWidth, v.y - buttonHeight / 2)
	g:AddLine(v1, v2)
	g:EndShape()
	
	-- Stroke 2
	
	g:SetPenWidth(3)
	g:SetColor(self.iconColor)
	
	v1:Set(v.x - buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x + buttonsWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x - buttonsWidth, v.y - buttonHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- symbol 2
	
	if self.bonesDataActiveIK then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	g:SetPenWidth(2)
	
	offsetVec = 0.0315 / currentScale / height
	symbolWidth = 0.015 / currentScale / height
	symbolHeight = 0.028 / currentScale / height
	iconCenter:Set(v.x - buttonsWidth / 2, v.y )
	iconCenter:Set(iconCenter.x - symbolWidth / 2 + offsetVec * 0.15, iconCenter.y)
	
	v1:Set(iconCenter.x - offsetVec * 0.3, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x, iconCenter.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x, iconCenter.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y - symbolHeight / 2)
	tempVec:Set(v1)
	v2:Set(v1.x + symbolWidth, v1.y + symbolHeight / 2 - offsetVec * 0.04)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(tempVec)
	v2:Set(v1.x + symbolWidth, v1.y - symbolHeight / 2 + offsetVec * 0.04)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- button 3
	
	if self.graphicMenuMode == 9 then
		buttonHeight = buttonsHeight * howerRadius
	else
		buttonHeight = buttonsHeight
	end
	
	if self.buttonPressed == 9 then
		buttonHeight = buttonsHeight / (howerRadius * 0.8)
	end
	
	-- fill 3
	
	v:Set(center.x - buttonsWidth / 2, center.y)
	
	g:SetPenWidth(1)
	g:SetColor(self.iconColorBack)
	g:BeginShape()
	v1:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x - buttonsWidth, v1.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	g:AddLine(v1, v2)
	g:EndShape()
	
	-- stroke 3
	
	g:SetPenWidth(3)
	g:SetColor(self.iconColor)
	v1:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x - buttonsWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- symbol 3
	
	if self.bonesDataActiveA then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	g:SetPenWidth(2)
	symbolWidth = 0.02 / currentScale / height
	symbolHeight = 0.028 / currentScale / height
	
	iconCenter:Set(v.x + buttonsWidth / 2, v.y )
	iconCenter:Set(iconCenter.x - symbolWidth / 2, iconCenter.y)
	
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x + symbolWidth / 2, iconCenter.y + symbolHeight / 2)
	
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + symbolWidth / 2, iconCenter.y - symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(iconCenter.x + symbolWidth / 4 , iconCenter.y - symbolHeight * 0.1)
	v2:Set(v1.x + symbolWidth / 2, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- button 4
	
	if self.graphicMenuMode == 10 then
		buttonHeight = buttonsHeight * howerRadius
	else
		buttonHeight = buttonsHeight
	end
	
	if self.buttonPressed == 10 then
		buttonHeight = buttonsHeight / (howerRadius * 0.8)
	end
	
	-- fill 4
	
	v:Set(center.x + buttonsWidth - buttonsWidth / 2, center.y)
	
	g:SetPenWidth(1)
	g:SetColor(self.iconColorBack)
	g:BeginShape()
	v1:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x - buttonsWidth, v1.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	g:AddLine(v1, v2)
	g:EndShape()
	
	-- stroke 4
	
	g:SetPenWidth(3)
	g:SetColor(self.iconColor)
	v1:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x - buttonsWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y - buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x + buttonsWidth, v.y - buttonHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- symbol 4
	
	if self.bonesDataActiveP then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + buttonsWidth / 2, v.y )
	g:SetPenWidth(2)
	
	symbolWidth = 0.015 / currentScale / height
	symbolHeight = 0.028 / currentScale / height
	
	offsetVec = 0.0009 / currentScale / height
	iconCenter:Set(iconCenter.x - symbolWidth / 2 + offsetVec * 2, iconCenter.y - offsetVec)
	
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x, iconCenter.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y - symbolHeight / 2.5)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x - symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- button 5
	
	if self.graphicMenuMode == 11 then
		buttonHeight = buttonsHeight * howerRadius
	else
		buttonHeight = buttonsHeight
	end
	
	if self.buttonPressed == 11 then
		buttonHeight = buttonsHeight / (howerRadius * 0.8)
	end
	
	-- fill 5
	
	v:Set(center.x + buttonsWidth * 2  - buttonsWidth / 2, center.y)
	local cornerCenter = LM.Vector2:new_local()

	g:SetPenWidth(1)
	g:SetColor(self.iconColorBack)	
	
	g:BeginShape()
	v1:Set(v.x, v.y - buttonHeight / 2)
	v2:Set(v1.x + buttonsWidth - buttonsRound / 1, v1.y)
	g:AddLine(v1, v2)
	
	v1:Set(v.x + buttonsWidth - buttonsRound / 1, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + buttonHeight - buttonsRound * 2)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x - buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y)
	g:AddLine(v1, v2)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y - buttonHeight)
	g:AddLine(v1, v2)
	
	g:EndShape()
	
	-- stroke 5
	
	local cornerCenter = LM.Vector2:new_local()

	g:SetPenWidth(3)
	g:SetColor(self.iconColor)	
	
	v1:Set(v.x, v.y - buttonHeight / 2)
	v2:Set(v1.x + buttonsWidth - buttonsRound / 1, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v.x + buttonsWidth - buttonsRound / 1, v.y - buttonHeight / 2)
	v2:Set(v1.x, v1.y + buttonsRound / 1)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + buttonHeight - buttonsRound * 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x - buttonsRound, v1.y)
	cornerCenter:Set(v2)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x, v2.y)
	v2:Set(MR_Utilities:RotateVector2(v1, cornerCenter, math.rad(22.5)))
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v.x, v2.y - buttonHeight)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	-- symbol 5
	
	if self.boneStretching then
		g:SetColor(self.iconColor)
	else
		g:SetColor(self.disabledIconColor)
	end
	
	iconCenter:Set(v.x + buttonsWidth / 2, v.y )
	g:SetPenWidth(2)
	
	symbolWidth = 0.015 / currentScale / height
	symbolHeight = 0.028 / currentScale / height
	
	offsetVec = 0.0009 / currentScale / height
	iconCenter:Set(iconCenter.x - symbolWidth / 2, iconCenter.y)
	
	v1:Set(iconCenter.x, iconCenter.y - symbolHeight / 2)
	v2:Set(v1.x + symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v2.x - symbolWidth, v2.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x, v1.y + symbolHeight / 2)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
	v1:Set(v2.x, v2.y)
	v2:Set(v1.x + symbolWidth, v1.y)
	g:DrawLine(v1.x, v1.y, v2.x, v2.y)
end

function MR_PoseTool:SetBoneStretching(moho, scan)
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	if not scan then
		self:ValidateFollowList(moho)
		self:ValidateIkList(moho)
	end
	local boneStretching = false
	for i=1, #self.followBonesList.id do
		for b=1, #self.followBonesList.id[i] do
			local bone = skel:Bone(self.followBonesList.id[i][b])
			if bone.fSelected then
				if scan then
					if self.followBonesList.stretching[i] then
						boneStretching = true
						break
					end
				else
					self.followBonesList.stretching[i] = not self.boneStretchingIconStatus
					break
				end
			end
		end
	end
	for i=1, #self.ikBonesList.id do
		for b=1, #self.ikBonesList.id[i] do
			local bone = skel:Bone(self.ikBonesList.id[i][b])
			if bone.fSelected then
				if scan then
					if self.ikBonesList.stretching[i] then
						boneStretching = true
						break
					end
				else
					self.ikBonesList.stretching[i] = not self.boneStretchingIconStatus
					break
				end
			end
		end
	end
	if scan then
		self.boneStretchingIconStatus = boneStretching
	else
		self:SaveBonesData(moho.layer)
	end
end

function MR_PoseTool:PrepareToEditMultipleKeys(moho)
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	local frame = moho.layerFrame
	self.bonesKeysAngleList = {}
	self.bonesKeysPosList = {}
	self.bonesKeysScaleList = {}
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		self.bonesKeysAngleList[i] = bone.fAnimAngle:GetValue(frame)
		local posChannel = bone.fAnimPos
		if posChannel:AreDimensionsSplit() then
			local channelPosX = posChannel:DimensionChannel(0)
			local channelPosY = posChannel:DimensionChannel(1)
			self.bonesKeysPosList[i] = LM.Vector2:new_local()
			self.bonesKeysPosList[i]:Set(channelPosX:GetValue(frame), channelPosY:GetValue(frame))
		else	
			self.bonesKeysPosList[i] = posChannel:GetValue(frame)
		end
		
		self.bonesKeysScaleList[i] = bone.fAnimScale:GetValue(frame)
	end
end

function MR_PoseTool:EditMultipleKeys(moho, mode)
	local skel = moho:Skeleton()
	if skel == nil or frame == 0 then
	end
	
	local frame = moho.layerFrame
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		local angleDelta = bone.fAnimAngle:GetValue(frame) - self.bonesKeysAngleList[i]
		
		if angleDelta ~= 0 then
			self:AddDeltaToValChannel(moho, bone.fAnimAngle, angleDelta)
		end
		
		local posDelta = LM.Vector2:new_local()
		local boneChannelPos = bone.fAnimPos
		if boneChannelPos:AreDimensionsSplit() then
			local channelPosX = boneChannelPos:DimensionChannel(0)
			local channelPosY = boneChannelPos:DimensionChannel(1)
			posDelta:Set(channelPosX:GetValue(frame) - self.bonesKeysPosList[i].x, channelPosY:GetValue(frame) - self.bonesKeysPosList[i].y)
			if posDelta.x ~= 0 or posDelta.y ~= 0 then
				self:AddDeltaToValChannel(moho, channelPosX, posDelta.x)
				self:AddDeltaToValChannel(moho, channelPosY, posDelta.y)
			end
		else
			posDelta:Set(bone.fAnimPos:GetValue(frame))
			posDelta:Set(posDelta.x - self.bonesKeysPosList[i].x, posDelta.y - self.bonesKeysPosList[i].y)
			if posDelta.x ~= 0 or posDelta.y ~= 0 then
				self:AddDeltaToVec2Channel(moho, bone.fAnimPos, posDelta)
			end
		end
		
		local scaleDelta = bone.fAnimScale:GetValue(frame) - self.bonesKeysScaleList[i]
		
		if scaleDelta ~= 0 then
			if self.relativeKeyframingScale then
				local deltaPercentage = ((bone.fAnimScale:GetValue(frame) - self.bonesKeysScaleList[i]) / self.bonesKeysScaleList[i]) * 100
				local currentFrame = moho.layerFrame
				local channel = bone.fAnimScale
				for keyID = 0, channel:CountKeys() - 1 do
					local keyFrame = channel:GetKeyWhen(keyID)
					if (keyFrame > 0 and keyFrame ~= currentFrame and channel:IsKeySelectedByID(keyID)) then
						local delta = (deltaPercentage / 100) * bone.fAnimScale:GetValue(keyFrame)
						local newVal = channel:GetValue(keyFrame) + delta
						channel:SetValue(keyFrame, newVal)
					end
				end
			else
				self:AddDeltaToValChannel(moho, bone.fAnimScale, scaleDelta)
			end
		end

	end
end

function MR_PoseTool:AddDeltaToValChannel(moho, channel, delta)
	local currentFrame = moho.layerFrame
	for keyID = 0, channel:CountKeys() - 1 do
		local keyFrame = channel:GetKeyWhen(keyID)
		if (keyFrame > 0 and keyFrame ~= currentFrame and channel:IsKeySelectedByID(keyID)) then
			local newVal = channel:GetValue(keyFrame) + delta
			channel:SetValue(keyFrame, newVal)
		end
	end
end

function MR_PoseTool:AddDeltaToVec2Channel(moho, channel, delta)
	local currentFrame = moho.layerFrame
	for keyID = 0, channel:CountKeys() - 1 do
		local keyFrame = channel:GetKeyWhen(keyID)
		if (keyFrame > 0 and keyFrame ~= currentFrame and channel:IsKeySelectedByID(keyID)) then
			local newVec2 = LM.Vector2:new_local()
			newVec2:Set(channel:GetValue(keyFrame))
			newVec2:Set(newVec2.x + delta.x, newVec2.y + delta.y)
			channel:SetValue(keyFrame, newVec2)
		end
	end
end

function MR_PoseTool:GoToSkeletonLayer(moho, layer, updateToolPanel)
	if layer then
		if layer:LayerType() ~= MOHO.LT_BONE then
			local skelLayer = MR_Utilities:FindSkeletonLayer(layer)
			if skelLayer then
				moho:SetSelLayer(skelLayer)
				moho:ShowLayerInLayersPalette(skelLayer)
				if updateToolPanel then
					local drawingToolsNonZero = MOHO.MohoGlobals.DisableDrawingToolsNonZero
					if not drawingToolsNonZero then
						MOHO.MohoGlobals.DisableDrawingToolsNonZero = true
					end
					local frame = moho.frame
					self.ignoreUpdateWidgets = true
					if frame == 0 then
						moho:SetCurFrame(1)
						moho:SetCurFrame(0)
					elseif frame ~= 0 then
						moho:SetCurFrame(0)
						moho:SetCurFrame(frame)
					end
					if not drawingToolsNonZero then
						MOHO.MohoGlobals.DisableDrawingToolsNonZero = drawingToolsNonZero
					end
				end
				moho.view:DrawMe()
				moho.layer:UpdateCurFrame()
				moho:UpdateUI()
			end
		end
		self.ignoreUpdateWidgets = false
	end
end

-- **************************************************
-- Localization
-- **************************************************

function MR_PoseTool:Localize(text)
	local phrase = {}

	phrase['Description'] = 'Set up the pose of your character (hold <ctrl/cmd> or <ctrl/cmd> + <shift> to access the quick menu, <alt> for compensation of child bone transformation, <shift> for additional transformation variations)'
	phrase['UILabel'] = 'MR Pose Tool '..self:Version()
	
	phrase['Settings'] = 'Settings'
	phrase['Quick menu tooltips'] = 'Quick menu tooltips'
	phrase['Relative keyframing scale'] = 'Relative keyframing scale in %'
	phrase['RK blend smoothness:'] = 'RK blend smoothness:'
	phrase['RK blend in:'] = 'RK blend in:'
	phrase['out:'] = 'out:'
	phrase['Skeleton layers navigation'] = 'Skeleton layers navigation'
	phrase['Double-click to set keyframe'] = 'Double-click to set keyframe'
	phrase['Click and hold to reset'] = 'Click and hold to reset'
	phrase['Move target parent'] = 'Move target\'s parent'
	phrase['Block on even frames'] = 'Block on even frames'
	phrase['Block on odd frames'] = 'Block on odd frames'
	phrase['Highlight bones'] = 'Highlight bones'
	phrase['Highlight width:'] = 'Highlight width:'
	phrase['Highlight opacity:'] = 'Highlight opacity:'
	phrase['Custom'] = 'Use custom:'
	phrase['Align handles along bone'] = 'Align handles along bone'
	phrase['Handles distance:'] = 'Handles distance:'
	phrase['Handles stroke opacity:'] = 'Handles stroke opacity:'
	phrase['Handles fill opacity:'] = 'Handles fill opacity:'
	phrase['Use custom colors'] = 'Use custom colors'
	phrase['Translate handle stroke color Tooltip'] = 'Translate handle stroke color'
	phrase['Translate handle fill color Tooltip'] = 'Translate handle fill color'
	phrase['Scale handle stroke color Tooltip'] = 'Scale handle stroke color'
	phrase['Scale handle fill color Tooltip'] = 'Scale handle fill color'
	phrase['Move joint handle stroke color Tooltip'] = 'Move joint handle stroke color'
	phrase['Move joint handle fill color Tooltip'] = 'Move joint handle fill color'
	phrase['Manipulate handle stroke color Tooltip'] = 'Manipulate handle stroke color'
	phrase['Manipulate handle fill color Tooltip'] = 'Manipulate handle fill color'
	phrase['Reset colors'] = 'Reset colors'
	
	phrase['Toggle panel'] = 'Toggle panel'
	phrase['Panel size tolltip'] = ''
	phrase['Show compact panel'] = 'Show compact panel'
	phrase['Show full panel'] = 'Show full panel'
	phrase['Twos mode'] = 'Twos mode'
	phrase['Keep selection'] = 'Keep selection'
	phrase['Multi transform'] = 'Multi transform'
	phrase['Lock handles'] = 'Lock handles'
	phrase['Hide bones while moving'] = 'Hide'
	phrase['Keep previous selection'] = 'Keep previous selection'
	phrase['Bake Adjacent Frames'] = 'Smart bake'
	phrase['Interval'] = 'Interval:'
	phrase['Show path'] = 'Show path'
	phrase['Range'] = 'Range'
	phrase['Range frames:'] = 'Range frames:'
	phrase['End flip'] = 'End flip'
	phrase['Side flip'] = 'Side flip'
	phrase['Reset:'] = 'Reset:'
	phrase['A'] = 'A'
	phrase['Reset angle'] = 'Reset angle'
	phrase['T'] = 'T'
	phrase['Reset translation'] = 'Reset translation'
	phrase['S'] = 'S'
	phrase['Reset scale'] = 'Reset scale'
	phrase['X'] = 'X'
	phrase['Y'] = 'Y'
	
	phrase['Set follow bones chains'] = 'Set follow bones chains'
	phrase['Set single follow bones'] = 'Set single follow bones'
	phrase['Set IK bones'] = 'Set IK bones'
	phrase['Clear all bone stretching'] = 'Clear all bone stretching'
	phrase['Set bone stretching'] = 'Set bone stretching '
	phrase['Lock angle'] = 'Lock angle'
	phrase['Lock position'] = 'Lock position'
	phrase['Clear selection'] = 'Clear selection'
	phrase['Clear all'] = 'Clear all'
	phrase['Enable'] = 'Enable'
	phrase['Single bone mode'] = 'Single bone mode'
	phrase['Reverse IK direction'] = 'Reverse IK direction'
	
	phrase['Info'] = 'Info'
	
	phrase['Copy link to clipboard'] = 'Copy link to clipboard'
	phrase['Show more info'] = 'Show more info'
	phrase['Script link'] = 'https://mohoscripts.com/script/mr_pose_tool'

	return phrase[text]
end

Icon
MR Pose Tool
Listed

Script type: Tool

Uploaded: Aug 14 2023, 06:38

Last modified: Jul 31 2024, 18:34

Script Version: 3.2.1

Plan and polish your animation with ease!
MR Pose Tool allows you to minimize the routine and spend more effort on creativity. This script combines the tools Transform Bone, Manipulate Bones, MR Move Targeted Joint, and even more.





To work correctly the lower bone (the shin or the forearm) must not have any Y-axis translation.

Update 1.2

Change List:
1. Improved Lock Handles mode, now there's no need to deselect the current bone to select another.
2. Enhanced Align Handles Along Bone mode, now the handles do not overlap each other when the bone on the screen is small in size. This works only when all four handles are active.
3. Added the ability to customize the color and transparency of the handles.
4. Added Highlight Bones option which draws a line along the bone under the cursor, making it easier to identify which bone you will select when you click.
5. Added Double-click to Reset option, allowing you to disable this feature if it interferes.

Update 1.3

Change List:
1. Added an option that allows blocking the script on even or odd frames. This is convenient if you work in twos, so as not to create keys outside the interval.

MR Pose Tool 2.0

1. Ability to select multiple bones at once.
2. Ability to transform multiple bones at once.
3. Quick access menu to options and functions of the tool.
4. Follow bone, Lock angle, and Lock Pos features, which allow you to find the pose faster by controlling only individual body parts of the character, while maintaining the position of other parts.
5. Added Twos mode option to the panel and in the quick menu.
6. In Lock handles mode, only handles for selected bones are displayed. Previously, this only worked with one bone.
7. The Keep selection option now retains selection only if there has been bone transformation. Meaning, now you can select bones without turning off this option.

Update 2.1

Change List:
1. All information about Follow bones and Lock bones is now stored in the character layer. This allows you to switch freely between characters without needing to reassign bones each time.
2. Added the ability to enable and disable Follow bones and Lock bones for quick access without the need to constantly reassign bones. This can be done via the quick menu or by double-clicking outside the bones.
3. Pressing Ctrl + Alt in the quick menu brings up additional options. For example, you can add individual bones as Follow bones instead of chains of bones.
4. Bug fixes.

Update 2.1.6

Change List:
1. Bug fixes.

MR Pose Tool 3.0

1. The Inverse Kinematic Bones.
2. New Bone Stretching option for Follow Bones and IK Bones that can be assigned separately to different bone chains.
3. Reverse IK Direction button for flipping elbows and knees.
4. All settings for the IK Bones, Follow Bones, and Lock Bones are now stored on the character itself, so it works as part of the rig.
5. The IK Bones, Follow Bones, and Lock Bones can be turned on or off at any moment using the quick menu or by double-clicking outside the bones. Each type of bone can be disabled individually.
6. MR Tween Machine 2.4 supports MR Pose Tool 3 and can use IK Bones, Follow Bones, and Lock Bones.
7. The Set Single Follow Bones button allows you to set them without grouping them into chains.
8. The Single Bone Mode provides an ability to turn on and off the Follow Bones chains without constant re-adjustments.
Please note that when this option is turned on some menu buttons will be disabled. Don't forget to turn it off if you need those buttons.
9. The tool panel now has buttons to reset bones to their default values. Also, the panel can be expanded to provide access to the text fields for the position, angle, and scale of the bones.
10. Holding Alt + Shift allows you to move bones without clicking on their handles.
11. Added an algorithm to verify if all of the tool’s files are available. If the script is installed incorrectly it will let you know what files are missing and what needs to be done to fix it.
12. Added the Info button, which allows you to quickly see the list of all shortcuts of the tool.

Update 3.1.6

Change List:

1. Added support for Relative Keyframing and bug fixes. Please note that when the Relative Keyframing option is enabled, the Smart Bake function becomes unavailable.
2. Added the Skeleton layers navigation option.

Update 3.2

Change List:

1. Relative Keyframing now supports all types of bone transformations.
2. Added option to use percentage values for bone scaling in Relative Keyframing.
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 3933