Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#170: fixes current element selection #171

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/src/main/scala/app/logorrr/util/JfxUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import javafx.stage.{Stage, WindowEvent}
object JfxUtils extends CanLog {

def execOnUiThread(f: => Unit): Unit = {
if (!Platform.isFxApplicationThread) {
Platform.runLater(() => f)
} else {
if (Platform.isFxApplicationThread) {
f
} else {
Platform.runLater(() => f)
}
}

Expand Down
6 changes: 5 additions & 1 deletion app/src/main/scala/app/logorrr/views/block/BlockImage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ object BlockImage {
/** defines how many table cells should be rendered per list height */
val DefaultBlocksPerPage = 4

def indexOf(x: Int, y: Int, blockWidth: Int, blockViewWidth: Int): Int = y / blockWidth * (blockViewWidth / blockWidth) + x / blockWidth
// assuming we have a grid of rectangles, and x and y give the coordinate of a mouse click
// this function should return the correct index for the surrounding rectangle
def indexOf(x: Int, y: Int, blockWidth: Int, blockViewWidth: Int): Int = {
y / blockWidth * (blockViewWidth / blockWidth) + x / blockWidth
}

/**
* Calculates overall height of virtual canvas
Expand Down
19 changes: 13 additions & 6 deletions app/src/main/scala/app/logorrr/views/block/ChunkListCell.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import javafx.collections.ObservableList
import javafx.event.EventHandler
import javafx.scene.control.ListCell
import javafx.scene.image.ImageView
import javafx.scene.input.MouseEvent
import javafx.scene.input.{MouseButton, MouseEvent}

import scala.util.Try

Expand All @@ -25,17 +25,24 @@ class ChunkListCell(selectedLineNumberProperty: SimpleIntegerProperty
, widthProperty: ReadOnlyDoubleProperty
, blockSizeProperty: SimpleIntegerProperty
, filtersProperty: ObservableList[Filter]
, selectInTextView: LogEntry => Unit
) extends ListCell[Chunk] with CanLog {

// if user selects an entry in the ChunkListView set selectedLineNumberProperty. This property is observed
// via an listener and a yellow square will be painted.
val mouseEventHandler = new EventHandler[MouseEvent]() {
override def handle(me: MouseEvent): Unit = {
val index = BlockImage.indexOf(me.getX.toInt, me.getY.toInt, blockSizeProperty.get, widthProperty.get.toInt)
getEntryAt(getItem, index) match {
case Some(value) =>
selectedLineNumberProperty.set(value.lineNumber)
case None => System.err.println("no element found")
// on left mouse button
if (me.getButton.equals(MouseButton.PRIMARY)) {
val index = BlockImage.indexOf(me.getX.toInt, me.getY.toInt, blockSizeProperty.get, widthProperty.get.toInt)
getEntryAt(getItem, index) match {
case Some(value) =>
// set selected property such that the next repaint will highlight this entry
selectedLineNumberProperty.set(value.lineNumber)
// we have to select also the entry in the LogTextView, couldn't get it to work with bindings / listeners
selectInTextView(value)
case None => System.err.println("no element found")
}
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions app/src/main/scala/app/logorrr/views/block/ChunkListView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ import scala.util.{Failure, Success, Try}
object ChunkListView {

def apply(entries: ObservableList[LogEntry]
, settings: MutLogFileSettings): ChunkListView = {
, settings: MutLogFileSettings
, selectInTextView: LogEntry => Unit
): ChunkListView = {
new ChunkListView(entries
, settings.selectedLineNumberProperty
, settings.blockSizeProperty
, settings.filtersProperty
, settings.dividerPositionProperty)
, settings.dividerPositionProperty
, selectInTextView)
}
}

Expand All @@ -40,7 +43,8 @@ class ChunkListView(val entries: ObservableList[LogEntry]
, val selectedLineNumberProperty: SimpleIntegerProperty
, val blockSizeProperty: SimpleIntegerProperty
, val filtersProperty: ObservableList[Filter]
, val dividersProperty: SimpleDoubleProperty)
, val dividersProperty: SimpleDoubleProperty
, selectInTextView: LogEntry => Unit)
extends ListView[Chunk] with CanLog {

var repaints = 0
Expand Down Expand Up @@ -73,11 +77,11 @@ class ChunkListView(val entries: ObservableList[LogEntry]

getStylesheets.add(getClass.getResource("/app/logorrr/ChunkListView.css").toExternalForm)

setCellFactory((lv: ListView[Chunk]) => new ChunkListCell(
selectedLineNumberProperty
setCellFactory((lv: ListView[Chunk]) => new ChunkListCell(selectedLineNumberProperty
, lv.widthProperty()
, blockSizeProperty
, filtersProperty))
, filtersProperty
, selectInTextView))


// if width/height of display is changed, also elements of this listview will change
Expand Down
65 changes: 21 additions & 44 deletions app/src/main/scala/app/logorrr/views/block/LPixelBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ case class LPixelBuffer(blockNumber: Int
, IntBuffer.wrap(rawInts)
, PixelFormat.getIntArgbPreInstance) with CanLog {

val name = s"${range.start}_${range.end}"

getBuffer.clear()

assert(shape.width != 0, s"For $name, width was ${shape.width}.")
assert(shape.height != 0, s"For $name, height was ${shape.height}.")
assert(shape.height * shape.width > 0)

private val name = s"${range.start}_${range.end}"
private val bgColor: Int = ColorUtil.toARGB(Color.WHITE)
lazy val background: Array[Int] = Array.fill(shape.area)(bgColor)

paint()
init()

def init(): Unit = {
assert(shape.width != 0, s"For $name, width was ${shape.width}.")
assert(shape.height != 0, s"For $name, height was ${shape.height}.")
assert(shape.height * shape.width > 0)
paint()
}

private def cleanBackground(): Unit = System.arraycopy(background, 0, rawInts, 0, background.length)

Expand All @@ -96,46 +96,23 @@ case class LPixelBuffer(blockNumber: Int
def filters = Option(filtersProperty).map(_.asScala.toSeq).getOrElse(Seq())

// todo check visibility
def paint(): Unit = {
if (blockSize != 0) {
if (Option(filtersProperty).isEmpty) {
logWarn("filters is null")
} else {
JfxUtils.execOnUiThread(
updateBuffer((_: PixelBuffer[IntBuffer]) => {
cleanBackground()
var i = 0
entries.forEach(e => {
if (e.lineNumber.equals(selectedLineNumberProperty.getValue() + 1)) {
LPixelBuffer.drawRect(rawInts, i, shape.width, blockSize, Color.YELLOW)
} else {
// LPixelBuffer.drawRect(rawInts, i, width, blockSize, blockColor)
LPixelBuffer.drawRect(rawInts, i, shape.width, blockSize, Filter.calcColor(e.value, filters))
//LPixelBuffer.drawRect(rawInts, i, shape.width.toInt, blockSize, ColorUtil.randColor)
}
i = i + 1
})
shape
}))
}
} else {
logWarn(s"getBlockWidth() = $blockSize")
}
}


/**
* draws a filled rectangle on the given index
*/
def draw(index: Int, color: Color): Unit = {
private def paint(): Unit = {
if (blockSize != 0) {
paint()
updateBuffer((_: PixelBuffer[IntBuffer]) => {
// drawRect(e.lineNumber - 1, Filter.calcColor(e.value, filtersProperty.asScala.toSeq).darker().darker())
LPixelBuffer.drawRect(rawInts, index, shape.width.toInt, blockSize, color)
cleanBackground()
var i = 0
entries.forEach(e => {
if (e.lineNumber.equals(selectedLineNumberProperty.getValue())) {
LPixelBuffer.drawRect(rawInts, i, shape.width, blockSize, Color.YELLOW)
} else {
LPixelBuffer.drawRect(rawInts, i, shape.width, blockSize, Filter.calcColor(e.value, filters))
}
i = i + 1
})
shape
})
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,13 @@ class LogFileTab(val pathAsString: String
op
}

private val chunkListView = ChunkListView(filteredList, mutLogFileSettings)

// display text to the right
private val logTextView = new LogTextView(mutLogFileSettings, filteredList)

// graphical display to the left
private val chunkListView = ChunkListView(filteredList, mutLogFileSettings, logTextView.selectLogEntry)


// start listener declarations
private lazy val scrollToEndEventListener: InvalidationListener = (_: Observable) => {
chunkListView.scrollTo(chunkListView.getItems.size())
Expand Down
43 changes: 17 additions & 26 deletions app/src/main/scala/app/logorrr/views/text/LogTextView.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package app.logorrr.views.text

import app.logorrr.conf.mut.MutLogFileSettings
import app.logorrr.model.LogEntry
import app.logorrr.util.{CanLog, ClipBoardUtils, JfxUtils}
import app.logorrr.util.{CanLog, JfxUtils}
import javafx.beans.value.ChangeListener
import javafx.collections.transformation.FilteredList
import javafx.scene.control._
Expand All @@ -23,42 +23,33 @@ object LogTextView {

class LogTextView(mutLogFileSettings: MutLogFileSettings
, filteredList: FilteredList[LogEntry]) extends ListView[LogEntry] with CanLog {
/** 'pragmatic way' to determine width of max elems in this view */
val maxLength: Int = filteredList.size().toString.length


private val selectedLineNumberListener: ChangeListener[Number] = JfxUtils.onNew((n: Number) => {
Option(getItems.filtered((t: LogEntry) => t.lineNumber == n.intValue()).get(0)) match {
case Some(value) =>
val relativeIndex = getItems.indexOf(value)
getSelectionModel.select(relativeIndex)
scrollTo(relativeIndex - ((getHeight / LogTextView.fixedCellSize) / 2).toInt)
case None =>
}
})

init()

/**
*
*/
def init(): Unit = {
getStyleClass.add("dense")
setItems(filteredList)
val i = mutLogFileSettings.selectedLineNumberProperty.get()
getSelectionModel.select(i)
getSelectionModel.select(mutLogFileSettings.selectedLineNumberProperty.get())

getSelectionModel.selectedIndexProperty().addListener(JfxUtils.onNew({ i: Number => {
mutLogFileSettings.selectedLineNumberProperty.removeListener(selectedLineNumberListener)
mutLogFileSettings.setSelectedLineNumber(i.intValue())
mutLogFileSettings.selectedLineNumberProperty.addListener(selectedLineNumberListener)
}
}))
getSelectionModel.selectedItemProperty().addListener(JfxUtils.onNew[LogEntry](e => mutLogFileSettings.setSelectedLineNumber(e.lineNumber)))
setCellFactory((_: ListView[LogEntry]) => new LogEntryListCell())
mutLogFileSettings.selectedLineNumberProperty.addListener(selectedLineNumberListener)

}

/** 'pragmatic way' to determine width of max elems in this view */
def maxLength: Int = filteredList.size().toString.length

def selectLogEntry(logEntry: LogEntry): Unit = {
getSelectionModel.select(logEntry)
val relativeIndex = getItems.indexOf(logEntry)
getSelectionModel.select(relativeIndex)
val cellHeight = lookup(".list-cell").getBoundsInLocal.getHeight
val visibleItemCount = (getHeight / cellHeight).asInstanceOf[Int]
val idx = if (relativeIndex - visibleItemCount / 2 <= 0) 0 else relativeIndex - visibleItemCount / 2
scrollTo(idx)
}


class LogEntryListCell extends ListCell[LogEntry] {
styleProperty().bind(mutLogFileSettings.fontStyleBinding)
setGraphic(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import org.scalatest.wordspec.AnyWordSpec

class BlockImageSpec extends AnyWordSpec {

"BlockImage.indexOf" should {
".a" in assert(BlockImage.indexOf(0, 0, 100, 1000) == 0)
".b" in assert(BlockImage.indexOf(0, 0, 10, 100) == 0)
".c" in assert(BlockImage.indexOf(11, 0, 10, 100) == 1)
".d" in assert(BlockImage.indexOf(99, 0, 10, 100) == 9)
".f" in assert(BlockImage.indexOf(0, 11, 10, 100) == 10)
".e" in assert(BlockImage.indexOf(99, 99, 10, 100) == 99)
}

"BlockImage.calcVirtualHeight" should {
"sc0" in assert(BlockImage.calcVirtualHeight(1, 7, 10, 0) == 0)
"sc1" in assert(BlockImage.calcVirtualHeight(1, 7, 10, 1) == 7)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class ChunkListTestApp extends Application with CanLog {
, new SimpleIntegerProperty(selectedLineNumber)
, new SimpleIntegerProperty(blockSize)
, filtersProperty
, new SimpleDoubleProperty(dividerPosition))
, new SimpleDoubleProperty(dividerPosition)
, e => ())
clv.addListeners()
val sp = new SplitPane(clv, new BorderPane(new Label("Test")))

Expand Down