Include a lambda inside an if..else statement - kotlin

I have the following function:
fun ValueListItem(
label: String,
value: String,
onClick: (() -> Unit)? = null
) {
}
But calling it like this is not allowed:
var edited = false
ValueListItem(
label = "my label",
value = "some value",
onClick = if (viewmodel.canEdit) { edited = true } else null
)
But calling it like this is allowed:
var edited = false
val onEditDateTime = {
edited = true
}
ValueListItem(
label = "my label",
value = "some value",
onClick = if (viewmodel.canEdit) onEditDateTime else null
)
How can I pass the lambda in a conditional statement rather than having to declare the lambda as an extra construct.

By writing
ValueListItem(
label = "my label",
value = "some value",
onClick = if (viewmodel.canEdit) { edited = true } else null
)
The compiler sees the braces as part of the if-statement syntax.
Simply adding another pair of braces like this should do the trick I think
ValueListItem(
label = "my label",
value = "some value",
onClick = if (viewmodel.canEdit) {{ edited = true }} else null
)

Related

Row drawn over columns in compose for desktop

I am developing a little application in compose for desktop on my windows machine. I put a OutlinedTextField into a column, which is in row. The problem is, that I cant see any text within it. Neither the default, nor am I able to edit the text. The box is focusable, but not editable.
I discovered, that the row is drawn above of my column. I assume that the row is swallow the event, or overpaint the text. I tried to set the z-index to high, but it didn't have any effect.
#Composable
fun menuInLeftSplitContent() = Row(Modifier.padding(all 5.dp).zIndex(-1F).background(Color
.Black)) {
Column {
IconButton(modifier = Modifier.padding(end = 5.dp), onClick = {}) {
Icon(Icons.Rounded.Add, "Add")
}
}
Column(modifier = Modifier.zIndex(20F)) {
val mutableText = mutableStateOf("Hello World")
OutlinedTextField(
value = mutableText.value,
onValueChange = { },
modifier = Modifier.fillMaxSize(),
singleLine = true,
leadingIcon = { Icons.Filled.Search },
enabled = true,
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Characters,
autoCorrect = false,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.None
),
maxLines = 1,
readOnly = false
)
}}
If the column wasn't overpainted by the row, you would see the picture beneath.
This is how it should look like.

Problems with Photoshop's onChanging function

I'm trying to change some label text depending on the state of a checkbox for Photoshop Script UI. Only it's not updating at all. No idea why.
Ideally I'd like it to say "Some text" when ticked and "Some other text" when left unchecked. And change dynamically.
Here's my code
// DIALOG
// ======
var dlg = new Window("dialog");
dlg.text = "Title";
dlg.preferredSize.width = 180;
dlg.preferredSize.height = 100;
dlg.orientation = "column";
dlg.alignChildren = ["center","top"];
dlg.spacing = 10;
dlg.margins = 16;
var statictext1 = dlg.add("statictext", undefined, undefined, {name: "statictext1"});
statictext1.text = "Some static text";
statictext1.justify = "center";
var checkbox1 = dlg.add("checkbox", undefined, undefined, {name: "checkbox1"});
checkbox1.text = "Some text";
checkbox1.value = true;
// GROUP1
// ======
var group1 = dlg.add("group", undefined, {name: "group1"});
group1.orientation = "row";
group1.alignChildren = ["left","center"];
group1.spacing = 10;
group1.margins = 0;
// add buttons
group1.add ("button", undefined, "OK");
group1.add ("button", undefined, "Cancel");
// Define behavior for when the slider value changes
dlg.checkbox1.onChanging = function()
{
var textArr = ["Some text", "Some other text"]
var val = dlg.checkbox1.value;
// Update the label text with the current checkbox value.
dlg.checkbox1.text = textArr[val];
}
var myReturn = dlg.show();
The Checkbox control fires the onClick event and not the onChanging event.
The only controls that fire the onChanging event are:
EditText
Scrollbar
Slider
Therefore consider changing this part in your script:
// Define behavior for when the slider value changes
dlg.checkbox1.onChanging = function() {
// ...
}
to the following instead:
// Define behavior for when the checkbox value changes
dlg.checkbox1.onClick = function() {
var textArr = ["Some text", "Some other text"]
var val = checkbox1.value ? textArr[0] : textArr[1];
statictext1.text = val;
}
Explanation
In the body of the preceding function for the onClick event, i.e. the part that reads;
var val = checkbox1.value ? textArr[0] : textArr[1];
we utilize the conditional (ternary) operator to check the value property of checkbox1. If checkbox1 is checked (true) we assign the string "Some text" to the val variable, otherwise if checkbox1 is unchecked (false) we assign the string "Some other text" to the val variable instead.
Additional changes:
The following changes also need to be carried out:
As checkbox1's initial value is set to true, i.e. it's checked, you'll need to change line number 13 from this:
statictext1.text = "Some static text";
to this:
statictext1.text = "Some text";
Also consider setting the size property for statictext1. As you can see on line number 15 below the following has been added:
statictext1.size = [180, 20];
This will ensure it's width accomodates the "Some other text" string.
Revised script:
Here is the full revised script:
// DIALOG
// ======
var dlg = new Window("dialog");
dlg.text = "Title";
dlg.preferredSize.width = 180;
dlg.preferredSize.height = 100;
dlg.orientation = "column";
dlg.alignChildren = ["center","top"];
dlg.spacing = 10;
dlg.margins = 16;
var statictext1 = dlg.add("statictext", undefined, undefined, {name: "statictext1"});
statictext1.text = "Some text"; // <--- Note: Also change this !
statictext1.justify = "center";
statictext1.size = [180, 20]; // <--- Note: Also set the width/height !
var checkbox1 = dlg.add("checkbox", undefined, undefined, {name: "checkbox1"});
checkbox1.text = "Some text";
checkbox1.value = true;
// GROUP1
// ======
var group1 = dlg.add("group", undefined, {name: "group1"});
group1.orientation = "row";
group1.alignChildren = ["left","center"];
group1.spacing = 10;
group1.margins = 0;
// add buttons
group1.add ("button", undefined, "OK");
group1.add ("button", undefined, "Cancel");
// Define behavior for when the checkbox value changes
dlg.checkbox1.onClick = function() {
var textArr = ["Some text", "Some other text"]
var val = checkbox1.value ? textArr[0] : textArr[1];
statictext1.text = val;
}
var myReturn = dlg.show();

How to save to TextField database transformed with visualTransformation

How to save to TextField database transformed with visualTransformation?
I have the following code:
var text by remember { mutableStateOf("") }
TextField(
value = text,
visualTransformation = DateTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = {
if (it.length < 9) text = it
}
)
Log.i("DATA",text)
the format is XX/XX/XXXX but when I send it to the database it loses the format and is XXXXXXXX
You can apply same transformations your VisualTransformation does using filter like this:
val visualTransformation: VisualTransformation = remember { DateTransformation() }
var text by remember { mutableStateOf("") }
Button(onClick = {
val transformedText = visualTransformation.filter(AnnotatedString(text)).text.text
// save to DB
}) {
}
TextField(
value = text, onValueChange = { text = it },
visualTransformation = visualTransformation
)

DecorationBox in Jetpack Compose BasicTextField

I use jetpack compose create a editText,I want to show a hint like before "android:hint",
so I try to use decorationBox,but after I created it the input isn't displayed and the log can display my input content.
this is my code,
val passState= remember { mutableStateOf(TextFieldValue("")) }
BasicTextField(
decorationBox = {
Text("password",color = loginGrayColor)
},
value = passState.value,
onValueChange = { passState.value = it ; Log.d("password",it.text) },
singleLine = true,
maxLines = 1,
textStyle = TextStyle(
fontSize = 15.sp,
color = loginInputTextColor
),
modifier = Modifier
.padding(start = 10.dp, top = 10.dp)
.height(20.dp)
)
You have to add the innerTextField provided by the decorationBox.
Something like:
var value by remember { mutableStateOf(TextFieldValue("")) }
BasicTextField(
value = value,
onValueChange = { value = it },
decorationBox = { innerTextField ->
Row(
Modifier
.background(Color.LightGray, RoundedCornerShape(percent = 30))
.padding(16.dp)
) {
if (value.text.isEmpty()) {
Text("Label")
}
innerTextField() //<-- Add this
}
},
)
If you would like to have the cursor start at the beginning of the placeholder label, put the decorationBox content inside a Box rather than a Row.

how to close the dropdown popup on clicking of outside the dropdown popup window?

I am Using jetbrain compose 2020.3.3 version and i am implementing Dropdown example similar as mentioned below code. as per my analysis "DropDownmenu" internally using the "Popup" and by default popup focusable is false and there is no option in "Dropdownmenu" to make it true so when dropdown list is expanded ,Clicking outside ther dropdownlist is not closing dropdown list. it seems Expanded dropdown list is acting as blocking popup
`
#Composable
fun DropdownDemo() {
var expanded = remember { mutableStateOf(false) }
val items = listOf("A", "B", "C", "D", "E", "F")
val disabledValue = "B"
var selectedIndex = remember { mutableStateOf(0) }
Box(modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.TopStart)) {
Text(items[selectedIndex.value],modifier = Modifier.fillMaxWidth().clickable(onClick = { expanded.value = true }).background(
Color.Gray))
DropdownMenu(
expanded = expanded.value,
onDismissRequest = { expanded.value = false },
modifier = Modifier.fillMaxWidth().background(
Color.Red)
) {
items.forEachIndexed { index, s ->
DropdownMenuItem(onClick = {
selectedIndex.value = index
expanded.value = false
}) {
val disabledText = if (s == disabledValue) {
" (Disabled)"
} else {
""
}
Text(text = s + disabledText)
}
}
}
}
}`