Skip to content

Commit 12c7ad0

Browse files
committed
Refactored GraphOutput to use new Tabs.Vertical library
1 parent 76d3bd2 commit 12c7ad0

File tree

2 files changed

+31
-128
lines changed

2 files changed

+31
-128
lines changed

view/material/Tabs.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.Box
2727
import androidx.compose.foundation.layout.Column
2828
import androidx.compose.foundation.layout.Row
2929
import androidx.compose.foundation.layout.Spacer
30+
import androidx.compose.foundation.layout.fillMaxHeight
3031
import androidx.compose.foundation.layout.fillMaxWidth
3132
import androidx.compose.foundation.layout.height
3233
import androidx.compose.foundation.layout.offset
@@ -74,9 +75,11 @@ object Tabs {
7475

7576
val WIDTH = 22.dp
7677
private val TAB_HEIGHT = 100.dp
77-
private val TAB_OFFSET = (-40).dp
7878

79-
enum class Position(internal val degree: Float) { LEFT(-90f), RIGHT(90f) }
79+
enum class Position(internal val degree: Float, internal val offset: Dp) {
80+
LEFT(-90f, (-40).dp),
81+
RIGHT(90f, 40.dp)
82+
}
8083

8184
@Composable
8285
fun <T : Any> Layout(
@@ -88,7 +91,7 @@ object Tabs {
8891
onClick: (T) -> Unit,
8992
) {
9093
Column(
91-
modifier = Modifier.width(WIDTH).background(Theme.studio.backgroundMedium),
94+
modifier = Modifier.width(WIDTH).fillMaxHeight().background(Theme.studio.backgroundMedium),
9295
verticalArrangement = Arrangement.Top
9396
) { tabs.forEach { Tab(it, position, labelFn, iconFn, isActiveFn, onClick) } }
9497
}
@@ -116,7 +119,7 @@ object Tabs {
116119
verticalAlignment = Alignment.CenterVertically,
117120
modifier = Modifier.requiredWidth(TAB_HEIGHT)
118121
.rotate(position.degree)
119-
.offset(x = TAB_OFFSET)
122+
.offset(x = position.offset)
120123
.background(color = bgColor())
121124
) {
122125
Spacer(modifier = Modifier.weight(1f))

view/output/GraphOutput.kt

Lines changed: 24 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,21 @@ package com.vaticle.typedb.studio.view.output
2020

2121
import androidx.compose.foundation.Canvas
2222
import androidx.compose.foundation.background
23-
import androidx.compose.foundation.clickable
2423
import androidx.compose.foundation.gestures.Orientation
2524
import androidx.compose.foundation.gestures.detectDragGestures
2625
import androidx.compose.foundation.gestures.detectTapGestures
2726
import androidx.compose.foundation.gestures.rememberScrollableState
2827
import androidx.compose.foundation.gestures.scrollable
29-
import androidx.compose.foundation.layout.Arrangement
3028
import androidx.compose.foundation.layout.Box
3129
import androidx.compose.foundation.layout.Column
3230
import androidx.compose.foundation.layout.Row
33-
import androidx.compose.foundation.layout.Spacer
3431
import androidx.compose.foundation.layout.fillMaxHeight
3532
import androidx.compose.foundation.layout.fillMaxSize
3633
import androidx.compose.foundation.layout.fillMaxWidth
3734
import androidx.compose.foundation.layout.height
3835
import androidx.compose.foundation.layout.offset
3936
import androidx.compose.foundation.layout.padding
40-
import androidx.compose.foundation.layout.requiredWidth
4137
import androidx.compose.foundation.layout.size
42-
import androidx.compose.foundation.layout.width
4338
import androidx.compose.runtime.Composable
4439
import androidx.compose.runtime.LaunchedEffect
4540
import androidx.compose.runtime.getValue
@@ -50,7 +45,6 @@ import androidx.compose.runtime.withFrameMillis
5045
import androidx.compose.ui.Alignment
5146
import androidx.compose.ui.ExperimentalComposeUiApi
5247
import androidx.compose.ui.Modifier
53-
import androidx.compose.ui.draw.rotate
5448
import androidx.compose.ui.geometry.CornerRadius
5549
import androidx.compose.ui.geometry.Offset
5650
import androidx.compose.ui.geometry.Rect
@@ -60,8 +54,6 @@ import androidx.compose.ui.graphics.drawscope.DrawScope
6054
import androidx.compose.ui.graphics.drawscope.Stroke
6155
import androidx.compose.ui.graphics.drawscope.withTransform
6256
import androidx.compose.ui.graphics.graphicsLayer
63-
import androidx.compose.ui.input.pointer.PointerIconDefaults
64-
import androidx.compose.ui.input.pointer.pointerHoverIcon
6557
import androidx.compose.ui.input.pointer.pointerInput
6658
import androidx.compose.ui.input.pointer.pointerMoveFilter
6759
import androidx.compose.ui.layout.LayoutCoordinates
@@ -78,7 +70,6 @@ import androidx.compose.ui.unit.Dp
7870
import androidx.compose.ui.unit.DpOffset
7971
import androidx.compose.ui.unit.DpSize
8072
import androidx.compose.ui.unit.dp
81-
import androidx.compose.ui.unit.sp
8273
import androidx.compose.ui.unit.toSize
8374
import androidx.compose.ui.zIndex
8475
import com.vaticle.force.graph.api.Simulation
@@ -130,11 +121,13 @@ import com.vaticle.typedb.studio.view.common.geometry.Geometry.rectIncomingLineI
130121
import com.vaticle.typedb.studio.view.common.geometry.Geometry.sweepAngle
131122
import com.vaticle.typedb.studio.view.common.theme.Color
132123
import com.vaticle.typedb.studio.view.common.theme.Theme
124+
import com.vaticle.typedb.studio.view.material.Browser
133125
import com.vaticle.typedb.studio.view.material.Form
134126
import com.vaticle.typedb.studio.view.material.Frame
135127
import com.vaticle.typedb.studio.view.material.Icon
136128
import com.vaticle.typedb.studio.view.material.Separator
137129
import com.vaticle.typedb.studio.view.material.Table
130+
import com.vaticle.typedb.studio.view.material.Tabs
138131
import com.vaticle.typedb.studio.view.output.GraphOutput.State.Graph.Physics.Constants.COLLIDE_RADIUS
139132
import com.vaticle.typedb.studio.view.output.GraphOutput.State.Graph.Physics.Constants.CURVE_COLLIDE_RADIUS
140133
import com.vaticle.typedb.studio.view.output.GraphOutput.State.Graph.Physics.Constants.CURVE_COMPRESSION_POWER
@@ -1690,7 +1683,7 @@ internal object GraphOutput : RunOutput() {
16901683
minSize = BrowserArea.MIN_WIDTH,
16911684
initSize = Either.first(
16921685
state.browserAreaState?.let { if (it.browser.isOpen) it.paneState.size else null }
1693-
?: BrowserArea.SIDE_TAB_WIDTH
1686+
?: Tabs.Vertical.WIDTH
16941687
),
16951688
initFreeze = state.browserAreaState?.browser?.isOpen != true
16961689
) { BrowserArea.Layout(state, it) }
@@ -1918,98 +1911,26 @@ internal object GraphOutput : RunOutput() {
19181911
}
19191912
}
19201913

1921-
// TODO: copied from browser/Browser.kt on 23/05/2022
1922-
abstract class Browser(
1923-
private val areaState: BrowserArea.State, internal val order: Int, initOpen: Boolean = false
1924-
) {
1925-
1926-
companion object {
1927-
internal val MIN_HEIGHT = 80.dp
1928-
}
1929-
1930-
internal abstract val label: String
1931-
internal abstract val icon: Icon.Code
1932-
internal abstract val buttons: List<Form.IconButtonArg>
1933-
1934-
internal var isOpen: Boolean by mutableStateOf(initOpen)
1935-
1936-
@Composable
1937-
abstract fun BrowserLayout()
1938-
1939-
fun toggle() {
1940-
isOpen = !isOpen
1941-
areaState.mayUpdatePaneState()
1942-
}
1943-
1944-
@Composable
1945-
internal fun Layout() {
1946-
Column {
1947-
Bar()
1948-
Separator.Horizontal()
1949-
Box(modifier = Modifier.weight(1f)) { BrowserLayout() }
1950-
}
1951-
}
1952-
1953-
@Composable
1954-
private fun Bar() {
1955-
Row(
1956-
modifier = Modifier.fillMaxWidth().height(Theme.PANEL_BAR_HEIGHT)
1957-
.background(color = Theme.studio.surface),
1958-
verticalAlignment = Alignment.CenterVertically
1959-
) {
1960-
Spacer(Modifier.width(Theme.PANEL_BAR_SPACING))
1961-
Icon.Render(icon = icon)
1962-
Spacer(Modifier.width(Theme.PANEL_BAR_SPACING))
1963-
Form.Text(value = label)
1964-
Spacer(Modifier.weight(1f))
1965-
Buttons(*buttons.toTypedArray(), isActive = true)
1966-
Buttons(Form.IconButtonArg(Icon.Code.XMARK) { toggle() }, isActive = true)
1967-
}
1968-
}
1969-
1970-
@Composable
1971-
private fun Buttons(vararg buttons: Form.IconButtonArg, isActive: Boolean) {
1972-
buttons.forEach {
1973-
Form.IconButton(
1974-
icon = it.icon,
1975-
hoverIcon = it.hoverIcon,
1976-
modifier = Modifier.size(Theme.PANEL_BAR_HEIGHT),
1977-
iconColor = it.color(),
1978-
iconHoverColor = it.hoverColor?.invoke(),
1979-
disabledColor = it.disabledColor?.invoke(),
1980-
bgColor = androidx.compose.ui.graphics.Color.Transparent,
1981-
roundedCorners = Theme.RoundedCorners.NONE,
1982-
enabled = isActive && it.enabled,
1983-
tooltip = it.tooltip,
1984-
onClick = it.onClick,
1985-
)
1986-
}
1987-
}
1988-
}
1989-
19901914
// TODO: copied from browser/BrowserArea.kt on 23/05/2022
19911915
object BrowserArea {
19921916

19931917
val WIDTH = 300.dp
19941918
val MIN_WIDTH = 150.dp
1995-
val SIDE_TAB_WIDTH = 22.dp
1996-
private val SIDE_TAB_HEIGHT = 100.dp
1997-
private val SIDE_TAB_SPACING = 8.dp
1998-
private val ICON_SIZE = 10.sp
1999-
private val TAB_OFFSET = 40.dp
20001919

20011920
class State constructor(state: GraphOutput.State, var paneState: Frame.PaneState) {
20021921

20031922
private var unfreezeSize: Dp by mutableStateOf(WIDTH)
2004-
internal val browser = PreviewBrowser(state, this, 0, false)
1923+
internal val browser = PreviewBrowser(state, 0, false) { mayUpdatePaneState() }
20051924
internal var isOpen
20061925
get() = browser.isOpen
2007-
set(value) { browser.isOpen = value }
1926+
set(value) {
1927+
browser.isOpen = value
1928+
}
20081929

20091930
fun mayUpdatePaneState() {
20101931
if (!isOpen) {
20111932
unfreezeSize = paneState.size
2012-
paneState.freeze(SIDE_TAB_WIDTH)
1933+
paneState.freeze(Tabs.Vertical.WIDTH)
20131934
} else if (paneState.isFrozen) paneState.unfreeze(unfreezeSize)
20141935
}
20151936
}
@@ -2035,61 +1956,40 @@ internal object GraphOutput : RunOutput() {
20351956
)
20361957
Separator.Vertical()
20371958
}
2038-
Column(Modifier.width(SIDE_TAB_WIDTH), verticalArrangement = Arrangement.Top) {
2039-
Tab(areaState.browser)
2040-
}
2041-
}
2042-
}
2043-
2044-
@OptIn(ExperimentalComposeUiApi::class)
2045-
@Composable
2046-
private fun Tab(browser: Browser) {
2047-
@Composable
2048-
fun bgColor(): androidx.compose.ui.graphics.Color =
2049-
if (browser.isOpen) Theme.studio.surface else Theme.studio.backgroundDark
2050-
Box(
2051-
modifier = Modifier
2052-
.fillMaxWidth()
2053-
.height(SIDE_TAB_HEIGHT)
2054-
.pointerHoverIcon(PointerIconDefaults.Hand)
2055-
.clickable { browser.toggle() }
2056-
) {
2057-
Row(
2058-
verticalAlignment = Alignment.CenterVertically,
2059-
modifier = Modifier.requiredWidth(SIDE_TAB_HEIGHT)
2060-
.rotate(90f)
2061-
.offset(x = TAB_OFFSET)
2062-
.background(color = bgColor())
2063-
) {
2064-
Spacer(modifier = Modifier.weight(1f))
2065-
Icon.Render(icon = browser.icon, size = ICON_SIZE)
2066-
Spacer(modifier = Modifier.width(SIDE_TAB_SPACING))
2067-
Form.Text(value = browser.label)
2068-
Spacer(modifier = Modifier.weight(1f))
2069-
}
1959+
Tabs.Vertical.Layout(
1960+
tabs = listOf(areaState.browser),
1961+
position = Tabs.Vertical.Position.RIGHT,
1962+
labelFn = { it.label },
1963+
iconFn = { it.icon },
1964+
isActiveFn = { it.isOpen },
1965+
) { it.toggle() }
20701966
}
2071-
Separator.Horizontal()
20721967
}
20731968
}
20741969

2075-
class PreviewBrowser(private val state: State, areaState: BrowserArea.State, order: Int, initOpen: Boolean) :
2076-
Browser(areaState, order, initOpen) {
1970+
class PreviewBrowser constructor(
1971+
private val state: State,
1972+
order: Int,
1973+
isOpen: Boolean,
1974+
onUpdatePane: () -> Unit
1975+
) : Browser(isOpen, order, onUpdatePane) {
20771976

20781977
override val label: String = Label.PREVIEW
20791978
override val icon: Icon.Code = Icon.Code.EYE
1979+
override val isActive: Boolean = true
20801980
override var buttons: List<Form.IconButtonArg> = emptyList()
20811981

20821982
private val placeholderPadding = 20.dp
20831983

20841984
@Composable
20851985
override fun BrowserLayout() {
20861986
val focusedVertex = state.interactions.focusedVertex
2087-
if (focusedVertex == null) PlaceholderText()
1987+
if (focusedVertex == null) SelectVertexMessage()
20881988
else ConceptPreview(focusedVertex.concept).Layout()
20891989
}
20901990

20911991
@Composable
2092-
private fun PlaceholderText() {
1992+
private fun SelectVertexMessage() {
20931993
Box(Modifier.fillMaxSize().padding(placeholderPadding), Alignment.Center) {
20941994
Form.Text(Label.GRAPH_CONCEPT_PREVIEW_PLACEHOLDER, align = TextAlign.Center, softWrap = true)
20951995
}

0 commit comments

Comments
 (0)