or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

desktop-application.mddesktop-components.mdgradle-plugin.mdindex.mdresource-management.mdui-tooling.md

desktop-components.mddocs/

0

# Desktop Components

1

2

Desktop components provide enhanced UI functionality specifically optimized for desktop platforms, including resizable panels, animated image support, and desktop-specific interactions.

3

4

## SplitPane Component

5

6

The SplitPane component allows creating resizable panels with a draggable splitter.

7

8

### Composable Functions

9

10

```kotlin { .api }

11

@ExperimentalSplitPaneApi

12

@Composable

13

fun HorizontalSplitPane(

14

modifier: Modifier = Modifier,

15

splitPaneState: SplitPaneState = rememberSplitPaneState(),

16

content: SplitPaneScope.() -> Unit

17

)

18

19

@ExperimentalSplitPaneApi

20

@Composable

21

fun VerticalSplitPane(

22

modifier: Modifier = Modifier,

23

splitPaneState: SplitPaneState = rememberSplitPaneState(),

24

content: SplitPaneScope.() -> Unit

25

)

26

```

27

28

### SplitPane State

29

30

```kotlin { .api }

31

@Stable

32

class SplitPaneState {

33

var positionPercentage: Float

34

fun dispatchRawMovement(delta: Float): Float

35

}

36

37

@ExperimentalSplitPaneApi

38

@Composable

39

fun rememberSplitPaneState(

40

initialPositionPercentage: Float = 0f,

41

moveEnabled: Boolean = true

42

): SplitPaneState

43

```

44

45

### SplitPane Scope

46

47

```kotlin { .api }

48

@ExperimentalSplitPaneApi

49

interface SplitPaneScope {

50

fun first(

51

minSize: Dp = 0.dp,

52

content: @Composable () -> Unit

53

)

54

55

fun second(

56

minSize: Dp = 0.dp,

57

content: @Composable () -> Unit

58

)

59

60

fun splitter(block: SplitterScope.() -> Unit)

61

}

62

63

@ExperimentalSplitPaneApi

64

interface SplitterScope {

65

fun visiblePart(content: @Composable () -> Unit)

66

fun handle(

67

alignment: SplitterHandleAlignment = SplitterHandleAlignment.ABOVE,

68

content: @Composable HandleScope.() -> Unit

69

)

70

}

71

72

@ExperimentalSplitPaneApi

73

interface HandleScope {

74

fun Modifier.markAsHandle(): Modifier

75

}

76

```

77

78

### Usage Example

79

80

```kotlin

81

import org.jetbrains.compose.splitpane.ExperimentalSplitPaneApi

82

import org.jetbrains.compose.splitpane.HorizontalSplitPane

83

import org.jetbrains.compose.splitpane.VerticalSplitPane

84

import org.jetbrains.compose.splitpane.rememberSplitPaneState

85

86

@OptIn(ExperimentalSplitPaneApi::class)

87

@Composable

88

fun SplitPaneExample() {

89

val horizontalSplitState = rememberSplitPaneState(initialPositionPercentage = 0.3f)

90

val verticalSplitState = rememberSplitPaneState(initialPositionPercentage = 0.7f)

91

92

HorizontalSplitPane(

93

splitPaneState = horizontalSplitState

94

) {

95

first {

96

// Left panel content

97

Box(

98

modifier = Modifier.fillMaxSize().background(Color.LightGray),

99

contentAlignment = Alignment.Center

100

) {

101

Text("Left Panel")

102

}

103

}

104

second {

105

VerticalSplitPane(

106

splitPaneState = verticalSplitState

107

) {

108

first {

109

// Top-right panel

110

Box(

111

modifier = Modifier.fillMaxSize().background(Color.Blue.copy(alpha = 0.3f)),

112

contentAlignment = Alignment.Center

113

) {

114

Text("Top Right Panel")

115

}

116

}

117

second {

118

// Bottom-right panel

119

Box(

120

modifier = Modifier.fillMaxSize().background(Color.Green.copy(alpha = 0.3f)),

121

contentAlignment = Alignment.Center

122

) {

123

Text("Bottom Right Panel")

124

}

125

}

126

}

127

}

128

}

129

}

130

```

131

132

## AnimatedImage Component

133

134

The AnimatedImage component provides support for displaying animated images like GIFs.

135

136

### Composable Functions

137

138

```kotlin { .api }

139

@Composable

140

fun AnimatedImage(

141

animatedImageLoader: AnimatedImageLoader,

142

modifier: Modifier = Modifier,

143

contentDescription: String? = null,

144

contentScale: ContentScale = ContentScale.Fit,

145

alignment: Alignment = Alignment.Center,

146

alpha: Float = DefaultAlpha,

147

colorFilter: ColorFilter? = null

148

)

149

```

150

151

### AnimatedImageLoader

152

153

```kotlin { .api }

154

interface AnimatedImageLoader {

155

suspend fun load(): AnimatedImageLoadResult

156

}

157

158

sealed class AnimatedImageLoadResult {

159

object Loading : AnimatedImageLoadResult()

160

class Success(val image: AnimatedImage) : AnimatedImageLoadResult()

161

class Error(val exception: Throwable) : AnimatedImageLoadResult()

162

}

163

164

abstract class AnimatedImage {

165

abstract val frames: List<ImageBitmap>

166

abstract val frameDelays: List<Int>

167

abstract fun intrinsicSize(): IntSize

168

}

169

```

170

171

### Image Loaders

172

173

```kotlin { .api }

174

class ResourceAnimatedImageLoader(

175

resourcePath: String

176

) : AnimatedImageLoader

177

178

class NetworkAnimatedImageLoader(

179

url: String,

180

httpClient: HttpClient? = null

181

) : AnimatedImageLoader

182

183

@Composable

184

fun LocalAnimatedImageLoader.current: AnimatedImageLoader

185

```

186

187

### Usage Example

188

189

```kotlin

190

import org.jetbrains.compose.animatedimage.AnimatedImage

191

import org.jetbrains.compose.animatedimage.ResourceAnimatedImageLoader

192

import org.jetbrains.compose.animatedimage.NetworkAnimatedImageLoader

193

import org.jetbrains.compose.animatedimage.LocalAnimatedImageLoader

194

195

@Composable

196

fun AnimatedImageExample() {

197

Column {

198

// Load from resources

199

AnimatedImage(

200

animatedImageLoader = ResourceAnimatedImageLoader("animations/loading.gif"),

201

modifier = Modifier.size(100.dp),

202

contentDescription = "Loading animation"

203

)

204

205

// Load from network

206

AnimatedImage(

207

animatedImageLoader = NetworkAnimatedImageLoader("https://example.com/animation.gif"),

208

modifier = Modifier.size(200.dp),

209

contentDescription = "Network animation",

210

contentScale = ContentScale.Crop

211

)

212

}

213

}

214

215

// Providing a default loader

216

@Composable

217

fun MyApp() {

218

CompositionLocalProvider(

219

LocalAnimatedImageLoader provides ResourceAnimatedImageLoader("default.gif")

220

) {

221

AnimatedImageExample()

222

}

223

}

224

```

225

226

## Resource Access

227

228

Desktop-specific resource loading utilities.

229

230

### ResourceEnvironment

231

232

```kotlin { .api }

233

object ResourceEnvironment {

234

fun isRunningFromJar(): Boolean

235

fun getResourcePath(resourcePath: String): String?

236

}

237

```

238

239

### ResourceReader

240

241

```kotlin { .api }

242

interface ResourceReader {

243

suspend fun read(path: String): ByteArray

244

suspend fun readText(path: String): String

245

}

246

247

object DesktopResourceReader : ResourceReader

248

```

249

250

### Usage Example

251

252

```kotlin

253

import org.jetbrains.compose.resources.ResourceReader

254

import org.jetbrains.compose.resources.ResourceEnvironment

255

256

@Composable

257

fun ResourceExample() {

258

var imageData by remember { mutableStateOf<ByteArray?>(null) }

259

260

LaunchedEffect(Unit) {

261

try {

262

imageData = DesktopResourceReader.read("images/icon.png")

263

} catch (e: Exception) {

264

println("Failed to load resource: ${e.message}")

265

}

266

}

267

268

imageData?.let { data ->

269

// Use the image data

270

Image(

271

bitmap = org.jetbrains.skia.Image.makeFromEncoded(data).toComposeImageBitmap(),

272

contentDescription = "App icon"

273

)

274

}

275

}

276

```

277

278

## Component Dependencies

279

280

Add desktop components to your project:

281

282

```kotlin

283

dependencies {

284

// SplitPane component (experimental)

285

implementation(compose.desktop.components.splitPane)

286

287

// AnimatedImage component (experimental)

288

implementation(compose.desktop.components.animatedImage)

289

290

// Resources support

291

implementation(compose.components.resources)

292

}

293

```

294

295

## Browser Component (Experimental)

296

297

The Browser component provides embedded web browser functionality using CEF (Chromium Embedded Framework).

298

299

### Browser Interface

300

301

```kotlin { .api }

302

interface Browser {

303

fun load(url: String)

304

}

305

306

class BrowserView : Browser {

307

override fun load(url: String)

308

fun view(): ComposeWindow

309

fun dismiss()

310

}

311

```

312

313

### Usage Example

314

315

```kotlin

316

import org.jetbrains.compose.desktop.browser.BrowserView

317

318

@Composable

319

fun BrowserExample() {

320

val browser = remember { BrowserView() }

321

322

Column {

323

Button(

324

onClick = { browser.load("https://example.com") }

325

) {

326

Text("Load Website")

327

}

328

329

Button(

330

onClick = { browser.dismiss() }

331

) {

332

Text("Close Browser")

333

}

334

}

335

}

336

```

337

338

## VideoPlayer Component (Experimental)

339

340

The VideoPlayer component provides video playback functionality using VLC backend.

341

342

### VideoPlayer Function

343

344

```kotlin { .api }

345

@Composable

346

fun VideoPlayerImpl(

347

url: String,

348

isResumed: Boolean = true,

349

volume: Float = 1f,

350

speed: Float = 1f,

351

seek: Long = 0,

352

isFullscreen: Boolean = false,

353

onFinish: () -> Unit = {}

354

)

355

```

356

357

### Usage Example

358

359

```kotlin

360

import org.jetbrains.compose.videoplayer.VideoPlayerImpl

361

362

@Composable

363

fun VideoPlayerExample() {

364

var isPlaying by remember { mutableStateOf(true) }

365

var volume by remember { mutableStateOf(1f) }

366

367

Column {

368

VideoPlayerImpl(

369

url = "file:///path/to/video.mp4",

370

isResumed = isPlaying,

371

volume = volume,

372

speed = 1f,

373

onFinish = { println("Video finished playing") }

374

)

375

376

Row {

377

Button(

378

onClick = { isPlaying = !isPlaying }

379

) {

380

Text(if (isPlaying) "Pause" else "Play")

381

}

382

383

Slider(

384

value = volume,

385

onValueChange = { volume = it },

386

valueRange = 0f..1f

387

)

388

}

389

}

390

}

391

```

392

393

## Experimental API Notice

394

395

Desktop components are marked with `@ExperimentalComposeLibrary` annotation, indicating they are experimental and their API may change in future versions.

396

397

```kotlin

398

@OptIn(ExperimentalComposeLibrary::class)

399

@Composable

400

fun MyDesktopApp() {

401

// Use experimental components

402

}

403

```