Testing resize
This commit is contained in:
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<settings>
|
|
||||||
<option name="PROJECT_PROFILE" />
|
|
||||||
<version value="1.0" />
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,4 +1,4 @@
|
|||||||
#Wed May 10 15:59:40 CEST 2017
|
#Wed May 10 19:56:18 CEST 2017
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
package nl.astraeus.komp
|
package nl.astraeus.komp
|
||||||
|
|
||||||
|
import org.w3c.dom.HTMLElement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: rnentjes
|
* User: rnentjes
|
||||||
* Date: 10-5-17
|
* Date: 10-5-17
|
||||||
* Time: 16:48
|
* Time: 16:48
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum class LayoutType {
|
||||||
|
NONE,
|
||||||
|
HORIZONTAL,
|
||||||
|
VERTICAL
|
||||||
|
}
|
||||||
|
|
||||||
enum class SizeType {
|
enum class SizeType {
|
||||||
NONE,
|
NONE,
|
||||||
ABSOLUTE,
|
ABSOLUTE,
|
||||||
@@ -15,10 +23,112 @@ enum class SizeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class ComponentSize(
|
open class ComponentSize(
|
||||||
val xType: SizeType,
|
val element: HTMLElement,
|
||||||
val yType: SizeType,
|
val layout: LayoutType,
|
||||||
val xValue: Float,
|
val type: SizeType,
|
||||||
val yValue: Float
|
val value: Float
|
||||||
)
|
) {
|
||||||
|
var calculatedSize: Rect = Rect(0,0,0,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rect(
|
||||||
|
val left: Int,
|
||||||
|
val top: Int,
|
||||||
|
val width: Int,
|
||||||
|
val height: Int
|
||||||
|
) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Rect(left=$left, top=$top, width=$width, height=$height)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SizeContainer(
|
||||||
|
val parentSize: Rect,
|
||||||
|
val componentList: List<ComponentSize>
|
||||||
|
) {
|
||||||
|
var layout: LayoutType? = null
|
||||||
|
var totalSize = 0
|
||||||
|
var totalPixels = 0f
|
||||||
|
var totalPercentage = 0f
|
||||||
|
var totalFlex = 0f
|
||||||
|
var fillCount = 0f
|
||||||
|
|
||||||
|
var afterPixels = 0f
|
||||||
|
var afterPercentage = 0f
|
||||||
|
var calculatedSize = 0
|
||||||
|
var calculatedStart = 0
|
||||||
|
|
||||||
|
fun calculate() {
|
||||||
|
for (size in componentList) {
|
||||||
|
if (layout == null) {
|
||||||
|
layout = size.layout
|
||||||
|
} else if (layout != size.layout) {
|
||||||
|
console.log("hbox/vbox combined:", componentList)
|
||||||
|
throw IllegalStateException("hbox and vbox mixed between siblings!")
|
||||||
|
}
|
||||||
|
|
||||||
|
when(size.type) {
|
||||||
|
SizeType.ABSOLUTE -> {
|
||||||
|
totalPixels += size.value
|
||||||
|
}
|
||||||
|
SizeType.PERCENTAGE -> {
|
||||||
|
totalPercentage += size.value
|
||||||
|
}
|
||||||
|
SizeType.FLEX -> {
|
||||||
|
totalFlex += size.value
|
||||||
|
}
|
||||||
|
SizeType.FILL -> {
|
||||||
|
fillCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout == null) {
|
||||||
|
throw IllegalStateException("No hbox or vbox attribute found!?")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout == LayoutType.HORIZONTAL) {
|
||||||
|
totalSize = parentSize.width
|
||||||
|
} else {
|
||||||
|
totalSize = parentSize.height
|
||||||
|
}
|
||||||
|
|
||||||
|
afterPixels = totalSize - totalPixels
|
||||||
|
afterPercentage = afterPixels * totalPercentage / 100f
|
||||||
|
|
||||||
|
for (size in componentList) {
|
||||||
|
when(size.type) {
|
||||||
|
SizeType.ABSOLUTE -> {
|
||||||
|
calculatedSize = size.value.toInt()
|
||||||
|
}
|
||||||
|
SizeType.PERCENTAGE -> {
|
||||||
|
calculatedSize = (afterPixels * size.value / 100f).toInt()
|
||||||
|
}
|
||||||
|
SizeType.FLEX -> {
|
||||||
|
calculatedSize = (afterPercentage * size.value / totalFlex).toInt()
|
||||||
|
}
|
||||||
|
SizeType.FILL -> {
|
||||||
|
calculatedSize = (afterPercentage * size.value / fillCount).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout == LayoutType.HORIZONTAL) {
|
||||||
|
size.calculatedSize = Rect(calculatedStart, parentSize.top, calculatedSize, parentSize.height)
|
||||||
|
} else {
|
||||||
|
size.calculatedSize = Rect(parentSize.left, calculatedStart, parentSize.width, calculatedSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
calculatedStart += calculatedSize
|
||||||
|
console.log("Set component to ${size.calculatedSize}", size.element)
|
||||||
|
|
||||||
|
size.element.style.position = "absolute"
|
||||||
|
size.element.style.left = "${size.calculatedSize.left}px"
|
||||||
|
size.element.style.top = "${size.calculatedSize.top}px"
|
||||||
|
size.element.style.width = "${size.calculatedSize.width}px"
|
||||||
|
size.element.style.height = "${size.calculatedSize.height}px"
|
||||||
|
|
||||||
|
size.element.setAttribute("data-resized", "true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NotSized : ComponentSize(SizeType.NONE, SizeType.NONE, 0f, 0f)
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ fun DIV.include(component: HtmlComponent) {
|
|||||||
|
|
||||||
abstract class HtmlComponent {
|
abstract class HtmlComponent {
|
||||||
var element: HTMLElement? = null
|
var element: HTMLElement? = null
|
||||||
|
var size: ComponentSize? = null
|
||||||
|
|
||||||
fun create(): HTMLElement {
|
fun create(): HTMLElement {
|
||||||
var elem =element
|
var elem =element
|
||||||
@@ -37,5 +38,4 @@ abstract class HtmlComponent {
|
|||||||
Komp.refresh(element)
|
Komp.refresh(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getSize(): ComponentSize? = null
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package nl.astraeus.komp
|
package nl.astraeus.komp
|
||||||
|
|
||||||
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
|
import org.w3c.dom.get
|
||||||
|
import kotlin.browser.document
|
||||||
import kotlin.browser.window
|
import kotlin.browser.window
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,9 +15,18 @@ import kotlin.browser.window
|
|||||||
object Komp {
|
object Komp {
|
||||||
|
|
||||||
private val elements: MutableMap<HTMLElement, HtmlComponent> = HashMap()
|
private val elements: MutableMap<HTMLElement, HtmlComponent> = HashMap()
|
||||||
|
private val elementList: MutableList<HtmlComponent> = ArrayList()
|
||||||
|
private var resizing = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
window.onresize = {
|
||||||
|
Komp.resize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun define(element: HTMLElement, component: HtmlComponent) {
|
fun define(element: HTMLElement, component: HtmlComponent) {
|
||||||
elements[element] = component
|
elements[element] = component
|
||||||
|
elementList.add(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(parent: HTMLElement, component: HtmlComponent, insertAsFirst: Boolean = false) {
|
fun create(parent: HTMLElement, component: HtmlComponent, insertAsFirst: Boolean = false) {
|
||||||
@@ -27,10 +39,16 @@ object Komp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
elements[element] = component
|
elements[element] = component
|
||||||
|
elementList.add(component)
|
||||||
|
|
||||||
|
resize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(element: HTMLElement) {
|
fun remove(element: HTMLElement) {
|
||||||
|
val component = elements[element]
|
||||||
|
|
||||||
elements.remove(element)
|
elements.remove(element)
|
||||||
|
elementList.remove(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsName("remove")
|
@JsName("remove")
|
||||||
@@ -40,6 +58,7 @@ object Komp {
|
|||||||
elements.remove(key)
|
elements.remove(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
elementList.remove(component)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refresh(component: HtmlComponent) {
|
fun refresh(component: HtmlComponent) {
|
||||||
@@ -55,45 +74,135 @@ object Komp {
|
|||||||
val newElement = comp.create()
|
val newElement = comp.create()
|
||||||
|
|
||||||
parent?.replaceChild(newElement, element)
|
parent?.replaceChild(newElement, element)
|
||||||
|
|
||||||
window.setTimeout({
|
|
||||||
resize(comp)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resize()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resize() {
|
||||||
|
if (!resizing) {
|
||||||
|
resizing = true
|
||||||
|
|
||||||
|
window.setTimeout({
|
||||||
|
resizing = false
|
||||||
|
|
||||||
|
resizeComponents()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resize(component: HtmlComponent) {
|
private fun resizeComponents() {
|
||||||
println("Resize $component")
|
for (component in elementList) {
|
||||||
}
|
component.element?.setAttribute("data-resized", "false")
|
||||||
|
|
||||||
fun sizeElement(element: HTMLElement, size: ComponentSize) {
|
|
||||||
var width = ""
|
|
||||||
var height = ""
|
|
||||||
val parent = element.parentElement as HTMLElement
|
|
||||||
|
|
||||||
when(size.xType) {
|
|
||||||
SizeType.ABSOLUTE -> {
|
|
||||||
width = "${size.xValue.toInt()}px"
|
|
||||||
}
|
|
||||||
SizeType.PERCENTAGE -> {
|
|
||||||
width = "${(parent.clientWidth * size.xValue / 100f).toInt()}px"
|
|
||||||
}
|
|
||||||
SizeType.FILL -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
SizeType.FLEX -> {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width.isNotBlank()) {
|
for (component in elementList) {
|
||||||
element.style.width = width
|
if (component.element?.getAttribute("data-resize") != "true") {
|
||||||
}
|
if (component.element?.attributes?.get("hbox") != null || component.element?.attributes?.get("vbox") != null) {
|
||||||
if (height.isNotBlank()) {
|
console.log("resize", component)
|
||||||
element.style.height = height
|
|
||||||
|
resize(component)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private fun resize(comp: HtmlComponent) {
|
||||||
|
val parent = comp.element?.parentElement
|
||||||
|
|
||||||
|
if (parent != null) {
|
||||||
|
val sizes = getSiblingSizes(parent)
|
||||||
|
val parentSize = elements[parent]?.size
|
||||||
|
val container: SizeContainer
|
||||||
|
|
||||||
|
if (parentSize != null) {
|
||||||
|
container = SizeContainer(
|
||||||
|
parentSize.calculatedSize,
|
||||||
|
sizes
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val leftString = (parent as HTMLElement).style.left
|
||||||
|
val topString = parent.style.top
|
||||||
|
val widthString = parent.style.width
|
||||||
|
val heightString = parent.style.height
|
||||||
|
|
||||||
|
if (parent == document.body) {
|
||||||
|
container = SizeContainer(
|
||||||
|
Rect(parent.clientLeft, parent.clientTop, parent.clientWidth, parent.clientHeight),
|
||||||
|
sizes
|
||||||
|
)
|
||||||
|
} else if (leftString.endsWith("px") && topString.endsWith("px") && widthString.endsWith("px") && heightString.endsWith("px")) {
|
||||||
|
container = SizeContainer(
|
||||||
|
Rect(
|
||||||
|
leftString.slice(0..leftString.length - 3).toInt(),
|
||||||
|
topString.slice(0..topString.length - 3).toInt(),
|
||||||
|
widthString.slice(0..widthString.length - 3).toInt(),
|
||||||
|
heightString.slice(0..heightString.length - 3).toInt()
|
||||||
|
),
|
||||||
|
sizes
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
container = SizeContainer(
|
||||||
|
Rect(parent.clientLeft, parent.clientTop, parent.clientWidth, parent.clientHeight),
|
||||||
|
sizes
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container.calculate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSiblingSizes(parent: Element): List<ComponentSize> {
|
||||||
|
val result: MutableList<ComponentSize> = ArrayList()
|
||||||
|
|
||||||
|
for (index in 0..parent.children.length-1) {
|
||||||
|
val child = parent.children[index]
|
||||||
|
|
||||||
|
if (child is HTMLElement) {
|
||||||
|
val comp = elements[child]
|
||||||
|
val size = getSize(child)
|
||||||
|
comp?.size = size
|
||||||
|
|
||||||
|
result.add(ComponentSize(child, size.layout, size.type, size.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSize(element: HTMLElement): ComponentSize {
|
||||||
|
val horText = element.attributes?.get("hbox")?.value
|
||||||
|
val verText = element.attributes?.get("vbox")?.value
|
||||||
|
var result: ComponentSize? = null
|
||||||
|
|
||||||
|
if (horText != null && verText != null) {
|
||||||
|
throw IllegalStateException("Attributes 'hbox' and 'vbox' can not be combined!")
|
||||||
|
} else if (horText != null) {
|
||||||
|
val (type, size) = getSizeFromAttribute(horText)
|
||||||
|
|
||||||
|
result = ComponentSize(element, LayoutType.HORIZONTAL, type, size)
|
||||||
|
} else if (verText != null) {
|
||||||
|
val (type, size) = getSizeFromAttribute(verText)
|
||||||
|
|
||||||
|
result = ComponentSize(element, LayoutType.VERTICAL, type, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result ?: throw IllegalStateException("Unable to calculate size for $this")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSizeFromAttribute(sizeString: String): Pair<SizeType, Float> {
|
||||||
|
if (sizeString == "fill") {
|
||||||
|
return SizeType.FILL to 0f
|
||||||
|
} else if (sizeString.endsWith("px")) {
|
||||||
|
return SizeType.ABSOLUTE to sizeString.slice(0..sizeString.length-3).toFloat()
|
||||||
|
} else if (sizeString.endsWith("%")) {
|
||||||
|
return SizeType.PERCENTAGE to sizeString.slice(0..sizeString.length-2).toFloat()
|
||||||
|
} else {
|
||||||
|
return SizeType.FLEX to sizeString.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user