Skip to content

Commit

Permalink
Merge pull request #531 from saalfeldlab/feat/1.2.0
Browse files Browse the repository at this point in the history
Feat/1.2.0
  • Loading branch information
cmhulbert committed May 13, 2024
2 parents aaccbd3 + 59de043 commit 74814ec
Show file tree
Hide file tree
Showing 19 changed files with 830 additions and 545 deletions.
13 changes: 13 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# .github/release.yml

changelog:
categories:
- title: Features
labels:
- '*'
exclude:
labels:
- dependencies
- title: Dependencies
labels:
- dependencies
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Build All Installers
name: Build Installers

on:
push:
branches: [ master ]
workflow_call:
pull_request:
branches: [ master ]
workflow_dispatch:
branches: [ master ]
branches: [master]

env:
DEV_IDENTITY: BXPZTQZ35S # Your Apple Dev identity, something like BXPZTQZ35S
Expand All @@ -21,9 +18,14 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, macos-14]
runs-on: ${{ matrix.os }}
env:
RELEASE_INSTALLERS: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set Version
shell: bash
run: |
short_version=`git rev-parse --short HEAD`
echo "VERSION=$short_version" >> $GITHUB_ENV
- name: Download Wix
uses: i3h/download-release-asset@v1
if: matrix.os == 'windows-latest'
Expand All @@ -42,7 +44,7 @@ jobs:
run: echo "$HOME/target/wix" >> $GITHUB_PATH
if: matrix.os == 'windows-latest'
- uses: actions/checkout@v2
- name: Set up JDK 17
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: 18.0.2
Expand All @@ -58,14 +60,11 @@ jobs:
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
if: ${{ env.MACOS_CERTIFICATE == null && (matrix.os == 'macos-latest' || matrix.os == 'macos-14') }}
run: mvn -B clean install -DskipTests -Pbuild-installer "-Dmatrix.os=${{ matrix.os }}" --file pom.xml
- name: Update Automatic Release
uses: marvinpinto/action-automatic-releases@latest
if: ${{ env.RELEASE_INSTALLERS }}

- name: Upload Installers
uses: actions/upload-artifact@v4
with:
repo_token: "${{ secrets.GITHUB_TOKEN}}"
automatic_release_tag: ${{ matrix.os }}
prerelease: true
title: ${{ matrix.os }} Development Build
files: |
name: Paintera-${{ matrix.os }}-${{ env.VERSION }}
path: |
${{ env.DMG_PATH }}
./target/installer-${{ matrix.os }}/*
./target/installer-${{ matrix.os }}/*
50 changes: 50 additions & 0 deletions .github/workflows/publish-installers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Publish Installers

on:
push:
tags: "paintera-*.*.*"
workflow_dispatch:



env:
DEV_IDENTITY: BXPZTQZ35S # Your Apple Dev identity, something like BXPZTQZ35S
PRIMARY_BUNDLE_ID: org.janelia.saalfeldlab.Paintera # Unique to your app, often the launcher class

jobs:
build_installers:
name: Build Installers
uses: ./.github/workflows/build-installers.yml

create_release:
needs: build_installers
runs-on: ubuntu-latest
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
- name: Set Version
run: |
tag_name=$(echo ${{ github.ref }} | grep -oE "[^/]+$")
echo "VERSION=$tag_name" >> $GITHUB_ENV
- name: Display structure of downloaded files
run: ls -R
- name: Rename Artifacts
run: |
mv Paintera-windows-latest-*/*.msi Paintera-${{ env.VERSION }}-Windows.msi
mv Paintera-ubuntu-latest-*/*.deb Paintera-${{ env.VERSION }}_x86_64.deb
mv Paintera-macos-latest-*/*.dmg Paintera-${{ env.VERSION }}-MacOS.dmg
mv Paintera-macos-14-*/*.dmg Paintera-${{ env.VERSION }}-MacOS-AppleSilicon.dmg
- name: Create Release
uses: softprops/action-gh-release@v2
with:
name: Paintera ${{ env.VERSION }}
tag_name: ${{ github.ref }}
prerelease: false
files: |
Paintera-${{ env.VERSION }}-Windows.msi
Paintera-${{ env.VERSION }}_x86_64.deb
Paintera-${{ env.VERSION }}-MacOS.dmg
Paintera-${{ env.VERSION }}-MacOS-AppleSilicon.dmg
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>paintera</artifactId>
<version>1.1.1-SNAPSHOT</version>
<version>1.2.0-SNAPSHOT</version>

<name>Paintera</name>
<description>New Era Painting and annotation tool</description>
Expand Down Expand Up @@ -53,7 +53,7 @@
<javadoc.skip>true</javadoc.skip>
<maven.javadoc.skip>${javadoc.skip}</maven.javadoc.skip>

<saalfx.version>1.2.0</saalfx.version>
<saalfx.version>1.3.0</saalfx.version>

<janino.version>3.0.7</janino.version>
<logback.version>1.4.0</logback.version>
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/org/janelia/saalfeldlab/fx/ui/ActionBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ActionBar : HBox() {
var newGroup : ToggleGroup? = null
buttons.forEach { node ->
(node as? Toggle)?.apply {
toggleGroup = toggleGroup ?: ToggleGroup().also { newGroup = it }
toggleGroup = toggleGroup ?: newGroup ?: ToggleGroup().also { newGroup = it }
}
}
toggleGroup = newGroup
Expand Down Expand Up @@ -77,7 +77,7 @@ class ActionBar : HBox() {

fun List<ToolBarItem>.toolBarNodes() = map { item ->
item.toolBarButton.apply {
this.onAction ?: let {
onAction ?: let {
userData = item
}
isFocusTraversable = false
Expand Down
61 changes: 31 additions & 30 deletions src/main/kotlin/org/janelia/saalfeldlab/paintera/BindingKeys.kt
Original file line number Diff line number Diff line change
Expand Up @@ -103,36 +103,37 @@ private class LateInitNamedKeyCombination(keyCombination: KeyCombination, initNa
}

enum class LabelSourceStateKeys(lateInitNamedKeyCombo : LateInitNamedKeyCombination) : NamedKeyBinding by lateInitNamedKeyCombo {
SELECT_ALL ( CONTROL_DOWN + A),
SELECT_ALL_IN_CURRENT_VIEW ( CONTROL_DOWN + SHIFT_DOWN + A),
LOCK_SEGMENT ( L),
NEXT_ID ( N),
COMMIT_DIALOG ( C + CONTROL_DOWN),
MERGE_ALL_SELECTED ( ENTER + CONTROL_DOWN),
ARGB_STREAM__INCREMENT_SEED ( C),
ARGB_STREAM__DECREMENT_SEED ( C + SHIFT_DOWN),
REFRESH_MESHES ( R),
CANCEL ( ESCAPE, "cancel tool / exit mode"),
TOGGLE_NON_SELECTED_LABELS_VISIBILITY ( V + SHIFT_DOWN, "toggle non-selected labels visibility"),
SEGMENT_ANYTHING__TOGGLE_MODE ( A),
PAINT_BRUSH ( SPACE),
FILL_2D ( F),
FILL_3D ( SHIFT_DOWN + F),
CLEAR_CANVAS ( CONTROL_DOWN + SHIFT_DOWN + C),
INTERSECT_UNDERLYING_LABEL ( SHIFT_DOWN + R),
SHAPE_INTERPOLATION__TOGGLE_MODE ( S),
SHAPE_INTERPOLATION__TOGGLE_PREVIEW ( CONTROL_DOWN + P),
SHAPE_INTERPOLATION__ACCEPT_INTERPOLATION ( ENTER),
SHAPE_INTERPOLATION__SELECT_FIRST_SLICE ( SHIFT_DOWN + LEFT),
SHAPE_INTERPOLATION__SELECT_LAST_SLICE ( SHIFT_DOWN + RIGHT),
SHAPE_INTERPOLATION__SELECT_PREVIOUS_SLICE ( LEFT),
SHAPE_INTERPOLATION__SELECT_NEXT_SLICE ( RIGHT ),
SHAPE_INTERPOLATION__REMOVE_SLICE_1 ( DELETE, "delete current slice "),
SHAPE_INTERPOLATION__REMOVE_SLICE_2 ( BACK_SPACE, "delete current slice "),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_LEFT ( OPEN_BRACKET, "shape interpolation: auto SAM: new slice left" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICES_BISECT ( QUOTE, "shape interpolation: auto SAM: new bisect slices" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_RIGHT ( CLOSE_BRACKET, "shape interpolation: auto SAM: new slice right" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_HERE ( SHIFT_DOWN + A, "shape interpolation: auto SAM: new slice at current location" ),
SELECT_ALL ( CONTROL_DOWN + A),
SELECT_ALL_IN_CURRENT_VIEW ( CONTROL_DOWN + SHIFT_DOWN + A),
LOCK_SEGMENT ( L),
NEXT_ID ( N),
COMMIT_DIALOG ( C + CONTROL_DOWN),
MERGE_ALL_SELECTED ( ENTER + CONTROL_DOWN),
ARGB_STREAM__INCREMENT_SEED ( C),
ARGB_STREAM__DECREMENT_SEED ( C + SHIFT_DOWN),
REFRESH_MESHES ( R),
CANCEL ( ESCAPE, "cancel tool / exit mode"),
TOGGLE_NON_SELECTED_LABELS_VISIBILITY ( V + SHIFT_DOWN, "toggle non-selected labels visibility"),
SEGMENT_ANYTHING__TOGGLE_MODE ( A),
PAINT_BRUSH ( SPACE),
FILL_2D ( F),
FILL_3D ( SHIFT_DOWN + F),
CLEAR_CANVAS ( CONTROL_DOWN + SHIFT_DOWN + C),
INTERSECT_UNDERLYING_LABEL ( SHIFT_DOWN + R),
SHAPE_INTERPOLATION__TOGGLE_MODE ( S),
SHAPE_INTERPOLATION__TOGGLE_PREVIEW ( CONTROL_DOWN + P),
SHAPE_INTERPOLATION__ACCEPT_INTERPOLATION ( ENTER),
SHAPE_INTERPOLATION__SELECT_FIRST_SLICE ( SHIFT_DOWN + LEFT),
SHAPE_INTERPOLATION__SELECT_LAST_SLICE ( SHIFT_DOWN + RIGHT),
SHAPE_INTERPOLATION__SELECT_PREVIOUS_SLICE ( LEFT),
SHAPE_INTERPOLATION__SELECT_NEXT_SLICE ( RIGHT ),
SHAPE_INTERPOLATION__REMOVE_SLICE_1 ( DELETE, "delete current slice "),
SHAPE_INTERPOLATION__REMOVE_SLICE_2 ( BACK_SPACE, "delete current slice "),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_LEFT ( OPEN_BRACKET, "shape interpolation: auto SAM: new slice left" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICES_BISECT ( QUOTE, "shape interpolation: auto SAM: new slice between closest slices" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICES_BISECT_ALL ( SHIFT_DOWN + QUOTE, "shape interpolation: auto SAM: new slice between all slices" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_RIGHT ( CLOSE_BRACKET, "shape interpolation: auto SAM: new slice right" ),
SHAPE_INTERPOLATION__AUTO_SAM__NEW_SLICE_HERE ( SHIFT_DOWN + A, "shape interpolation: auto SAM: new slice at current location" ),
;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,23 @@ class LoggingConfig {
.apply { addTriggeredListener { _, _, level -> LogUtils.rootLoggerLevel = level } }
var rootLoggerLevel: Level by rootLoggerLevelProperty.nonnull()

val isLoggingEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_ENABLED)
.apply {
val isLoggingEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_ENABLED).apply {
addTriggeredListener { _, _, new ->
LogUtils.setLoggingEnabled(new)
loggerLevels.forEach { (logger, level) -> LogUtils.setLogLevelFor(logger, level.get()) }
}
}
var isLoggingEnabled: Boolean by isLoggingEnabledProperty.nonnull()

val isLoggingToConsoleEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_TO_CONSOLE_ENABLED)
.apply {
val isLoggingToConsoleEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_TO_CONSOLE_ENABLED).apply {
addTriggeredListener { _, _, new ->
LogUtils.setLoggingToConsoleEnabled(new)
loggerLevels.forEach { (logger, level) -> LogUtils.setLogLevelFor(logger, level.get()) }
}
}
var isLoggingToConsoleEnabled: Boolean by isLoggingEnabledProperty.nonnull()

val isLoggingToFileEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_TO_FILE_ENABLED)
.apply {
val isLoggingToFileEnabledProperty = SimpleBooleanProperty(DEFAULT_IS_LOGGING_TO_FILE_ENABLED).apply {
addTriggeredListener { _, _, new ->
LogUtils.setLoggingToFileEnabled(new)
loggerLevels.forEach { (logger, level) -> LogUtils.setLogLevelFor(logger, level.get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.janelia.saalfeldlab.paintera.config

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon
import javafx.beans.InvalidationListener
import javafx.beans.property.ObjectProperty
Expand All @@ -20,10 +21,12 @@ import org.janelia.saalfeldlab.fx.Buttons
import org.janelia.saalfeldlab.fx.Labels
import org.janelia.saalfeldlab.fx.TitledPanes
import org.janelia.saalfeldlab.fx.extensions.TitledPaneExtensions
import org.janelia.saalfeldlab.fx.ui.MatchSelection
import org.janelia.saalfeldlab.fx.ui.NamedNode
import org.janelia.saalfeldlab.paintera.ui.FontAwesome
import org.janelia.saalfeldlab.paintera.ui.PainteraAlerts
import org.janelia.saalfeldlab.paintera.util.logging.LogUtils
import org.slf4j.LoggerFactory

class LoggingConfigNode(private val config: LoggingConfig) {

Expand Down Expand Up @@ -122,12 +125,25 @@ class LoggingConfigNode(private val config: LoggingConfig) {
}
}
}

val loggerList = FXCollections.observableArrayList<String>()
val updateLoggerList = {
(LoggerFactory.getILoggerFactory() as? LoggerContext)?.let {
loggerList.setAll(it.loggerList.map { logger -> logger.name }.toList())
}
}
val newLoggerField = TextField("")
val newLoggerChoiceBox = logLevelChoiceBox(null)
val matcherField = MatchSelection.fuzzyTop(loggerList, { name -> newLoggerField.text = name }, 5)
matcherField.emptyBehavior = MatchSelection.EmptyBehavior.MATCH_NONE
matcherField.promptText = "Search for Loggers..."
matcherField.focusedProperty().addListener { _, _, focused -> if (focused) updateLoggerList() }

val newLogLevelChoiceBox = logLevelChoiceBox(null)
val newLoggerButton = Buttons
.withTooltip(null) { config.setLogLevelFor(newLoggerField.text, newLoggerChoiceBox.value) }
.withTooltip(null) { config.setLogLevelFor(newLoggerField.text, newLogLevelChoiceBox.value) }
.also { it.graphic = FontAwesome[FontAwesomeIcon.PLUS, 2.0] }
val listener = InvalidationListener {
updateLoggerList()
val name = newLoggerField.text
val isRootLoggerName = LogUtils.rootLogger.name == name
val isExistingLogger = name in keys
Expand All @@ -147,11 +163,13 @@ class LoggingConfigNode(private val config: LoggingConfig) {
newLoggerField.textProperty().addListener(listener)
listener.invalidated(newLoggerField.textProperty())
add(newLoggerField, 0, row)
add(newLoggerChoiceBox, 1, row)
add(newLogLevelChoiceBox, 1, row)
add(newLoggerButton, 2, row)
add(matcherField, 0, row + 1, GridPane.REMAINING, GridPane.REMAINING)
GridPane.setHgrow(matcherField, Priority.ALWAYS)
GridPane.setVgrow(matcherField, Priority.ALWAYS)
matcherField.maxWidthProperty().bind(widthProperty())
}


}

}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import org.janelia.saalfeldlab.paintera.id.IdService
import org.janelia.saalfeldlab.paintera.stream.AbstractHighlightingARGBStream
import org.janelia.saalfeldlab.paintera.stream.HighlightingStreamConverter
import org.janelia.saalfeldlab.paintera.util.IntervalHelpers
import org.janelia.saalfeldlab.paintera.util.IntervalHelpers.Companion.extendBy
import org.janelia.saalfeldlab.paintera.util.IntervalHelpers.Companion.smallestContainingInterval
import org.janelia.saalfeldlab.util.*
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -187,11 +188,9 @@ class ShapeInterpolationController<D : IntegerType<D>>(
?.also { repaintInterval ->
if (preview) {
isBusy = true
requestRepaintInterval = repaintInterval union requestRepaintInterval
interpolateBetweenSlices(false)
} else {
requestRepaintAfterTasks(repaintInterval)
}
requestRepaintAfterTasks(repaintInterval)
}
}

Expand Down Expand Up @@ -364,6 +363,7 @@ class ShapeInterpolationController<D : IntegerType<D>>(
Last
}

//TODO Caleb: Controller should not move, let the tool/mode do that
fun editSelection(choice: EditSelectionChoice) {
val slices = slicesAndInterpolants.slices
when (choice) {
Expand Down Expand Up @@ -751,7 +751,9 @@ class ShapeInterpolationController<D : IntegerType<D>>(
val interpolatedMaskView = interpolant.dataInterpolant
.affine(viewerMask.currentGlobalToMaskTransform)
.interval(interpolantIntervalSliceInMaskSpace)
val fillMaskOverInterval = viewerMask.viewerImg.interval(interpolantIntervalSliceInMaskSpace)
val fillMaskOverInterval = viewerMask.viewerImg.apply {
extendValue(Label.INVALID)
}.interval(interpolantIntervalSliceInMaskSpace)

LoopBuilder.setImages(interpolatedMaskView, fillMaskOverInterval)
.multiThreaded()
Expand Down Expand Up @@ -1164,7 +1166,7 @@ class ShapeInterpolationController<D : IntegerType<D>>(
computeBoundingBoxInInitialMask()
}
val globalBoundingBox: RealInterval?
get() = maskBoundingBox?.let { mask.initialGlobalToMaskTransform.inverse().estimateBounds(it) }
get() = maskBoundingBox?.let { mask.initialMaskToGlobalWithDepthTransform.estimateBounds(it.extendBy(0.0, 0.0, .5)) }

private val selectionIntervals: MutableList<Interval> = mutableListOf()

Expand Down
Loading

0 comments on commit 74814ec

Please sign in to comment.