structure ClickPoints = struct fun generate (windowWidth, windowHeight, canvasWidth, canvasHeight) = let val realWindowWidth = Real32.fromInt windowWidth val realCanvasWidth = Real32.fromInt canvasWidth val realWindowHeight = Real32.fromInt windowHeight val realCanvasHeight = Real32.fromInt canvasHeight val xPixelSize = realWindowWidth / realCanvasWidth val yPixelSize = realWindowHeight / realCanvasHeight val pixelSize = Real32.min (xPixelSize, yPixelSize) val actualWidth = pixelSize * realCanvasWidth val actualHeight = pixelSize * realCanvasHeight val heightDifference = realWindowHeight - actualHeight val yOffset = heightDifference / 2.0 val widthDifference = realWindowWidth - actualWidth val xOffset = widthDifference / 2.0 val xClickPoints = Vector.tabulate (canvasWidth + 1, fn i => (Real32.fromInt i * pixelSize) + xOffset) val yClickPoints = Vector.tabulate (canvasHeight + 1, fn i => (Real32.fromInt i * pixelSize) + yOffset) in (xClickPoints, yClickPoints) end fun getClickPos (clickPoints, mousePos, idx) = let val nextIdx = idx + 1 in if nextIdx >= Vector.length clickPoints then NONE else let val curPos = Vector.sub (clickPoints, idx) val nextPos = Vector.sub (clickPoints, nextIdx) in if mousePos >= curPos andalso mousePos <= nextPos then SOME idx else getClickPos (clickPoints, mousePos, idx + 1) end end fun getClickPositionFromMouse (app: AppType.app_type) = case getClickPos (#xClickPoints app, #mouseX app, 0) of SOME hIdx => (case getClickPos (#yClickPoints app, #mouseY app, 0) of SOME vIdx => SOME (hIdx, vIdx) | NONE => NONE) | NONE => NONE fun getDrawDot (xpos, ypos, windowWidth, windowHeight) = let (* calculate normalised device coordinates *) val halfWidth = Real32.fromInt (windowWidth div 2) val halfHeight = Real32.fromInt (windowHeight div 2) val hpos = xpos - halfWidth val vpos = ~(ypos - halfHeight) (* coordinates to form small box around clicked area *) val left = (hpos - 5.0) / halfWidth val right = (hpos + 5.0) / halfWidth val bottom = (vpos - 5.0) / halfHeight val top = (vpos + 5.0) / halfHeight in Ndc.ltrbToVertex (left, top, right, bottom) end fun getDrawDotRgb (xpos, ypos, r, g, b, windowWidth, windowHeight) = let (* calculate normalised device coordinates *) val halfWidth = Real32.fromInt (windowWidth div 2) val halfHeight = Real32.fromInt (windowHeight div 2) val hpos = xpos - halfWidth val vpos = ~(ypos - halfHeight) (* coordinates to form small box around clicked area *) val left = (hpos - 5.0) / halfWidth val right = (hpos + 5.0) / halfWidth val bottom = (vpos - 5.0) / halfHeight val top = (vpos + 5.0) / halfHeight in Ndc.ltrbToVertexRgb (left, top, right, bottom, r, g, b) end end