From e1ea7d22177043926676bff1b6a63e9c89ad16ad Mon Sep 17 00:00:00 2001 From: khlmood Date: Fri, 3 May 2024 10:28:30 +0300 Subject: [PATCH 1/2] added button component --- .../main/scala/gooey/component/button.scala | 54 +++++++++++++++++++ docs/src/css/creative-scala.css | 3 ++ .../src/main/scala/gooey/swing/Algebra.scala | 32 ++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 core/shared/src/main/scala/gooey/component/button.scala diff --git a/core/shared/src/main/scala/gooey/component/button.scala b/core/shared/src/main/scala/gooey/component/button.scala new file mode 100644 index 0000000..e2d35b4 --- /dev/null +++ b/core/shared/src/main/scala/gooey/component/button.scala @@ -0,0 +1,54 @@ +/* + * Copyright 2023 Creative Scala + * + * 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. + */ + +import cats.data.Chain +import gooey.Algebra +import gooey.WritableVar + +final case class Button( + label: Option[String], + onClick: () => Unit, + observers: Chain[WritableVar[Unit]] +) extends Component[Button.Algebra, Unit] { + def withLabel(label: String): Button = + this.copy(label = Some(label)) + + def withoutLabel: Button = + this.copy(label = "Click") + + def withOnClick(onClick: () => Unit): Button = + this.copy(onClick = onClick) + + def withObserver(writable: WritableVar[String]): Button = + this.copy(observers = writable +: observers) + + private[gooey] def build(algebra: Button.Algebra)( + env: algebra.Env + ): algebra.UI[Unit] = + algebra.button(label, onClick, observers)(env) +} + +object Button { + trait Algebra extends gooey.Algebra { + def button( + label: Option[String], + onClick: () => Unit, + observers: Chain[WritableVar[Unit]] + )(env: Env): UI[Unit] + } + + val empty: Button = Button("", () => {}, Chain.empty) +} diff --git a/docs/src/css/creative-scala.css b/docs/src/css/creative-scala.css index 72fd6de..ae7ce45 100644 --- a/docs/src/css/creative-scala.css +++ b/docs/src/css/creative-scala.css @@ -62,6 +62,9 @@ p { a { @apply hover:underline hover:decoration-solid; } +button { + @apply bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-blue-300 transition-colors duration-150 ease-in-out; +} .content a { @apply underline decoration-dotted decoration-1 hover:decoration-solid; } diff --git a/swing/src/main/scala/gooey/swing/Algebra.scala b/swing/src/main/scala/gooey/swing/Algebra.scala index 84ab848..17d8b3a 100644 --- a/swing/src/main/scala/gooey/swing/Algebra.scala +++ b/swing/src/main/scala/gooey/swing/Algebra.scala @@ -28,13 +28,14 @@ import gooey.component.Checkbox import gooey.component.Map import gooey.component.Pure import gooey.component.Textbox +import gooey.component.Button import gooey.component.style.* import net.bulbyvr.swing.io.all.{_, given} import net.bulbyvr.swing.io.wrapper.* type Algebra = gooey.Algebra & And.Algebra & Checkbox.Algebra & Map.Algebra & Pure.Algebra & - Textbox.Algebra + Textbox.Algebra & Button.Algebra given Algebra: gooey.Algebra with And.Algebra @@ -42,6 +43,7 @@ given Algebra: gooey.Algebra with Map.Algebra with Pure.Algebra with Textbox.Algebra + with Button.Algebra with { type Env = Environment @@ -116,6 +118,34 @@ given Algebra: gooey.Algebra } } + def button( + label: Option[String], + onClick: () => Unit, + observers: Chain[WritableVar[Unit]] + )(env: Env): UI[Unit] = { + SignallingRef[IO].of(()).toResource.flatMap { clickSignal => + val signals = addObservers(observers, clickSignal) + val component = makeComponent( + makeLabel(label), + buttonWithClick(onClick, clickSignal) + ) + signals *> component.map(c => (c, ())) + } + } + + private def buttonWithClick( + onClick: () => Unit, + clickSignal: SignallingRef[IO, Unit] + ): Resource[IO, Component[IO]] = + Resource.pure[IO, JButton]( + new JButton().tap { btn => + btn.addActionListener { _ => + onClick() + clickSignal.set(()) + } + } + ).map(Component(_)) + // Utilities ------------------------------------------------------- def makeComponent[A]( From 6cec5cb9c37d06c236848ac64687c56f18e932dd Mon Sep 17 00:00:00 2001 From: khlmood Date: Fri, 3 May 2024 10:41:33 +0300 Subject: [PATCH 2/2] package --- core/shared/src/main/scala/gooey/component/button.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/shared/src/main/scala/gooey/component/button.scala b/core/shared/src/main/scala/gooey/component/button.scala index e2d35b4..c087021 100644 --- a/core/shared/src/main/scala/gooey/component/button.scala +++ b/core/shared/src/main/scala/gooey/component/button.scala @@ -14,6 +14,8 @@ * limitations under the License. */ +package gooey.component + import cats.data.Chain import gooey.Algebra import gooey.WritableVar