Move view tests to common

This commit is contained in:
2019-04-14 10:33:36 -05:00
parent defa2f9431
commit a3bfc05068
62 changed files with 427 additions and 246 deletions

View File

@@ -22,17 +22,22 @@ package org.isoron.platform.io
interface Log {
fun info(tag: String, msg: String)
fun debug(tag: String, msg: String)
fun warn(tag: String, msg: String)
}
/**
* A Log that prints to the standard output.
*/
class StandardLog : Log {
override fun warn(tag: String, msg: String) {
println(sprintf("W %-20s %s", tag, msg))
}
override fun info(tag: String, msg: String) {
println("I/$tag $msg")
println(sprintf("I %-20s %s", tag, msg))
}
override fun debug(tag: String, msg: String) {
println("D/$tag $msg")
println(sprintf("D %-20s %s", tag, msg))
}
}

View File

@@ -19,18 +19,27 @@
package org.isoron.platform.gui
import kotlinx.coroutines.*
import org.w3c.dom.*
import kotlin.browser.*
import kotlin.js.*
import kotlin.math.*
class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas {
class JsCanvas(val element: HTMLCanvasElement,
val pixelScale: Double) : Canvas {
val ctx = canvas.getContext("2d") as CanvasRenderingContext2D
val ctx = element.getContext("2d") as CanvasRenderingContext2D
var fontSize = 12.0
var fontWeight = ""
var fontFamily = "sans-serif"
var fontFamily = "NotoRegular"
var align = CanvasTextAlign.CENTER
private fun toPixel(x: Double): Double {
return pixelScale * x
}
private fun toDp(x: Int): Double {
return x / pixelScale
}
override fun setColor(color: Color) {
val c = "rgb(${color.red * 255}, ${color.green * 255}, ${color.blue * 255})"
ctx.fillStyle = c;
@@ -39,45 +48,54 @@ class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas {
override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) {
ctx.beginPath()
ctx.moveTo(x1 + 0.5, y1 + 0.5)
ctx.lineTo(x2 + 0.5, y2 + 0.5)
ctx.moveTo(toPixel(x1), toPixel(y1))
ctx.lineTo(toPixel(x2), toPixel(y2))
ctx.stroke()
}
override fun drawText(text: String, x: Double, y: Double) {
ctx.font = "${fontWeight} ${fontSize}px ${fontFamily}"
ctx.font = "${fontSize}px ${fontFamily}"
ctx.textAlign = align
ctx.textBaseline = CanvasTextBaseline.MIDDLE
ctx.fillText(text, x, y)
ctx.fillText(text, toPixel(x), toPixel(y + fontSize * 0.05))
}
override fun fillRect(x: Double, y: Double, width: Double, height: Double) {
ctx.fillRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0)
ctx.fillRect(toPixel(x),
toPixel(y),
toPixel(width),
toPixel(height))
}
override fun drawRect(x: Double, y: Double, width: Double, height: Double) {
ctx.strokeRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0)
ctx.strokeRect(toPixel(x),
toPixel(y),
toPixel(width),
toPixel(height))
}
override fun getHeight(): Double {
return canvas.height.toDouble()
return toDp(element.height)
}
override fun getWidth(): Double {
return canvas.width.toDouble()
return toDp(element.width)
}
override fun setFont(font: Font) {
fontWeight = if (font == Font.BOLD) "bold" else ""
fontFamily = if (font == Font.FONT_AWESOME) "FontAwesome" else "sans-serif"
fontFamily = when(font) {
Font.REGULAR -> "NotoRegular"
Font.BOLD -> "NotoBold"
Font.FONT_AWESOME -> "FontAwesome"
}
}
override fun setFontSize(size: Double) {
fontSize = size
fontSize = size * pixelScale
}
override fun setStrokeWidth(size: Double) {
ctx.lineWidth = size
ctx.lineWidth = size * pixelScale
}
override fun fillArc(centerX: Double,
@@ -85,18 +103,24 @@ class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas {
radius: Double,
startAngle: Double,
swipeAngle: Double) {
val x = toPixel(centerX)
val y = toPixel(centerY)
val from = startAngle / 180 * PI
val to = (startAngle + swipeAngle) / 180 * PI
ctx.beginPath()
ctx.moveTo(centerX, centerY)
ctx.arc(centerX, centerY, radius, -from, -to, swipeAngle >= 0)
ctx.lineTo(centerX, centerY)
ctx.moveTo(x, y)
ctx.arc(x, y, toPixel(radius), -from, -to, swipeAngle >= 0)
ctx.lineTo(x, y)
ctx.fill()
}
override fun fillCircle(centerX: Double, centerY: Double, radius: Double) {
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0.0, 2 * PI)
ctx.arc(toPixel(centerX),
toPixel(centerY),
toPixel(radius),
0.0,
2 * PI)
ctx.fill()
}
@@ -107,4 +131,15 @@ class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas {
TextAlign.RIGHT -> CanvasTextAlign.RIGHT
}
}
suspend fun loadImage(src: String) {
Promise<Int> { resolve, reject ->
val img = Image()
img.onload = {
ctx.drawImage(img, 0.0, 0.0)
resolve(0)
}
img.src = src
}.await()
}
}

View File

@@ -24,6 +24,9 @@ import org.w3c.xhr.*
import kotlin.js.*
class JsFileStorage {
private val TAG = "JsFileStorage"
private val log = StandardLog()
private val indexedDB = eval("indexedDB")
private var db: dynamic = null
@@ -31,16 +34,16 @@ class JsFileStorage {
private val OS_NAME = "Files"
suspend fun init() {
console.log("Initializing JsFileStorage...")
log.info(TAG, "Initializing")
Promise<Int> { resolve, reject ->
val req = indexedDB.open(DB_NAME, 2)
req.onerror = { reject(Exception("could not open IndexedDB")) }
req.onupgradeneeded = {
console.log("Creating document store for JsFileStorage...")
log.info(TAG, "Creating document store")
req.result.createObjectStore(OS_NAME)
}
req.onsuccess = {
console.log("JsFileStorage is ready.")
log.info(TAG, "Ready")
db = req.result
resolve(0)
}

View File

@@ -20,5 +20,5 @@
package org.isoron.platform.io
actual fun sprintf(format: String, vararg args: Any?): String {
TODO()
return js("vsprintf")(format, args)
}

View File

@@ -19,6 +19,7 @@
package org.isoron.platform.gui
import kotlinx.coroutines.*
import org.isoron.platform.io.*
import java.awt.*
import java.awt.RenderingHints.*
@@ -26,14 +27,6 @@ import java.awt.font.*
import java.awt.image.*
import kotlin.math.*
fun createFont(path: String): java.awt.Font {
val file = JavaFileOpener().openResourceFile(path) as JavaResourceFile
return java.awt.Font.createFont(0, file.stream())
}
private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf")
private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf")
private val FONT_AWESOME_FONT = createFont("fonts/FontAwesome.ttf")
class JavaCanvas(val image: BufferedImage,
val pixelScale: Double = 2.0) : Canvas {
@@ -46,6 +39,10 @@ class JavaCanvas(val image: BufferedImage,
val heightPx = image.height
val g2d = image.createGraphics()
private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf")
private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf")
private val FONT_AWESOME_FONT = createFont("fonts/FontAwesome.ttf")
init {
g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON);
@@ -73,6 +70,7 @@ class JavaCanvas(val image: BufferedImage,
}
override fun drawText(text: String, x: Double, y: Double) {
updateFont()
val bounds = g2d.font.getStringBounds(text, frc)
val bWidth = bounds.width.roundToInt()
val bHeight = bounds.height.roundToInt()
@@ -122,7 +120,7 @@ class JavaCanvas(val image: BufferedImage,
}
override fun setStrokeWidth(size: Double) {
g2d.setStroke(BasicStroke(size.toFloat()))
g2d.stroke = BasicStroke((size * pixelScale).toFloat())
}
private fun updateFont() {
@@ -158,4 +156,10 @@ class JavaCanvas(val image: BufferedImage,
override fun setTextAlign(align: TextAlign) {
this.textAlign = align
}
private fun createFont(path: String) = runBlocking<java.awt.Font> {
val file = JavaFileOpener().openResourceFile(path) as JavaResourceFile
if (!file.exists()) throw RuntimeException("File not found: ${file.path}")
java.awt.Font.createFont(0, file.stream())
}
}

View File

@@ -22,7 +22,7 @@ package org.isoron.platform.io
import java.io.*
import java.nio.file.*
class JavaResourceFile(private val path: String) : ResourceFile {
class JavaResourceFile(val path: String) : ResourceFile {
private val javaPath: Path
get() {
val mainPath = Paths.get("assets/main/$path")
@@ -41,7 +41,9 @@ class JavaResourceFile(private val path: String) : ResourceFile {
override suspend fun copyTo(dest: UserFile) {
if (dest.exists()) dest.delete()
Files.copy(javaPath, (dest as JavaUserFile).path)
val destPath = (dest as JavaUserFile).path
destPath.toFile().parentFile?.mkdirs()
Files.copy(javaPath, destPath)
}
fun stream(): InputStream {