Skip to content

Commit

Permalink
#177: adds animation to 'copy to clipboard' action
Browse files Browse the repository at this point in the history
  • Loading branch information
rladstaetter committed Dec 26, 2023
1 parent 5318327 commit 7d6d7da
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
71 changes: 63 additions & 8 deletions app/src/main/scala/app/logorrr/views/ops/CopyLogButton.scala
Original file line number Diff line number Diff line change
@@ -1,23 +1,78 @@
package app.logorrr.views.ops

import app.logorrr.model.LogEntry
import javafx.animation.AnimationTimer
import javafx.collections.ObservableList
import javafx.scene.control.{Button, Tooltip}
import javafx.scene.input.{Clipboard, ClipboardContent}
import org.kordamp.ikonli.fontawesome5.FontAwesomeSolid
import org.kordamp.ikonli.fontawesome5.{FontAwesomeRegular, FontAwesomeSolid}
import org.kordamp.ikonli.javafx.FontIcon

import scala.collection.mutable.ListBuffer

/**
* Copy current contents to clipboard.
*
* @param logEntries current active log entries
*/
class CopyLogButton(logEntries: ObservableList[LogEntry]) extends Button {

private val icon = new FontIcon(FontAwesomeSolid.COPY)
setGraphic(icon)
setTooltip(new Tooltip("copy current selection to clipboard"))
setOnAction(_ => {
val lb = new ListBuffer[String]
logEntries.forEach(e => lb.addOne(e.value))
copyToClipboard(lb.mkString("\n"))
})
private val iconLight = new FontIcon(FontAwesomeRegular.COPY)
private val TooltipText = "copy current selection to clipboard"
private val defaultToolTip = new Tooltip(TooltipText)

init()

def init(): Unit = {
setGraphic(icon)
setTooltip(defaultToolTip)

setOnAction(_ => {
val lb = new ListBuffer[String]
logEntries.forEach(e => lb.addOne(e.value))
copyToClipboard(lb.mkString("\n"))
defaultToolTip.setText(s"Copied ${lb.size} entries to clipboard")
val bounds = localToScreen(getBoundsInLocal)
val x = bounds.getMinX
val y = bounds.getMaxY
defaultToolTip.show(this,x,y)

mkTimer().start() // visual response to click
})
}

def mkTimer(): AnimationTimer = new AnimationTimer() {
private var startTime: Long = -1

def handle(now: Long): Unit = {
if (startTime < 0) {
setGraphic(iconLight)
startTime = now
}

val elapsedSeconds = (now - startTime) / 1_000_000_000.0

// Stop the animation after 1 second
if (elapsedSeconds > 1) {
getGraphic.setOpacity(1) // Ensure it ends at full opacity
setGraphic(icon)
defaultToolTip.hide()
defaultToolTip.setText(TooltipText)
this.stop()
return
}
val alpha = elapsedSeconds / 1 // From 0 to 1 in one second

if (alpha <= 0.5) {
// Fade out for the first half
getGraphic.setOpacity(1 - 2 * alpha)
} else {
// Fade in for the second half
getGraphic.setOpacity(2 * alpha - 1)
}
}
}

def copyToClipboard(text: String): Unit = {
val clipboard = Clipboard.getSystemClipboard
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/scala/app/logorrr/views/search/OpsToolBar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ class OpsToolBar(pathAsString: String

val copySelectionButton = new CopyLogButton(filteredList)

val firstNEntries: ObservableList[LogEntry] = TimerSettingsLogView.mkEntriesToShow(logEntries)
val timerButton = new TimerButton(pathAsString, firstNEntries)
// val firstNEntries: ObservableList[LogEntry] = TimerSettingsLogView.mkEntriesToShow(logEntries)

// val timerButton = new TimerButton(pathAsString, firstNEntries)

def execSearchOnHitEnter(event: KeyEvent): Unit = {
if (event.getCode == KeyCode.ENTER) {
Expand Down
7 changes: 3 additions & 4 deletions docs/ffmpeg.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Convert mov to gif
# Convert mp4 to gif

ffmpeg -i \#177-copy-to-clipboard.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v gif -f gif \#177-copy-to-clipboard.gif

ffmpeg -i logorrr-poc.mov -pix_fmt rgb8 -s 389x308 out.gif
convert out.gif -verbose -coalesce -layers OptimizeFrame out-preopt.gif
gifsicle -O2 out-preopt.gif -o out-final.gif

0 comments on commit 7d6d7da

Please sign in to comment.