@@ -5,17 +5,12 @@ import androidx.compose.animation.core.LinearEasing
55import androidx.compose.animation.core.tween
66import androidx.compose.animation.fadeIn
77import androidx.compose.animation.fadeOut
8- import androidx.compose.foundation.ExperimentalFoundationApi
9- import androidx.compose.foundation.Image
10- import androidx.compose.foundation.background
8+ import androidx.compose.foundation.*
119import androidx.compose.foundation.layout.*
12- import androidx.compose.foundation.onClick
1310import androidx.compose.foundation.shape.CircleShape
1411import androidx.compose.material.*
1512import androidx.compose.material.icons.Icons
1613import androidx.compose.material.icons.filled.PlayArrow
17- import androidx.compose.material.icons.filled.Settings
18- import androidx.compose.material.icons.outlined.Share
1914import androidx.compose.runtime.*
2015import androidx.compose.ui.Alignment
2116import androidx.compose.ui.ExperimentalComposeUiApi
@@ -29,11 +24,15 @@ import androidx.compose.ui.graphics.StrokeCap
2924import androidx.compose.ui.input.pointer.PointerEventType
3025import androidx.compose.ui.input.pointer.onPointerEvent
3126import androidx.compose.ui.res.loadImageBitmap
27+ import androidx.compose.ui.res.loadSvgPainter
28+ import androidx.compose.ui.res.useResource
29+ import androidx.compose.ui.unit.Density
3230import androidx.compose.ui.unit.Dp
3331import androidx.compose.ui.unit.dp
3432import androidx.compose.ui.window.Window
3533import androidx.compose.ui.window.WindowPosition
3634import androidx.compose.ui.window.rememberWindowState
35+ import groovyjarjarantlr4.v4.runtime.misc.Args
3736import processing.app.gradle.helpers.ActionGradleJob
3837import processing.app.gradle.GradleJob
3938import processing.app.gradle.ScreenshotService
@@ -44,7 +43,7 @@ import processing.app.ui.theme.toColorInt
4443import java.io.File
4544import javax.swing.JComponent
4645
47- class Toolbar (val editor : Editor ) {
46+ class Toolbar (val editor : Editor ? ) {
4847 companion object {
4948 @JvmStatic
5049 fun legacyWrapped (editor : Editor , toolbar : EditorToolbar ): JComponent {
@@ -64,6 +63,10 @@ class Toolbar(val editor: Editor) {
6463
6564 return panel
6665 }
66+ @JvmStatic
67+ fun main (args : Array <String >) {
68+
69+ }
6770 }
6871
6972 // TODO: Split into multiple files
@@ -117,67 +120,92 @@ class Toolbar(val editor: Editor) {
117120
118121 }
119122
120- // TODO: Indicate waiting for vm connection to be ready
121- val vm = editor.service.jobs.lastOrNull()?.vm?.value
122- // TODO: Fade in
123- // TODO: Set icon
124- vm?.apply {
125- ActionButton (
126- modifier = Modifier
127- .onClick {
128- ScreenshotService .takeScreenshot(this ) { file ->
123+ Row {
124+ hoverPill(actions = {
125+ actionButton(
126+ onClick = {
127+
128+ }
129+ ) {
130+ val icon = useResource(" toolbar/Settings.svg" ) { loadSvgPainter(it, Density (1f )) }
131+ val color = LocalContentColor .current
132+ Icon (
133+ painter = icon,
134+ contentDescription = " Settings" ,
135+ tint = color
136+ )
137+ }
138+ val vm = editor?.service?.jobs?.lastOrNull()?.vm?.value
139+ actionButton(
140+ enabled = vm != null ,
141+ onClick = {
142+ vm ? : return @actionButton
143+ ScreenshotService .takeScreenshot(vm) { file ->
129144 screenshot = file.toFile()
130145 }
131146 }
132- ) {
133- Icon (
134- imageVector = Icons .Outlined .Share ,
135- contentDescription = " Settings" ,
136- tint = Color (Theme .get(" toolbar.button.enabled.glyph" ).toColorInt()),
137- modifier = Modifier .padding(6 .dp)
138- )
139- }
147+ ) {
148+ val icon = useResource(" toolbar/Screenshot.svg" ) { loadSvgPainter(it, Density (1f )) }
149+ val color = LocalContentColor .current
150+ Icon (
151+ painter = icon,
152+ contentDescription = " Screenshot" ,
153+ tint = color
154+ )
155+ }
140156
141- }
142157
143- // TODO: Set icon
144- var expanded by remember { mutableStateOf(false ) }
145- ActionButton (
146- active = expanded,
147- modifier = Modifier
148- .onClick {
149- val x = editor.location.x + editor.width
150- val y = editor.location.y
151- windowState.position = WindowPosition (
152- x = x.dp,
153- y = y.dp,
158+ var expanded by remember { mutableStateOf(false ) }
159+ actionButton(
160+ active = expanded,
161+ modifier = Modifier
162+ .onClick {
163+ editor ? : return @onClick
164+ val x = editor.location.x + editor.width
165+ val y = editor.location.y
166+ windowState.position = WindowPosition (
167+ x = x.dp,
168+ y = y.dp,
169+ )
170+ expanded = ! expanded
171+ }
172+ ) {
173+ val icon = useResource(" toolbar/Sketch Settings.svg" ) { loadSvgPainter(it, Density (1f )) }
174+ val color = LocalContentColor .current
175+ Icon (
176+ painter = icon,
177+ contentDescription = " Sketch Settings" ,
178+ tint = color
154179 )
155- expanded = ! expanded
156180 }
157- ){
158- Icon (
159- imageVector = Icons .Filled .Settings ,
160- contentDescription = " Settings" ,
161- tint = Color (Theme .get(" toolbar.button.enabled.glyph" ).toColorInt()),
162- modifier = Modifier .padding(6 .dp)
163- )
164- }
165- Window (
166- visible = expanded,
167- onCloseRequest = {
168- expanded = false
169- },
170- resizable = true ,
171- title = " Sketch Settings" ,
172- state = windowState,
173- ) {
174- Column (modifier = Modifier .padding(16 .dp)) {
175- Chip (onClick = {
176- editor.service.active.value = false
177- }) {
178- Text (" Switch back to legacy" )
181+ Window (
182+ visible = expanded,
183+ onCloseRequest = {
184+ expanded = false
185+ },
186+ resizable = true ,
187+ title = " Sketch Settings" ,
188+ state = windowState,
189+ ) {
190+ Column (modifier = Modifier .padding(16 .dp)) {
191+ Chip (onClick = {
192+ editor?.service?.active?.value = false
193+ }) {
194+ Text (" Switch back to legacy" )
195+ }
196+ }
179197 }
180- }
198+ }, base = {
199+ actionButton {
200+ val icon = useResource(" toolbar/More.svg" ) { loadSvgPainter(it, Density (1f )) }
201+ val color = LocalContentColor .current
202+ Icon (
203+ painter = icon,
204+ contentDescription = " More" ,
205+ tint = color
206+ )
207+ }
208+ })
181209 }
182210 }
183211
@@ -186,15 +214,15 @@ class Toolbar(val editor: Editor) {
186214 @OptIn(ExperimentalComposeUiApi ::class )
187215 @Composable
188216 fun SketchButtons () {
189- val job = editor.service.jobs.filterIsInstance<ActionGradleJob >().lastOrNull()
217+ val job = editor? .service? .jobs? .filterIsInstance<ActionGradleJob >()? .lastOrNull()
190218 val state = job?.state?.value ? : GradleJob .State .NONE
191219 val isActive = state != GradleJob .State .NONE && state != GradleJob .State .DONE
192220 Row (horizontalArrangement = Arrangement .spacedBy(8 .dp)) {
193- ActionButton (
221+ actionButton (
194222 active = isActive,
195223 modifier = Modifier
196224 .onPointerEvent(PointerEventType .Press ) {
197- editor.service.run ()
225+ editor? .service? .run ()
198226 }
199227 .padding(2 .dp)
200228 ) {
@@ -207,27 +235,26 @@ class Toolbar(val editor: Editor) {
207235 strokeWidth = 3 .dp
208236 )
209237 }
210- Box (modifier = Modifier .padding(4 .dp)) {
211- Icon (
212- imageVector = Icons .Filled .PlayArrow ,
213- contentDescription = " Play" ,
214- tint = color
215- )
216- }
238+ val icon = useResource(" toolbar/Play.svg" ) { loadSvgPainter(it, Density (1f )) }
239+ Icon (
240+ painter = icon,
241+ contentDescription = " Play" ,
242+ tint = color
243+ )
217244 }
218245 Fading (visible = isActive) {
219- ActionButton (
246+ actionButton (
220247 modifier = Modifier
221248 .onPointerEvent(PointerEventType .Press ) {
222- editor.service.stop()
249+ editor? .service? .stop()
223250 }
224251 ) {
252+ val icon = useResource(" toolbar/Stop.svg" ) { loadSvgPainter(it, Density (1f )) }
225253 val color = LocalContentColor .current
226- Box (
227- modifier = Modifier
228- .padding(12 .dp)
229- .size(12 .dp)
230- .background(color)
254+ Icon (
255+ painter = icon,
256+ contentDescription = " Stop" ,
257+ tint = color
231258 )
232259 }
233260 }
@@ -236,7 +263,38 @@ class Toolbar(val editor: Editor) {
236263
237264 @OptIn(ExperimentalComposeUiApi ::class )
238265 @Composable
239- fun ActionButton (modifier : Modifier = Modifier , active : Boolean = false, content : @Composable () -> Unit ) {
266+ fun hoverPill (actions : @Composable () -> Unit , base : @Composable () -> Unit ) {
267+ var hover by remember { mutableStateOf(false ) }
268+ val baseColor = Theme .get(" toolbar.button.enabled.field" ).toColorInt().let { Color (it) }
269+
270+ Row (
271+ modifier = Modifier
272+ .onPointerEvent(PointerEventType .Enter ) {
273+ hover = true
274+ }
275+ .onPointerEvent(PointerEventType .Exit ) {
276+ hover = false
277+ }
278+ .clip(CircleShape )
279+ .background(baseColor)
280+
281+
282+ ){
283+ if (hover) actions()
284+ base()
285+ }
286+ }
287+
288+
289+ @OptIn(ExperimentalComposeUiApi ::class , ExperimentalFoundationApi ::class )
290+ @Composable
291+ fun actionButton (
292+ modifier : Modifier = Modifier ,
293+ enabled : Boolean = true,
294+ active : Boolean = false,
295+ onClick : () -> Unit = {},
296+ content : @Composable () -> Unit
297+ ) {
240298 val baseColor = Theme .get(" toolbar.button.enabled.field" )
241299 val baseTextColor = Theme .get(" toolbar.button.enabled.glyph" )
242300
@@ -283,6 +341,11 @@ class Toolbar(val editor: Editor) {
283341 .clip(CircleShape )
284342 .aspectRatio(1f )
285343 .background(color = Color (color))
344+ .onClick{
345+ if (enabled) {
346+ onClick()
347+ }
348+ }
286349 .then(modifier)
287350 ) {
288351 CompositionLocalProvider (LocalContentColor provides Color (textColor.toColorInt())) {
0 commit comments