[go: nahoru, domu]

blob: d362f56c16d33c6a3d052afaaec2d786fb4d0721 [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* 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
*
* http://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 androidx.compose.ui.window
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.dp
/**
* Creates a [WindowState] that is remembered across compositions.
*
* Changes to the provided initial values will **not** result in the state being recreated or
* changed in any way if it has already been created.
*
* @param placement the initial value for [WindowState.placement]
* @param isMinimized the initial value for [WindowState.isMinimized]
* @param position the initial value for [WindowState.position]
* @param size the initial value for [WindowState.size]
*/
@Composable
fun rememberWindowState(
placement: WindowPlacement = WindowPlacement.Floating,
isMinimized: Boolean = false,
position: WindowPosition = WindowPosition.PlatformDefault,
size: WindowSize = WindowSize(800.dp, 600.dp),
): WindowState = rememberSaveable(saver = WindowStateImpl.Saver(position)) {
WindowStateImpl(
placement,
isMinimized,
position,
size
)
}
/**
* A state object that can be hoisted to control and observe window attributes
* (size/position/state).
*
* In most cases, this will be created via [rememberWindowState].
*
* @param placement the initial value for [WindowState.placement]
* @param isMinimized the initial value for [WindowState.isMinimized]
* @param position the initial value for [WindowState.position]
* @param size the initial value for [WindowState.size]
*/
fun WindowState(
placement: WindowPlacement = WindowPlacement.Floating,
isMinimized: Boolean = false,
position: WindowPosition = WindowPosition.PlatformDefault,
size: WindowSize = WindowSize(800.dp, 600.dp)
): WindowState = WindowStateImpl(
placement, isMinimized, position, size
)
/**
* A state object that can be hoisted to control and observe window attributes
* (size/position/state).
*
* In most cases, this will be created via [rememberWindowState].
*/
interface WindowState {
/**
* Describes how the window is placed on the screen.
*/
var placement: WindowPlacement
/**
* `true` if the window is minimized.
*/
var isMinimized: Boolean
/**
* Current position of the window. If position is not specified ([WindowPosition.isSpecified]
* is false) then once the window shows on the screen the position will be set to
* absolute values [WindowPosition.Absolute].
*/
var position: WindowPosition
/**
* Current size of the window.
*/
var size: WindowSize
}
private class WindowStateImpl(
placement: WindowPlacement,
isMinimized: Boolean,
position: WindowPosition,
size: WindowSize
) : WindowState {
override var placement by mutableStateOf(placement)
override var isMinimized by mutableStateOf(isMinimized)
override var position by mutableStateOf(position)
override var size by mutableStateOf(size)
companion object {
/**
* The default [Saver] implementation for [WindowStateImpl].
*/
fun Saver(unspecifiedPosition: WindowPosition) = listSaver<WindowState, Any>(
save = {
listOf(
it.placement.ordinal,
it.isMinimized,
it.position.isSpecified,
it.position.x.value,
it.position.y.value,
it.size.width.value,
it.size.height.value,
)
},
restore = { state ->
WindowStateImpl(
placement = WindowPlacement.values()[state[0] as Int],
isMinimized = state[1] as Boolean,
position = if (state[2] as Boolean) {
WindowPosition((state[3] as Float).dp, (state[4] as Float).dp)
} else {
unspecifiedPosition
},
size = WindowSize((state[5] as Float).dp, (state[6] as Float).dp),
)
}
)
}
}