mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
remove compose completely and stub out temp broken things
This commit is contained in:
parent
8709d9db8c
commit
012139cb01
22 changed files with 161 additions and 728 deletions
|
|
@ -1,88 +0,0 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.core.DensityAmbient
|
||||
import androidx.ui.core.DrawModifier
|
||||
import androidx.ui.core.Modifier
|
||||
import androidx.ui.core.asModifier
|
||||
import androidx.ui.foundation.Box
|
||||
import androidx.ui.graphics.*
|
||||
import androidx.ui.graphics.colorspace.ColorSpaces
|
||||
import androidx.ui.graphics.painter.ImagePainter
|
||||
import androidx.ui.unit.Density
|
||||
import androidx.ui.unit.PxSize
|
||||
import androidx.ui.unit.toRect
|
||||
|
||||
/// Stolen from the Compose SimpleImage, replace with their real Image component someday
|
||||
// TODO(mount, malkov) : remove when RepaintBoundary is a modifier: b/149982905
|
||||
// This is class and not val because if b/149985596
|
||||
private object ClipModifier : DrawModifier {
|
||||
override fun draw(density: Density, drawContent: () -> Unit, canvas: Canvas, size: PxSize) {
|
||||
canvas.save()
|
||||
canvas.clipRect(size.toRect())
|
||||
drawContent()
|
||||
canvas.restore()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Stolen from the Compose SimpleImage, replace with their real Image component someday
|
||||
@Composable
|
||||
fun ScaledImage(
|
||||
image: ImageAsset,
|
||||
modifier: Modifier = Modifier.None,
|
||||
tint: Color? = null
|
||||
) {
|
||||
with(DensityAmbient.current) {
|
||||
val imageModifier = ImagePainter(image).asModifier(
|
||||
scaleFit = ScaleFit.FillMaxDimension,
|
||||
colorFilter = tint?.let { ColorFilter(it, BlendMode.srcIn) }
|
||||
)
|
||||
Box(modifier + ClipModifier + imageModifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Borrowed from Compose
|
||||
class AndroidImage(val bitmap: Bitmap) : ImageAsset {
|
||||
|
||||
/**
|
||||
* @see Image.width
|
||||
*/
|
||||
override val width: Int
|
||||
get() = bitmap.width
|
||||
|
||||
/**
|
||||
* @see Image.height
|
||||
*/
|
||||
override val height: Int
|
||||
get() = bitmap.height
|
||||
|
||||
override val config: ImageAssetConfig get() = ImageAssetConfig.Argb8888
|
||||
|
||||
/**
|
||||
* @see Image.colorSpace
|
||||
*/
|
||||
override val colorSpace: androidx.ui.graphics.colorspace.ColorSpace
|
||||
get() = ColorSpaces.Srgb
|
||||
|
||||
/**
|
||||
* @see Image.hasAlpha
|
||||
*/
|
||||
override val hasAlpha: Boolean
|
||||
get() = bitmap.hasAlpha()
|
||||
|
||||
/**
|
||||
* @see Image.nativeImage
|
||||
*/
|
||||
override val nativeImage: NativeImageAsset
|
||||
get() = bitmap
|
||||
|
||||
/**
|
||||
* @see
|
||||
*/
|
||||
override fun prepareToDraw() {
|
||||
bitmap.prepareToDraw()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +1,7 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.bluetooth.le.*
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.ParcelUuid
|
||||
import androidx.compose.Composable
|
||||
import androidx.compose.Model
|
||||
import androidx.compose.frames.modelMapOf
|
||||
import androidx.compose.onCommit
|
||||
import androidx.ui.core.ContextAmbient
|
||||
import androidx.ui.foundation.Text
|
||||
import androidx.ui.layout.Column
|
||||
import androidx.ui.layout.LayoutGravity
|
||||
import androidx.ui.material.CircularProgressIndicator
|
||||
import androidx.ui.material.MaterialTheme
|
||||
import androidx.ui.material.ProvideEmphasis
|
||||
import androidx.ui.material.RadioGroup
|
||||
import androidx.ui.tooling.preview.Preview
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.service.RadioInterfaceService
|
||||
import com.geeksville.util.exceptionReporter
|
||||
|
||||
|
||||
/*
|
||||
@Model
|
||||
object ScanUIState {
|
||||
var selectedMacAddr: String? = null
|
||||
|
|
@ -171,14 +147,6 @@ fun BTScanScreen() {
|
|||
} else {
|
||||
// val allPaired = bluetoothAdapter?.bondedDevices.orEmpty().map { it.address }.toSet()
|
||||
|
||||
/* Only let user select paired devices
|
||||
val paired = devices.values.filter { allPaired.contains(it.macAddress) }
|
||||
if (paired.size < devices.size) {
|
||||
Text(
|
||||
"Warning: there are nearby Meshtastic devices that are not paired with this phone. Before you can select a device, you will need to pair it in Bluetooth Settings."
|
||||
)
|
||||
} */
|
||||
|
||||
RadioGroup {
|
||||
Column {
|
||||
ScanUIState.devices.values.forEach {
|
||||
|
|
@ -237,10 +205,4 @@ fun BTScanScreen() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun btScanScreenPreview() {
|
||||
BTScanScreen()
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,30 +1,16 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.AutoCompleteTextView
|
||||
import androidx.compose.Composable
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.ui.core.ContextAmbient
|
||||
import androidx.ui.foundation.Text
|
||||
import androidx.ui.input.ImeAction
|
||||
import androidx.ui.layout.*
|
||||
import androidx.ui.material.MaterialTheme
|
||||
import androidx.ui.material.OutlinedButton
|
||||
import androidx.ui.tooling.preview.Preview
|
||||
import androidx.ui.unit.dp
|
||||
import com.geeksville.analytics.DataPair
|
||||
import com.geeksville.android.GeeksvilleApplication
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.Channel
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.model.toHumanString
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
|
||||
object ChannelLog : Logging
|
||||
|
|
@ -68,7 +54,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@Composable
|
||||
fun ChannelContent(channel: Channel?) {
|
||||
|
||||
|
|
@ -165,12 +151,4 @@ fun ChannelContent(channel: Channel?) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun previewChannel() {
|
||||
// another bug? It seems modaldrawerlayout not yet supported in preview
|
||||
MaterialTheme(colors = palette) {
|
||||
ChannelContent(Channel.emulated)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.core.setContent
|
||||
|
||||
fun androidx.fragment.app.Fragment.setComposable(
|
||||
id: Int,
|
||||
content: @Composable() () -> Unit
|
||||
): View? =
|
||||
context?.let {
|
||||
FrameLayout(it).apply {
|
||||
this.isClickable = true
|
||||
this.id =
|
||||
id // Compose requires a unique ID for the containing view to make savedInstanceState work
|
||||
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
setContent(content)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open class ComposeFragment(
|
||||
screenName: String,
|
||||
id: Int,
|
||||
private val content: @Composable() () -> Unit
|
||||
) : ScreenFragment(screenName) {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? =
|
||||
FrameLayout(context!!).apply {
|
||||
this.isClickable = true
|
||||
this.id =
|
||||
id // Compose requires a unique ID for the containing view to make savedInstanceState work
|
||||
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
setContent(content)
|
||||
}
|
||||
|
||||
/* override fun onStart() {
|
||||
super.onStart()
|
||||
(view as ViewGroup).setContent(content)
|
||||
} */
|
||||
}
|
||||
|
|
@ -5,10 +5,12 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.NodeDB
|
||||
import com.geeksville.mesh.model.UIState
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.mapbox.geojson.Feature
|
||||
import com.mapbox.geojson.FeatureCollection
|
||||
import com.mapbox.geojson.Point
|
||||
|
|
@ -30,6 +32,8 @@ import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
|
|||
|
||||
class MapFragment : ScreenFragment("Map"), Logging {
|
||||
|
||||
private val model: UIViewModel by activityViewModels()
|
||||
|
||||
private val nodeSourceId = "node-positions"
|
||||
private val nodeLayerId = "node-layer"
|
||||
private val labelLayerId = "label-layer"
|
||||
|
|
@ -52,56 +56,61 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
textAllowOverlap(true)
|
||||
)
|
||||
|
||||
private fun nodesWithPosition() = NodeDB.nodes.values.filter { it.validPosition != null }
|
||||
|
||||
/**
|
||||
* Using the latest nodedb, generate geojson features
|
||||
*/
|
||||
private fun getCurrentNodes(): FeatureCollection {
|
||||
// Find all nodes with valid locations
|
||||
private fun onNodesChanged(map: MapboxMap, nodes: Collection<NodeInfo>) {
|
||||
val nodesWithPosition = nodes.filter { it.validPosition != null }
|
||||
|
||||
val locations = nodesWithPosition().map { node ->
|
||||
val p = node.position!!
|
||||
debug("Showing on map: $node")
|
||||
/**
|
||||
* Using the latest nodedb, generate geojson features
|
||||
*/
|
||||
fun getCurrentNodes(): FeatureCollection {
|
||||
// Find all nodes with valid locations
|
||||
|
||||
val f = Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
p.longitude,
|
||||
p.latitude
|
||||
val locations = nodesWithPosition.map { node ->
|
||||
val p = node.position!!
|
||||
debug("Showing on map: $node")
|
||||
|
||||
val f = Feature.fromGeometry(
|
||||
Point.fromLngLat(
|
||||
p.longitude,
|
||||
p.latitude
|
||||
)
|
||||
)
|
||||
)
|
||||
node.user?.let {
|
||||
f.addStringProperty("name", it.longName)
|
||||
node.user?.let {
|
||||
f.addStringProperty("name", it.longName)
|
||||
}
|
||||
f
|
||||
}
|
||||
f
|
||||
|
||||
return FeatureCollection.fromFeatures(locations)
|
||||
}
|
||||
|
||||
return FeatureCollection.fromFeatures(locations)
|
||||
}
|
||||
fun zoomToNodes(map: MapboxMap) {
|
||||
if (nodesWithPosition.isNotEmpty()) {
|
||||
val update = if (nodesWithPosition.size >= 2) {
|
||||
// Multiple nodes, make them all fit on the map view
|
||||
val bounds = LatLngBounds.Builder()
|
||||
|
||||
private fun zoomToNodes(map: MapboxMap) {
|
||||
val nodes = nodesWithPosition()
|
||||
if (nodes.isNotEmpty()) {
|
||||
val update = if (nodes.size >= 2) {
|
||||
// Multiple nodes, make them all fit on the map view
|
||||
val bounds = LatLngBounds.Builder()
|
||||
// Add all positions
|
||||
bounds.includes(nodes.map { it.position!! }
|
||||
.map { LatLng(it.latitude, it.longitude) })
|
||||
|
||||
// Add all positions
|
||||
bounds.includes(nodes.map { it.position!! }
|
||||
.map { LatLng(it.latitude, it.longitude) })
|
||||
CameraUpdateFactory.newLatLngBounds(bounds.build(), 150)
|
||||
} else {
|
||||
// Only one node, just zoom in on it
|
||||
val it = nodesWithPosition[0].position!!
|
||||
|
||||
CameraUpdateFactory.newLatLngBounds(bounds.build(), 150)
|
||||
} else {
|
||||
// Only one node, just zoom in on it
|
||||
val it = nodes[0].position!!
|
||||
|
||||
val cameraPos = CameraPosition.Builder().target(
|
||||
LatLng(it.latitude, it.longitude)
|
||||
).zoom(9.0).build()
|
||||
CameraUpdateFactory.newCameraPosition(cameraPos)
|
||||
val cameraPos = CameraPosition.Builder().target(
|
||||
LatLng(it.latitude, it.longitude)
|
||||
).zoom(9.0).build()
|
||||
CameraUpdateFactory.newCameraPosition(cameraPos)
|
||||
}
|
||||
map.animateCamera(update, 1000)
|
||||
}
|
||||
map.animateCamera(update, 1000)
|
||||
}
|
||||
|
||||
nodePositions.setGeoJson(getCurrentNodes()) // Update node positions
|
||||
zoomToNodes(map)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
|
@ -115,12 +124,12 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
mapView = view.findViewById(R.id.mapView)
|
||||
mapView.onCreate(UIState.savedInstanceState)
|
||||
mapView.onCreate(savedInstanceState)
|
||||
|
||||
mapView.getMapAsync { map ->
|
||||
|
||||
// val markerIcon = BitmapFactory.decodeResource(context.resources, R.drawable.ic_twotone_person_pin_24)
|
||||
val markerIcon = activity!!.getDrawable(R.drawable.ic_twotone_person_pin_24)!!
|
||||
val markerIcon = requireActivity().getDrawable(R.drawable.ic_twotone_person_pin_24)!!
|
||||
|
||||
map.setStyle(Style.OUTDOORS) { style ->
|
||||
style.addSource(nodePositions)
|
||||
|
|
@ -129,6 +138,10 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
style.addLayer(labelLayer)
|
||||
}
|
||||
|
||||
model.nodeDB.nodes.observe(viewLifecycleOwner, Observer { nodes ->
|
||||
onNodesChanged(map, nodes.values)
|
||||
})
|
||||
|
||||
//map.uiSettings.isScrollGesturesEnabled = true
|
||||
//map.uiSettings.isZoomGesturesEnabled = true
|
||||
}
|
||||
|
|
@ -152,11 +165,6 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView.onResume()
|
||||
|
||||
mapView.getMapAsync { map ->
|
||||
nodePositions.setGeoJson(getCurrentNodes()) // Update node positions
|
||||
zoomToNodes(map)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import androidx.ui.material.lightColorPalette
|
||||
import com.geeksville.android.Logging
|
||||
|
||||
|
||||
object UILog : Logging
|
||||
|
||||
/*
|
||||
val palette = lightColorPalette() // darkColorPalette()
|
||||
|
||||
/*
|
||||
|
||||
@Composable
|
||||
fun MeshApp() {
|
||||
val (drawerState, onDrawerStateChange) = state { DrawerState.Closed }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
import androidx.compose.Composable
|
||||
import androidx.compose.state
|
||||
import androidx.ui.core.Modifier
|
||||
|
|
@ -31,9 +32,7 @@ val TimestampEmphasis = object : Emphasis {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* A pretty version the text, with user icon to the left, name and time of arrival (copy slack look and feel)
|
||||
*/
|
||||
/// A pretty version the text, with user icon to the left, name and time of arrival (copy slack look and feel)
|
||||
@Composable
|
||||
fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) {
|
||||
Row(modifier = modifier) {
|
||||
|
|
@ -112,11 +111,4 @@ fun MessagesContent() {
|
|||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun previewMessagesView() {
|
||||
// another bug? It seems modaldrawerlayout not yet supported in preview
|
||||
MaterialTheme(colors = palette) {
|
||||
MessagesContent()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.foundation.Text
|
||||
import androidx.ui.layout.*
|
||||
|
|
@ -13,22 +14,7 @@ import com.geeksville.mesh.model.NodeDB
|
|||
import androidx.ui.core.Modifier as Modifier1
|
||||
|
||||
|
||||
/*
|
||||
@Composable
|
||||
fun NodeIcon(modifier: Modifier1 = Modifier1.None, node: NodeInfo) {
|
||||
Column {
|
||||
Container(modifier = modifier + LayoutSize(40.dp, 40.dp)) {
|
||||
VectorImage(id = if (node.user?.shortName != null) R.drawable.person else R.drawable.help)
|
||||
}
|
||||
|
||||
// Show our shortname if possible
|
||||
/* node.user?.shortName?.let {
|
||||
Text(it)
|
||||
} */
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Composable
|
||||
fun CompassHeading(modifier: Modifier1 = Modifier1.None, node: NodeInfo) {
|
||||
|
|
@ -81,11 +67,4 @@ fun NodeInfoCard(node: NodeInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun nodeInfoPreview() {
|
||||
Column {
|
||||
NodeInfoCard(NodeDB.testNodes[0])
|
||||
NodeInfoCard(NodeDB.testNodeNoPosition)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
import androidx.compose.Composable
|
||||
import androidx.compose.state
|
||||
import androidx.ui.core.ContextAmbient
|
||||
|
|
@ -68,12 +69,4 @@ fun SettingsContent() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun previewSettings() {
|
||||
// another bug? It seems modaldrawerlayout not yet supported in preview
|
||||
MaterialTheme(colors = palette) {
|
||||
SettingsContent()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
data class ScreenInfo(val icon: Int, val label: String)
|
||||
|
||||
// defines the screens we have in the app
|
||||
object Screen {
|
||||
val settings = ScreenInfo(R.drawable.ic_twotone_settings_applications_24, "Settings")
|
||||
val channel = ScreenInfo(R.drawable.ic_twotone_contactless_24, "Channel")
|
||||
val users = ScreenInfo(R.drawable.ic_twotone_people_24, "Users")
|
||||
val messages = ScreenInfo(R.drawable.ic_twotone_message_24, "Messages")
|
||||
val map = ScreenInfo(R.drawable.ic_twotone_map_24, "Map")
|
||||
}
|
||||
|
||||
|
||||
@Model
|
||||
object AppStatus {
|
||||
var currentScreen: ScreenInfo = Screen.messages
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Temporary solution pending navigation support.
|
||||
*/
|
||||
fun navigateTo(destination: ScreenInfo) {
|
||||
AppStatus.currentScreen = destination
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import androidx.compose.Composable
|
||||
import androidx.compose.state
|
||||
import androidx.ui.core.Modifier
|
||||
import androidx.ui.foundation.TextField
|
||||
import androidx.ui.foundation.shape.corner.RoundedCornerShape
|
||||
import androidx.ui.graphics.Color
|
||||
import androidx.ui.input.ImeAction
|
||||
import androidx.ui.input.KeyboardType
|
||||
import androidx.ui.input.VisualTransformation
|
||||
import androidx.ui.layout.LayoutPadding
|
||||
import androidx.ui.material.Emphasis
|
||||
import androidx.ui.material.MaterialTheme
|
||||
import androidx.ui.material.ProvideEmphasis
|
||||
import androidx.ui.material.Surface
|
||||
import androidx.ui.text.TextStyle
|
||||
import androidx.ui.unit.dp
|
||||
|
||||
|
||||
val HintEmphasis = object : Emphasis {
|
||||
override fun emphasize(color: Color) = color.copy(alpha = 0.05f)
|
||||
}
|
||||
|
||||
|
||||
/// A text field that visually conveys that it is editable - FIXME, once Compose has material
|
||||
/// design text fields use that instead.
|
||||
@Composable
|
||||
fun StyledTextField(
|
||||
value: String,
|
||||
modifier: Modifier = Modifier.None,
|
||||
onValueChange: (String) -> Unit = {},
|
||||
textStyle: TextStyle = TextStyle.Default,
|
||||
keyboardType: KeyboardType = KeyboardType.Text,
|
||||
imeAction: ImeAction = ImeAction.Unspecified,
|
||||
onFocus: () -> Unit = {},
|
||||
onBlur: () -> Unit = {},
|
||||
focusIdentifier: String? = null,
|
||||
onImeActionPerformed: (ImeAction) -> Unit = {},
|
||||
visualTransformation: VisualTransformation? = null,
|
||||
hintText: String = ""
|
||||
) {
|
||||
val backgroundColor = palette.secondary.copy(alpha = 0.12f)
|
||||
Surface(
|
||||
modifier = LayoutPadding(8.dp),
|
||||
color = backgroundColor,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
) {
|
||||
val showingHint = state { value.isEmpty() }
|
||||
val level = if (showingHint.value) HintEmphasis else MaterialTheme.emphasisLevels.medium
|
||||
|
||||
ProvideEmphasis(level) {
|
||||
TextField(
|
||||
value.ifEmpty { if (showingHint.value) hintText else "" },
|
||||
modifier + LayoutPadding(4.dp),
|
||||
onValueChange,
|
||||
textStyle,
|
||||
keyboardType,
|
||||
imeAction,
|
||||
{
|
||||
showingHint.value = false // Stop showing the hint now
|
||||
onFocus()
|
||||
},
|
||||
{
|
||||
// if the string is empty again, return to the hint text
|
||||
showingHint.value = value.isEmpty()
|
||||
onBlur()
|
||||
},
|
||||
focusIdentifier,
|
||||
onImeActionPerformed,
|
||||
visualTransformation
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.core.Modifier
|
||||
import androidx.ui.foundation.Text
|
||||
|
|
@ -34,11 +35,4 @@ fun UserIcon(user: NodeInfo? = null, modifier: Modifier = Modifier.None) {
|
|||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun previewUserIcon() {
|
||||
// another bug? It seems modaldrawerlayout not yet supported in preview
|
||||
MaterialTheme(colors = palette) {
|
||||
UserIcon(NodeDB.testNodes[1])
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
/*
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.core.ContextAmbient
|
||||
import androidx.ui.foundation.Text
|
||||
|
|
@ -16,14 +17,7 @@ import com.geeksville.mesh.service.RadioInterfaceService
|
|||
import com.geeksville.mesh.service.SoftwareUpdateService
|
||||
|
||||
|
||||
/// Given a human name, strip out the first letter of the first three words and return that as the initials for
|
||||
/// that user.
|
||||
fun getInitials(name: String): String {
|
||||
val words = name.split(Regex("\\s+")).filter { it.isNotEmpty() }.take(3).map { it.first() }
|
||||
.joinToString("")
|
||||
|
||||
return words
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UsersContent() {
|
||||
|
|
@ -88,3 +82,5 @@ fun UsersContent() {
|
|||
} */
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.Composable
|
||||
import androidx.ui.core.Modifier
|
||||
import androidx.ui.foundation.Icon
|
||||
import androidx.ui.graphics.Color
|
||||
import androidx.ui.graphics.vector.drawVector
|
||||
import androidx.ui.layout.Container
|
||||
import androidx.ui.layout.LayoutSize
|
||||
import androidx.ui.material.IconButton
|
||||
import androidx.ui.res.vectorResource
|
||||
|
||||
|
||||
@Composable
|
||||
fun VectorImageButton(@DrawableRes id: Int, onClick: () -> Unit) {
|
||||
//Ripple(bounded = false) {
|
||||
IconButton(onClick = onClick) {
|
||||
Icon(vectorResource(id) /* , modifier = LayoutSize(40.dp, 40.dp) */)
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
/* fun AppBarIcon(icon: Image, onClick: () -> Unit) {
|
||||
Container(width = ActionIconDiameter, height = ActionIconDiameter) {
|
||||
Ripple(bounded = false) {
|
||||
Clickable(onClick = onClick) {
|
||||
SimpleImage(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
@Composable
|
||||
fun VectorImage(
|
||||
modifier: Modifier = Modifier.None, @DrawableRes id: Int,
|
||||
tint: Color = Color.Transparent
|
||||
) {
|
||||
val vector = vectorResource(id)
|
||||
// WithDensity {
|
||||
Container(
|
||||
modifier = modifier + LayoutSize(
|
||||
vector.defaultWidth,
|
||||
vector.defaultHeight
|
||||
) + drawVector(vector, tint)
|
||||
) {
|
||||
}
|
||||
// }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue