structure AppUpdate = struct open AppType open DrawMessage open FileMessage open InputMessage open UpdateMessage fun getDotVecFromIndices (model: app_type, hIdx, vIdx) = let val {windowWidth, windowHeight, xClickPoints, yClickPoints, ...} = model val xpos = Vector.sub (xClickPoints, hIdx) val ypos = Vector.sub (yClickPoints, vIdx) val endXpos = if hIdx + 1 = Vector.length xClickPoints then xpos else Vector.sub (xClickPoints, hIdx + 1) val endYpos = if vIdx + 1 = Vector.length yClickPoints then ypos else Vector.sub (yClickPoints, vIdx + 1) val tl = ClickPoints.getDrawDotRgb (xpos, ypos, 0.0, 0.0, 1.0, windowWidth, windowHeight) val tr = ClickPoints.getDrawDotRgb (endXpos, ypos, 0.0, 0.0, 1.0, windowWidth, windowHeight) val bl = ClickPoints.getDrawDotRgb (xpos, endYpos, 0.0, 0.0, 1.0, windowWidth, windowHeight) val br = ClickPoints.getDrawDotRgb (endXpos, endYpos, 0.0, 0.0, 1.0, windowWidth, windowHeight) in Vector.concat [tl, tr, bl, br] end fun mouseMoveOrRelease (model: app_type) = let val drawVec = case ClickPoints.getClickPositionFromMouse model of SOME (hIdx, vIdx) => getDotVecFromIndices (model, hIdx, vIdx) | NONE => Vector.fromList [] val drawMsg = DRAW_DOT drawVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end fun getDrawDotMsgWhenArrowIsAtBoundary model = let val {arrowX, arrowY, ...} = model val dotVec = getDotVecFromIndices (model, arrowX, arrowY) val drawMsg = DRAW_DOT dotVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end fun moveArrowUp (model: app_type) = let val {arrowX, arrowY, ...} = model in if arrowY > 0 then let val newArrowY = arrowY - 1 val model = AppWith.arrowY (model, newArrowY) val dotVec = getDotVecFromIndices (model, arrowX, newArrowY) val drawMsg = DRAW_DOT dotVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end else getDrawDotMsgWhenArrowIsAtBoundary model end fun moveArrowLeft (model: app_type) = let val {arrowX, arrowY, ...} = model in if arrowX > 0 then let val newArrowX = arrowX - 1 val model = AppWith.arrowX (model, newArrowX) val dotVec = getDotVecFromIndices (model, newArrowX, arrowY) val drawMsg = DRAW_DOT dotVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end else getDrawDotMsgWhenArrowIsAtBoundary model end fun moveArrowRight (model: app_type) = let val {arrowX, arrowY, xClickPoints, ...} = model in if arrowX < Vector.length xClickPoints - 2 then let val newArrowX = arrowX + 1 val model = AppWith.arrowX (model, newArrowX) val dotVec = getDotVecFromIndices (model, newArrowX, arrowY) val drawMsg = DRAW_DOT dotVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end else getDrawDotMsgWhenArrowIsAtBoundary model end fun moveArrowDown (model: app_type) = let val {arrowX, arrowY, yClickPoints, ...} = model in if arrowY < Vector.length yClickPoints - 2 then let val newArrowY = arrowY + 1 val model = AppWith.arrowY (model, newArrowY) val dotVec = getDotVecFromIndices (model, arrowX, newArrowY) val drawMsg = DRAW_DOT dotVec val drawMsg = [DRAW drawMsg] in (model, drawMsg) end else getDrawDotMsgWhenArrowIsAtBoundary model end fun realToInt x = Real32.toInt IEEEReal.TO_NEAREST x fun addCoordinates (model: app_type, hIdx, vIdx) = let val { windowWidth , windowHeight , xClickPoints , yClickPoints , canvasWidth , canvasHeight , ... } = model val xpos = Vector.sub (xClickPoints, hIdx) val ypos = Vector.sub (yClickPoints, vIdx) val model = AppWith.addSquare (model, realToInt xpos, realToInt ypos, hIdx, vIdx) val squares = #squares model val dotVec = getDotVecFromIndices (model, hIdx, vIdx) val halfWidth = Real32.fromInt (windowWidth div 2) val halfHeight = Real32.fromInt (windowHeight div 2) val maxSide = Int.max (canvasWidth, canvasHeight) val squares = CollisionTree.toTriangles (windowWidth, windowHeight, squares, maxSide) val drawMsg = DRAW_SQUARES_AND_DOTS {squares = squares, dots = dotVec} in (model, [drawMsg]) end fun mouseLeftClick model = case ClickPoints.getClickPositionFromMouse model of SOME (hIdx, vIdx) => addCoordinates (model, hIdx, vIdx) | NONE => (model, []) fun enterOrSpaceCoordinates model = let val {arrowX, arrowY, ...} = model in addCoordinates (model, arrowX, arrowY) end end