How to add Default Key Behavior with Jetpack Compose Desktop UI? - kotlin

I need to upgrade a Desktop App which used Jetpack Compose 0.4.0. There, some default behavior for KeyEvents was implemented like this, when pressing ctrl + q
private fun addDefaultKeyBehaviour(){
val key: Key = if(System.getProperty("os.name") == "Mac OS X") Key.MetaLeft else Key.CtrlLeft
LocalAppWindow.current.keyboard.setShortcut(KeysSet(setOf(key, Key.Q))){
AppManager.focusedWindow?.close()
}
...
}
I've now upgraded to Jetpack Compose 1.1.0 and as assumed, the code is not working anymore. I couldn't find a migrate script and in the tutorials, there are no examples shown. The functionality should be added globally like above, if it's still possible.
Would anyone know how to implement this? LocalAppWindow,KeysSet as well as AppManager are not existing anymore.

Related

how to convert BitMatrix to Painter/ImageBitmap/ImageVector without the use of android libraries? (for desktop application)

I am trying to generate a QR code within my desktop app. So, for the QRcode image, I am generating a BitMatrix of the QRCode. I am using the zxing library for this purpose since I didn't find anything else for the same.
BitMatrix generator -
import com.google.zxing.BarcodeFormat
import com.google.zxing.common.BitMatrix
import com.google.zxing.qrcode.QRCodeWriter
fun getMatrix(text: String, size: Int): BitMatrix {
return QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, size, size)
}
The problem I am encountering is that majority of the solutions are the same and they use this method
Bitmap.createBitmap(..., ..., ...)
This method uses the android libraries which aren't available when building a desktop app. So due to this reason, I haven't gotten a single correct answer on how to do this. All I want is how to convert a given text to a QR code which I can show in my desktop app. Also, latency isn't an issue. So, If you have a solution, do suggest without hesitation.

How do I use fonts in Jetpack Compose for Desktop?

I'm trying to use some font ttf files placed in src/main/resources/fonts/ in JetBrains Compose for Desktop. How do I use the font files in the function androidx.compose.ui.text.font.Font()? I tried using the R.fonts.font_file mentioned in many online articles, but it seems like it only works on Android.
I know that there's this. He's facing the exact same problem I'm having here. I've tried this. Unfortunately, it didn't work. The only answer in the question I linked above says that the solution was to put the font files in src/main/resources and use:
Font(
resource = "font.ttf",
weight = FontWeight.W400,
style = FontStyle.Normal,
)
But it doesn't work. The androidx.compose.ui.text.font.Font() function on my machine requires 3 params, resId, weight, and style.
public fun Font(
resId: Int,
weight: FontWeight,
style: FontStyle,
)
(copied from the Idea tooltip)
As you can see, it requires a resId: Int. How am I supposed to specify it in an Int?
Since JetBrains Compose for Desktop is still in its early beta stage, resources I could find on the web is really scarce. I tried searching for "kotlin resource id" to find the way to refer to the font file as an ID, but all I could find are really Android-targeted things. I also tried searching for "jetpack compose desktop font" and "jetbrains compose font", and the results I get are also flooded with Android things. Yes, I tried using "-android" in the search query, but all that's left in the results are irrelevant. The question I linked is the only thing I could find about Jetpack Compose for Desktop font.
Here's most of my project structure.
Here is the tooltip that IntelliJ Idea shows when I hover over Font(). It isn't that useful, is it?
Kotlin version: 1.5.10
Jetpack compose version: 0.5.0-build225 (latest pre-release)
By the way, I'm using Manjaro Linux on a MacBook if it matters.
You can't use androidx.compose.ui.text.font.Font for this. Import androidx.compose.ui.text.platform.Font instead.
Perhaps counter-intuitively, androidx.compose.ui.text.platform.Font is a valid parameter type in a androidx.compose.ui.text.font.FontFamily, and supports resource, weight and style.

Actions Class not working properly after ChromeDriver updated to newer version

I have updated my ChromeDriver to newest version (to 77). and noticed that previously working methods are not working now. Specifically Actions class is not working properly, its not sending data, not hitting enter.
for example this method is not clicking "Ctrl + F". it used to always click before chromedriver update. I am using pageFactory, this method below I am using in my actual scripts and it not sending keys
public void PressCtrlF() {
Actions a = new Actions(ldriver);
a.sendKeys(Keys.chord(Keys.CONTROL,"F")).build().perform();
}
it supposed to hit "Ctrl+F" and search box should appear
Anyone know how to resolve Actions class due to ChromeDriver update

Kotlin synthetic in Adapter or ViewHolder

I am new in kotlin. I have found and tried to use synthetic method instead of annoying method findViewById in my Activity class, but I have found "If we want to call the synthetic properties on View (useful in adapter classes), we should also import kotlinx.android.synthetic.main.view.*." But I can't figure out how it exactly works? Is there any examples?
Simple example from https://github.com/antoniolg/Kotlin-for-Android-Developers
import kotlinx.android.synthetic.item_forecast.view.*
class ForecastListAdapter() : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bindForecast(forecast: Forecast) {
itemView.date.text = forecast.date.toDateString()
}
}
}
No need to write
val view = itemView.findViewById(R.id.date) as TextView
view.text = forecast.date.toDateString()
Just
itemView.date.text = forecast.date.toDateString()
Simple and effective!
Kotling 1.1.4 out
Further information : https://antonioleiva.com/kotlin-android-extensions/
You need to enable Kotlin Android Extentions by adding this to your build.gradle:
apply plugin: 'org.jetbrains.kotlin.android.extensions'
androidExtensions {
experimental = true
}
Since this new version of Kotlin, the Android Extensions have incorporated some new interesting features: caches in any class (which interestingly includes ViewHolder)
Using it on a ViewHolder (or any custom class). Note that this class should implement LayoutContainer interface:
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView),
LayoutContainer {
fun bind(title: String) {
itemTitle.text = "Hello Kotlin!"
}
}
You need
import kotlinx.android.synthetic.row_wall.view.*
And later something along the lines of:
convertView.titleText.text = item.title
The point is that the view.* introduces extensions to the View class.
Try
class CustomViewModel(val baseView: View) {
val firstName = baseView.firstName
val lastName = baseView.lastName
}
View object exposes the views
ref:https://discuss.kotlinlang.org/t/unable-to-use-kotlin-android-extension-in-adapter-class/2890
If you are using the latest version l;.you don't have to add experimental = true to it.
in Project level Gradle
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21'
And in app level Gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' //These should be on the top of file.
and in dependencies..
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21'
and import below as
import kotlinx.android.synthetic.main.your_layout_file_name.view.*
and example
import kotlinx.android.synthetic.main.item_animal.view.*
class AnimalVH(parent: ViewGroup, layoutID: Int) : BaseViewHolder<Animal>(parent, layoutID) {
override fun bindData(animal: Animal) {
itemView.tv_animal.text = animal.title
}
}
where BaseViewHolder is
abstract class BaseViewHolder<T>(parent: ViewGroup, layoutID: Int) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(layoutID, parent, false)
) {
abstract fun bindData(model: T)
}
It means you have to place this line at the beginning of your source file:
import kotlinx.android.synthetic.main.view.*
So now instead of, for example, findView(R.id.textView) as TextView you would write just textView. The latter is a synthetic extension property located in the package kotlinx.android.synthetic.main.view, that's why you have to import everything from it.
There's a tutorial on the official site, take a look.
FYI: Data binding is recommended over synthetic for view lookups.
Comment from a DA for Android from Google on Reddit
Hey! Developer Advocate for Android at Google here!
I wanted to add a bit of background here. Kotlin Extensions with
synthetic views was never intentionally “recommended” though that
shouldn’t be taken as a recommendation to not use them. If they're
working for you please feel free to continue using them in your app!
We’ve been shifting away from them (e.g. we don’t teach them in the
Udacity course) because they expose a global namespace of ids that’s
unrelated to the layout that’s actually inflated with no checks
against invalid lookups, are Kotlin only, and don't expose nullability
when views are only present in some configuration. All together, these
issues cause the API to increase number of crashes for Android apps.
On the other hand, they do offer a lightweight API that can help
simplify view lookups. In this space it's also worth taking a look at
Data Binding which also does automatic view lookups - as well as
integrates with LiveData to automatically update your views as data
changes.
Today, there's a few options in this space that work:
Data Binding is the recommendation for view lookup as well as binding,
but it does add a bit of overhead when compared to Android Kotlin
Extensions. It's worth taking a look to see if this is a good fit for
your app. Data Binding also allows you to observe LiveData to bind
views automatically when data changes. Compared to Kotlin Extensions,
it adds compile time checking of view lookups and type safety. Android
Kotlin Extensions is not officially recommended (which is not the same
as recommendation against). It does come with the issues mentioned
above, so for our code we're not using them. Butter Knife is another
solution that is extremely popular and works for both Kotlin and the
Java Programming Language. Reading through the comments here there's a
lot of developers that are having great luck with Kotlin Extensions.
That's great - and something we'll keep in mind as we look at ways to
continue improving our APIs. If you haven't taken a look at Data
Binding, definitely give it a shot.
As an aside, our internal code style guide is not intended to be
directly applied outside of our codebase. For example, we use
mPrefixVariables, but there's no reason that every app should follow
that style.

Safari Extension: "on install" event?

I am developing an extension for Safari 6 and I want to set some default values for my settings. These default values depend on window.navigator.language, so setting them in Settings.plist does not the trick – I need to run some JS code to set them.
Obviously, this code should only run once right after install. And it shouldn't run after simply reenabling the extension.
Is there an "official" event that I can attach a function with addEventlistener to? Or do I really need the trick with setting a helper variable?
There is no official event that I know of. But it's pretty easy to do something like this in your global page:
if (!safari.extension.settings.hasRun) {
safari.extension.settings.hasRun = true;
safari.extension.settings.lang = window.navigator.language;
}