Skip to content

Commit

Permalink
Merge branch 'main' of github.com:lightningkite/kiteui
Browse files Browse the repository at this point in the history
  • Loading branch information
WesleyEdwards committed May 15, 2024
2 parents 2374770 + 21e44e7 commit dae994d
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import platform.QuartzCore.CATransform3DMakeScale
import platform.UIKit.*
import kotlin.math.min
import com.lightningkite.kiteui.objc.UIViewWithSpacingRulesProtocol
import platform.Foundation.NSNotificationCenter
import platform.Foundation.NSOperationQueue

@OptIn(ExperimentalForeignApi::class)
@Suppress("ACTUAL_WITHOUT_EXPECT")
actual class NIconView(): NView(CGRectMake(0.0,0.0,0.0,0.0)), UIViewWithSpacingRulesProtocol {
init {
setUserInteractionEnabled(false)
NSNotificationCenter.defaultCenter.addObserverForName(UIContentSizeCategoryDidChangeNotification, null, NSOperationQueue.mainQueue) {
informParentOfSizeChange()
}
}

val spacingOverride: Property<Dimension?> = Property<Dimension?>(null)
Expand Down Expand Up @@ -63,9 +68,10 @@ actual class NIconView(): NView(CGRectMake(0.0,0.0,0.0,0.0)), UIViewWithSpacingR

override fun sizeThatFits(size: CValue<CGSize>): CValue<CGSize> {
val axisTotalPadding = (extensionPadding ?: 0.0) * 2
val scaleFactor = preferredScaleFactor()
return CGSizeMake(
icon?.width?.value?.let { it + axisTotalPadding } ?: 0.0,
icon?.height?.value?.let { it + axisTotalPadding } ?: 0.0
icon?.width?.value?.let { it * scaleFactor + axisTotalPadding } ?: 0.0,
icon?.height?.value?.let { it * scaleFactor + axisTotalPadding } ?: 0.0
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import com.lightningkite.kiteui.models.*
import com.lightningkite.kiteui.reactive.ReadableState
import com.lightningkite.kiteui.reactive.Writable
import com.lightningkite.kiteui.views.*
import platform.Foundation.NSAttributedString
import platform.Foundation.NSAttributedStringMeta
import platform.Foundation.NSMutableAttributedString
import platform.Foundation.NSString
import platform.Foundation.*
import platform.UIKit.*
import platform.darwin.NSObject

Expand All @@ -17,6 +14,7 @@ actual typealias NTextField = UITextField
@ViewDsl
actual inline fun ViewWriter.textFieldActual(crossinline setup: TextField.() -> Unit): Unit = stack {
element(UITextField()) {
setContentSizeCategoryChangeListener()
smartDashesType = UITextSmartDashesType.UITextSmartDashesTypeNo
smartQuotesType = UITextSmartQuotesType.UITextSmartQuotesTypeNo
backgroundColor = UIColor.clearColor
Expand Down Expand Up @@ -125,10 +123,29 @@ actual inline var TextField.align: Align
Align.Stretch -> NSTextAlignmentJustified
}
}

private val UILabelTextSize = ExtensionProperty<UITextField, Dimension>()
var UITextField.extensionTextSize: Dimension? by UILabelTextSize

actual inline var TextField.textSize: Dimension
get() = native.font?.pointSize?.let(::Dimension) ?: 1.rem
get() = native.extensionTextSize ?: native.font?.pointSize?.let(::Dimension) ?: 1.rem
set(value) {
native.extensionFontAndStyle?.let {
native.font = it.font.get(value.value, it.weight.toUIFontWeight(), it.italic)
}
}
native.extensionTextSize = value
native.updateFont()
native.informParentOfSizeChange()
}

fun UITextField.setContentSizeCategoryChangeListener() {
NSNotificationCenter.defaultCenter.addObserverForName(UIContentSizeCategoryDidChangeNotification, null, NSOperationQueue.mainQueue) {
updateFont()
informParentOfSizeChange()
}
}
fun UITextField.updateFont() {
val textSize = extensionTextSize ?: return
val alignment = textAlignment
font = extensionFontAndStyle?.let {
it.font.get(textSize.value * preferredScaleFactor(), it.weight.toUIFontWeight(), it.italic)
} ?: UIFont.systemFontOfSize(textSize.value)
textAlignment = alignment
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package com.lightningkite.kiteui.views.direct

import com.lightningkite.kiteui.models.*
import com.lightningkite.kiteui.views.*
import platform.Foundation.NSNotificationCenter
import platform.Foundation.NSOperationQueue
import platform.UIKit.*

@Suppress("ACTUAL_WITHOUT_EXPECT")
actual typealias NTextView = UILabel

@ViewDsl
actual inline fun ViewWriter.h1Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(2.0.rem.value)
extensionTextSize = 2.0.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 2.0.rem * 0.6,
minHeight = 2.0.rem * 1.5,
Expand All @@ -20,14 +24,16 @@ actual inline fun ViewWriter.h1Actual(crossinline setup: TextView.() -> Unit): U
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.title
it.title.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.h2Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.6.rem.value)
extensionTextSize = 1.6.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.6.rem * 0.6,
minHeight = 1.6.rem * 1.5,
Expand All @@ -38,14 +44,16 @@ actual inline fun ViewWriter.h2Actual(crossinline setup: TextView.() -> Unit): U
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.title
it.title.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.h3Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.4.rem.value)
extensionTextSize = 1.4.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.4.rem * 0.6,
minHeight = 1.4.rem * 1.5,
Expand All @@ -56,14 +64,16 @@ actual inline fun ViewWriter.h3Actual(crossinline setup: TextView.() -> Unit): U
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.title
it.title.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.h4Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.3.rem.value)
extensionTextSize = 1.3.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.3.rem * 0.6,
minHeight = 1.3.rem * 1.5,
Expand All @@ -74,14 +84,16 @@ actual inline fun ViewWriter.h4Actual(crossinline setup: TextView.() -> Unit): U
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.title
it.title.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.h5Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.2.rem.value)
extensionTextSize = 1.2.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.2.rem * 0.6,
minHeight = 1.2.rem * 1.5,
Expand All @@ -99,7 +111,9 @@ actual inline fun ViewWriter.h5Actual(crossinline setup: TextView.() -> Unit): U

@ViewDsl
actual inline fun ViewWriter.h6Actual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.1.rem.value)
extensionTextSize = 1.1.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.1.rem * 0.6,
minHeight = 1.1.rem * 1.5,
Expand All @@ -110,14 +124,16 @@ actual inline fun ViewWriter.h6Actual(crossinline setup: TextView.() -> Unit): U
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.title
it.title.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.textActual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(1.0.rem.value)
extensionTextSize = 1.0.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 1.0.rem * 0.6,
minHeight = 1.0.rem * 1.5,
Expand All @@ -128,14 +144,16 @@ actual inline fun ViewWriter.textActual(crossinline setup: TextView.() -> Unit):
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.body
it.body.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { setup(TextView(this)) }
}

@ViewDsl
actual inline fun ViewWriter.subtextActual(crossinline setup: TextView.() -> Unit): Unit = element(UILabel()) {
font = UIFont.systemFontOfSize(0.8.rem.value)
extensionTextSize = 0.8.rem
updateFont()
setContentSizeCategoryChangeListener()
extensionSizeConstraints = SizeConstraints(
minWidth = 0.8.rem * 0.6,
minHeight = 0.8.rem * 1.5,
Expand All @@ -146,7 +164,7 @@ actual inline fun ViewWriter.subtextActual(crossinline setup: TextView.() -> Uni
foreground = {
this.textColor = it.foreground.closestColor().toUiColor()
this.extensionFontAndStyle = it.body
it.body.let { this.font = it.font.get(font.pointSize, it.weight.toUIFontWeight(), it.italic) }
updateFont()
},
) { opacity = 0.8; setup(TextView(this)) }
}
Expand Down Expand Up @@ -179,12 +197,16 @@ actual inline var TextView.align: Align
Align.Stretch -> NSTextAlignmentJustified
}
}

private val UILabelTextSize = ExtensionProperty<UILabel, Dimension>()
var UILabel.extensionTextSize: Dimension? by UILabelTextSize

actual inline var TextView.textSize: Dimension
get() = Dimension(native.font.pointSize)
get() = native.extensionTextSize ?: Dimension(native.font.pointSize)
set(value) {
native.extensionFontAndStyle?.let {
native.font = it.font.get(value.value, it.weight.toUIFontWeight(), it.italic)
}
native.extensionTextSize = value
native.updateFont()
native.informParentOfSizeChange()
}
actual var TextView.ellipsis: Boolean
get() = TODO("Not yet implemented")
Expand All @@ -195,4 +217,31 @@ actual var TextView.wraps: Boolean
get() = TODO("Not yet implemented")
set(value) {
native.numberOfLines = if(value) 0 else 1
}
}

// Calculated from font sizes shown at https://developer.apple.com/design/human-interface-guidelines/typography#Specifications
private val dynamicTypeScaleFactors = mapOf(
UIContentSizeCategoryUnspecified to 1.0,
UIContentSizeCategoryExtraSmall to 0.87,
UIContentSizeCategorySmall to 0.91,
UIContentSizeCategoryMedium to 0.95,
UIContentSizeCategoryLarge to 1.0,
UIContentSizeCategoryExtraLarge to 1.11,
UIContentSizeCategoryExtraExtraLarge to 1.21,
UIContentSizeCategoryExtraExtraExtraLarge to 1.32,
)
fun preferredScaleFactor() = dynamicTypeScaleFactors[UIApplication.sharedApplication.preferredContentSizeCategory] ?: 1.0
fun UILabel.setContentSizeCategoryChangeListener() {
NSNotificationCenter.defaultCenter.addObserverForName(UIContentSizeCategoryDidChangeNotification, null, NSOperationQueue.mainQueue) {
updateFont()
informParentOfSizeChange()
}
}
fun UILabel.updateFont() {
val textSize = extensionTextSize ?: return
val alignment = textAlignment
font = extensionFontAndStyle?.let {
it.font.get(textSize.value * preferredScaleFactor(), it.weight.toUIFontWeight(), it.italic)
} ?: UIFont.systemFontOfSize(textSize.value)
textAlignment = alignment
}

0 comments on commit dae994d

Please sign in to comment.