From f4af24bb50be610a6b180835d3d311df1165c729 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Tue, 9 Apr 2024 23:15:32 +0300 Subject: [PATCH 1/4] add sessionTitle css class --- .../dev/nuculabs/imagetagger/ui/main-window-view.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css index a390532..d01b61a 100644 --- a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css @@ -1,3 +1,7 @@ tooltip { -fx-show-delay: 250ms; +} + +.sessionTitle { + -fx-font-size: 32; } \ No newline at end of file From 113863cc972d47997d39fc1965c56ce0d751f0c6 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Tue, 9 Apr 2024 23:18:41 +0300 Subject: [PATCH 2/4] add standalone css file for image-tags-session-header.fxml --- .../imagetagger/ui/controls/image-tags-session-header.css | 4 ++++ .../imagetagger/ui/controls/image-tags-session-header.fxml | 3 ++- .../dev/nuculabs/imagetagger/ui/main-window-view.css | 4 ---- 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css new file mode 100644 index 0000000..e3234fa --- /dev/null +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css @@ -0,0 +1,4 @@ + +.sessionTitle { + -fx-font-size: 32; +} \ No newline at end of file diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml index fdd37e2..96541e2 100644 --- a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml @@ -5,7 +5,8 @@ - + diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css index d01b61a..6a11646 100644 --- a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/main-window-view.css @@ -1,7 +1,3 @@ tooltip { -fx-show-delay: 250ms; } - -.sessionTitle { - -fx-font-size: 32; -} \ No newline at end of file From 13696d3c54ec2a24aecd21d2c3fcb2c3add2f572 Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Wed, 10 Apr 2024 00:02:44 +0300 Subject: [PATCH 3/4] implement DateTimeProvider.kt --- .../ui/utils/date/DateTimeProvider.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/utils/date/DateTimeProvider.kt diff --git a/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/utils/date/DateTimeProvider.kt b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/utils/date/DateTimeProvider.kt new file mode 100644 index 0000000..72869dd --- /dev/null +++ b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/utils/date/DateTimeProvider.kt @@ -0,0 +1,27 @@ +package dev.nuculabs.imagetagger.ui.utils.date + +import java.text.DateFormat +import java.text.SimpleDateFormat +import java.util.* + +interface IDateTimeProvider { + /** + * Returns today's short date. For example: 09 April 2024 + */ + fun getTodayShortDate(): String +} + +/** + * Utilities for providing date and time related values. + */ +class DateTimeProvider : IDateTimeProvider { + + /** + * Returns today's short date. For example: 09 April 2024 + */ + override fun getTodayShortDate(): String { + val dateFormat: DateFormat = SimpleDateFormat("dd MMMM YYYY", Locale.ENGLISH) + val date = Date() + return dateFormat.format(date) + } +} \ No newline at end of file From 87339f853eb6f5c2c2ce2e5d5ab66ae204f105de Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Wed, 10 Apr 2024 00:17:01 +0300 Subject: [PATCH 4/4] implement ImageTagsSessionHeader feature --- .../imagetagger/ui/MainPageController.kt | 16 +++++ .../ui/controls/ImageTagsSessionHeader.kt | 66 +++++++++++++++++++ .../ui/controls/image-tags-session-header.css | 2 +- .../controls/image-tags-session-header.fxml | 5 +- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/MainPageController.kt b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/MainPageController.kt index 08902c1..502d86d 100644 --- a/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/MainPageController.kt +++ b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/MainPageController.kt @@ -1,6 +1,7 @@ package dev.nuculabs.imagetagger.ui import dev.nuculabs.imagetagger.ui.controls.ImageTagsEntryControl +import dev.nuculabs.imagetagger.ui.controls.ImageTagsSessionHeader import javafx.application.Platform import javafx.fxml.FXML import javafx.scene.control.Button @@ -93,6 +94,11 @@ class MainPageController { // Create a new thread to predict the image tags. Thread { logger.info("Analyzing $imageFilesTotal files") + if (filePaths.isNotEmpty()) { + Platform.runLater { + addNewImagePredictionHeader(imageFilesTotal, filePaths.first().parent) + } + } filePaths.forEach { filePath -> if (isCurrentTagsOperationCancelled) { logger.info("Cancelling current prediction operation.") @@ -171,6 +177,16 @@ class MainPageController { verticalBox.children.add(Separator()) } + /** + * Display the image prediction session header on the UI. + */ + fun addNewImagePredictionHeader(totalImages: Int, directoryPath: String) { + val imageSessionHeader = ImageTagsSessionHeader() + imageSessionHeader.updateHeader(totalImages, directoryPath) + verticalBox.children.add(imageSessionHeader) + verticalBox.children.add(Separator()) + } + /** * Updates the progress bar of the UI. */ diff --git a/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/controls/ImageTagsSessionHeader.kt b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/controls/ImageTagsSessionHeader.kt index 6da8dff..feb8603 100644 --- a/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/controls/ImageTagsSessionHeader.kt +++ b/img-ui/src/main/kotlin/dev/nuculabs/imagetagger/ui/controls/ImageTagsSessionHeader.kt @@ -1,10 +1,37 @@ package dev.nuculabs.imagetagger.ui.controls +import dev.nuculabs.imagetagger.ui.alerts.ErrorAlert +import dev.nuculabs.imagetagger.ui.utils.date.DateTimeProvider +import dev.nuculabs.imagetagger.ui.utils.date.IDateTimeProvider +import javafx.fxml.FXML import javafx.fxml.FXMLLoader +import javafx.scene.control.Button +import javafx.scene.control.Label import javafx.scene.layout.HBox +import java.awt.Desktop +import java.io.File import java.io.IOException +import java.util.logging.Logger class ImageTagsSessionHeader : HBox() { + private val logger: Logger = Logger.getLogger("ImageTagsSessionHeader") + + /** + * Is a provider for providing the date-time data for setting the title's header. + */ + var dateTimeProvider: IDateTimeProvider = DateTimeProvider() + + /** + * Is the path that will be opened when the open directory button is clicked. + */ + private var directoryPath: String? = null + + @FXML + private lateinit var title: Label + + @FXML + private lateinit var openDirectoryButton: Button + init { val fxmlLoader = FXMLLoader( ImageTagsSessionHeader::class.java.getResource("image-tags-session-header.fxml") @@ -16,5 +43,44 @@ class ImageTagsSessionHeader : HBox() { } catch (exception: IOException) { throw RuntimeException(exception) } + + updateHeader(0) + } + + /** + * Updates the header with the number of images and the directory path. + */ + fun updateHeader(numberOfImages: Int, directoryPath: String? = null) { + // set directory path and button visibility + this.directoryPath = directoryPath + if (this.directoryPath == null) { + this.openDirectoryButton.isVisible = false + } else { + this.openDirectoryButton.isVisible = true + } + + // update header title + val shortDate = dateTimeProvider.getTodayShortDate() + this.title.text = "$shortDate ($numberOfImages Images)" + } + + /** + * Opens the directory in the user's Desktop. + */ + fun openDirectory() { + this.directoryPath?.let { + if (Desktop.isDesktopSupported()) { + val desktop = Desktop.getDesktop() + if (desktop.isSupported(Desktop.Action.OPEN)) { + desktop.open(File(it)) + } else { + logger.severe("Cannot open image directory $it. Desktop action not supported!") + ErrorAlert("Can't open file: $it\nOperation is not supported!") + } + } else { + logger.severe("Cannot open image directory $it. Desktop action not supported!") + ErrorAlert("Can't open file: $it\nOperation is not supported!") + } + } } } \ No newline at end of file diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css index e3234fa..161176f 100644 --- a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.css @@ -1,4 +1,4 @@ .sessionTitle { - -fx-font-size: 32; + -fx-font-size: 24; } \ No newline at end of file diff --git a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml index 96541e2..bc5ecfd 100644 --- a/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml +++ b/img-ui/src/main/resources/dev/nuculabs/imagetagger/ui/controls/image-tags-session-header.fxml @@ -10,9 +10,9 @@ -