Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@liutikas
Last active September 28, 2020 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liutikas/d8d37576921aed83b55ac649b0bbd710 to your computer and use it in GitHub Desktop.
Save liutikas/d8d37576921aed83b55ac649b0bbd710 to your computer and use it in GitHub Desktop.
Compose Gray UI
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.myapplication
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.animate
import androidx.compose.animation.core.*
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.ButtonConstants
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.inset
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import androidx.ui.tooling.preview.Preview
import com.android.myapplication.ui.MyApplicationTheme
import com.android.myapplication.ui.darkGray
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting()
}
}
}
}
}
@Composable
fun Greeting() {
Column(modifier = Modifier.fillMaxHeight().fillMaxWidth()) {
Row(verticalAlignment = Alignment.CenterVertically) {
GrayCheckBox(Modifier.padding(8.dp))
Text(text = "Use precompiled header files")
}
Row {
GrayTextField(Modifier.padding(start = 32.dp))
}
Row(verticalAlignment = Alignment.CenterVertically) {
GrayCheckBox(Modifier.padding(8.dp))
Text(text = "Ignore obsolete keywords")
}
Row(verticalAlignment = Alignment.CenterVertically) {
GrayCheckBox(Modifier.padding(8.dp), true)
Text(text = "Make .OBJ the default extension")
}
GrayBorder(label = "Margins") {
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Left")
GrayTextField(Modifier.width(100.dp).padding(start = 8.dp, end = 8.dp), "1")
Text("Right")
GrayTextField(Modifier.width(100.dp).padding(start = 8.dp, end = 8.dp), "*")
Text("[1-65535,*]")
}
}
Row(verticalAlignment = Alignment.CenterVertically) {
GrayButton() {
Text("Reset Page")
}
}
val goingUp = remember { mutableStateOf(false) }
val progress = animate(
target = if (goingUp.value) 10 else 0,
animSpec = TweenSpec(delay = 200, durationMillis = 2000, easing = LinearEasing),
endListener = { goingUp.value = !goingUp.value }
)
GrayProgressBar(Modifier.padding(8.dp), progress = progress)
}
}
private val CheckboxSize = 20.dp
@Composable
fun GrayCheckBox(
modifier: Modifier = Modifier,
initialValue: Boolean = false
) {
val checked = remember { mutableStateOf(initialValue) }
Canvas(modifier.wrapContentSize(Alignment.Center)
.size(CheckboxSize)
.toggleable(
value = checked.value ,
onValueChange = {checked.value = it},
indication = null
)
) {
drawRect(Color.Black, style = Stroke(2.dp.toPx()))
if (checked.value) {
val size = CheckboxSize.toPx()
drawLine(
Color.Black,
start = Offset(0f,0f),
end = Offset(size, size),
strokeWidth = 2.dp.toPx()
)
drawLine(
Color.Black,
start = Offset(size,0f),
end = Offset(0f, size),
strokeWidth = 2.dp.toPx()
)
}
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GrayTextField(modifier: Modifier = Modifier, initialValue: String = "") {
val userValue = remember { mutableStateOf(TextFieldValue(initialValue)) }
BaseTextField(
modifier = modifier.drawBehind {
drawRect(Color.White, style = Fill)
drawRect(Color.Black, style = Stroke(2.dp.toPx()))
}.padding(8.dp),
value = userValue.value,
onValueChange = { userValue.value = it }
)
}
@Composable
fun GrayBorder(
modifier: Modifier = Modifier,
label: String,
content: @Composable () -> Unit
) {
Stack(Modifier.drawBehind {
inset(8.dp.toPx(), 8.dp.toPx()) {
drawRect(Color.Black, style = Stroke(2.dp.toPx()))
}
}) {
Text(
label,
Modifier.padding(start = 32.dp)
.background(MaterialTheme.colors.background)
.padding(start = 4.dp, end = 4.dp),
style = MaterialTheme.typography.subtitle2
)
Stack(modifier.padding(24.dp)) {
content()
}
}
}
@Preview(showBackground = true)
@Composable
fun GrayBorderPreview() {
MyApplicationTheme {
GrayBorder(label = "Margins") { Text("Hello", modifier = Modifier.fillMaxWidth()) }
}
}
@Composable
fun GrayButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
content: @Composable RowScope.() -> Unit
) {
val state = remember { InteractionState() }
Stack(modifier.clickable(onClick = onClick, interactionState = state, indication = null)) {
Canvas(modifier.matchParentSize().padding(2.dp)) {
val isPressed = state.value.contains(Interaction.Pressed)
val width = this.size.width
val height = this.size.height
val oneDp = 1.dp.toPx()
val outerStroke = 2.dp.toPx()
drawLine(
Color.Black,
start = Offset(oneDp, 0f),
end = Offset(width - oneDp, 0f),
strokeWidth = outerStroke
)
drawLine(
Color.Black,
start = Offset(oneDp, height),
end = Offset(width - oneDp, height),
strokeWidth = outerStroke
)
drawLine(
Color.Black,
start = Offset(0f, oneDp),
end = Offset(0f, height - oneDp),
strokeWidth = outerStroke
)
drawLine(
Color.Black,
start = Offset(width, oneDp),
end = Offset(width, height - oneDp),
strokeWidth = outerStroke
)
val topStartColor = if (isPressed) darkGray else Color.White
val bottomEndColor = if (isPressed) Color.White else darkGray
val innerStroke = 4.dp.toPx()
drawLine(
topStartColor,
start = Offset(oneDp, outerStroke + oneDp),
end = Offset(width - oneDp, outerStroke + oneDp),
strokeWidth = innerStroke
)
drawLine(
topStartColor,
start = Offset(outerStroke + oneDp, oneDp),
end = Offset(outerStroke + oneDp, height - oneDp),
strokeWidth = innerStroke
)
drawLine(
bottomEndColor,
start = Offset(oneDp, height - outerStroke - oneDp),
end = Offset(width - oneDp, height - outerStroke - oneDp),
strokeWidth = innerStroke
)
drawLine(
bottomEndColor,
start = Offset(width - outerStroke - oneDp, oneDp),
end = Offset(width - outerStroke - oneDp, height - oneDp),
strokeWidth = innerStroke
)
}
Row(
Modifier
.defaultMinSizeConstraints(
minWidth = ButtonConstants.DefaultMinWidth,
minHeight = ButtonConstants.DefaultMinHeight
)
.padding(8.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
children = content
)
}
}
@Preview(showBackground = true)
@Composable
fun GrayButtonPreview() {
MyApplicationTheme {
GrayButton() {
Text("Hello")
}
}
}
@Composable
fun GrayProgressBar(
modifier: Modifier = Modifier,
progress: Int = 0) {
Canvas(modifier = modifier.width(200.dp).height(32.dp)) {
drawRect(Color.Black, style = Stroke(2.dp.toPx()))
val entryHeight = 24.dp.toPx()
val entryGap = 4.dp.toPx()
val entryWidth = ((size.width - entryGap) / 10) - entryGap
for (i in 0 until progress) {
drawRect(
Color.Black,
style = Fill,
size = Size(entryWidth, entryHeight),
topLeft = Offset(entryGap + i * (entryWidth + entryGap) , entryGap)
)
}
}
}
@Preview
@Composable
fun GrayProgressBarPreview() {
MyApplicationTheme {
GrayProgressBar()
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MyApplicationTheme {
Greeting()
}
}
@JoseAlcerreca
Copy link

Copyright 👮

@liutikas
Copy link
Author

Copyright 👮

👍 now?

@JoseAlcerreca
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment