Skip to content

Commit

Permalink
+ ide basic customization
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilbocc committed Jan 18, 2021
1 parent 8f32e27 commit 9a1b510
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,46 +1,20 @@
package it.unibo.tuprolog.ui.gui

import javafx.application.Application
import javafx.event.EventHandler
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.scene.control.Alert
import javafx.scene.control.ButtonType
import javafx.stage.Stage
import javafx.stage.WindowEvent
import kotlin.system.exitProcess


class PrologIDEApplication : Application() {
override fun start(stage: Stage) {
try {
val loader = FXMLLoader(javaClass.getResource("PrologIDEView.fxml"))
val root = loader.load<Parent>()
stage.title = "tuProlog IDE"
stage.scene = Scene(root)
stage.icons.add(TUPROLOG_LOGO)
stage.onCloseRequest = EventHandler(this::onCloseRequest)
stage.scene.stylesheets += JAVA_KEYWORDS_LIGHT
stage.scene.stylesheets += LIGHT_CODE_AREA
stage.show()
PrologIdeBuilder(stage).show()
} catch (e: Throwable) {
e.printStackTrace()
throw Error(e)
}
}

private fun onCloseRequest(e: WindowEvent) {
val alert = Alert(Alert.AlertType.CONFIRMATION)
alert.title = "Close tuProlog IDE"
alert.headerText = "Confirmation"
alert.contentText = "Are you absolutely sure you wanna close the IDE?"
alert.showAndWait().ifPresent {
if (it != ButtonType.OK) {
e.consume()
}
}
}

override fun stop() {
exitProcess(0)
}
Expand All @@ -51,4 +25,4 @@ class PrologIDEApplication : Application() {
launch(PrologIDEApplication::class.java)
}
}
}
}
44 changes: 20 additions & 24 deletions ide/src/main/kotlin/it/unibo/tuprolog/ui/gui/PrologIDEController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class PrologIDEController : Initializable {

private val model = PrologIDEModel.of()

private var onClose = {}

private var onAbout = {}

@FXML
private lateinit var root: Parent

Expand Down Expand Up @@ -505,15 +509,7 @@ class PrologIDEController : Initializable {

@FXML
fun onQuitRequested(e: ActionEvent) {
val alert = Alert(Alert.AlertType.CONFIRMATION)
alert.title = "Close tuProlog IDE"
alert.headerText = "Confirmation"
alert.contentText = "Are you absolutely sure you wanna close the IDE?"
alert.showAndWait().ifPresent {
if (it == ButtonType.OK) {
stage.close()
}
}
this.onClose()
}

private fun onCaretMovedIn(area: CodeArea) {
Expand Down Expand Up @@ -680,20 +676,20 @@ class PrologIDEController : Initializable {

@FXML
fun onAbout(e: ActionEvent) {
val dialog = Alert(Alert.AlertType.INFORMATION)
dialog.title = "About"
dialog.headerText = "tuProlog IDE v${Info.VERSION}"
dialog.dialogPane.graphic = ImageView(TUPROLOG_LOGO).also {
it.fitWidth = TUPROLOG_LOGO.width * 0.3
it.fitHeight = TUPROLOG_LOGO.height * 0.3
}
dialog.contentText =
"""
|Running on:
| - 2P-Kt v${Info.VERSION}
| - JVM v${System.getProperty("java.version")}
| - JavaFX v${System.getProperty("javafx.runtime.version")}
""".trimMargin()
dialog.showAndWait()
this.onAbout()
}

fun customizeModel(setup: (PrologIDEModel) -> Unit) = setup(model)

fun addTab(tab: Tab) {
this.tabsStreams.tabs.add(tab)
}

fun setOnClose(onClose: () -> Unit) {
this.onClose = onClose
}

fun setOnAbout(onAbout: () -> Unit) {
this.onAbout = onAbout
}
}
12 changes: 11 additions & 1 deletion ide/src/main/kotlin/it/unibo/tuprolog/ui/gui/PrologIDEModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@ package it.unibo.tuprolog.ui.gui

import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.core.exception.TuPrologException
import it.unibo.tuprolog.solve.MutableSolver
import it.unibo.tuprolog.solve.Solution
import it.unibo.tuprolog.solve.TimeDuration
import it.unibo.tuprolog.solve.channel.InputChannel
import it.unibo.tuprolog.solve.channel.OutputChannel
import it.unibo.tuprolog.solve.classic.classicWithDefaultBuiltins
import it.unibo.tuprolog.solve.exception.PrologWarning
import it.unibo.tuprolog.solve.library.Libraries
import it.unibo.tuprolog.solve.libs.io.IOLib
import it.unibo.tuprolog.solve.libs.oop.OOPLib
import org.reactfx.EventStream
import java.io.File
import java.util.concurrent.ExecutorService
import java.util.concurrent.ForkJoinPool


interface PrologIDEModel {

companion object {
fun of(executor: ExecutorService = ForkJoinPool.commonPool()): PrologIDEModel = PrologIDEModelImpl(executor)
fun of(executor: ExecutorService = ForkJoinPool.commonPool()): PrologIDEModel = PrologIDEModelImpl(executor) {}
}

enum class State {
Expand All @@ -26,6 +34,8 @@ interface PrologIDEModel {

val executor: ExecutorService

fun customizeSolver(customizer : (MutableSolver) -> Unit)

fun newFile(): File

fun loadFile(file: File)
Expand Down
13 changes: 10 additions & 3 deletions ide/src/main/kotlin/it/unibo/tuprolog/ui/gui/PrologIDEModelImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import java.util.EnumSet
import java.util.concurrent.ExecutorService
import kotlin.system.exitProcess

internal class PrologIDEModelImpl(override val executor: ExecutorService) : PrologIDEModel {
internal class PrologIDEModelImpl(override val executor: ExecutorService, var customizer : ((MutableSolver) -> Unit)?) : PrologIDEModel {

private data class FileContent(var text: String, var changed: Boolean = true) {
fun text(text: String) {
Expand Down Expand Up @@ -111,6 +111,12 @@ internal class PrologIDEModelImpl(override val executor: ExecutorService) : Prol
override var state: State = State.IDLE
private set

override fun customizeSolver(customizer: (MutableSolver) -> Unit) {
this.customizer = customizer
this.solver.invalidate()
this.solver.regenerate()
}

private inline fun <T> ensuringStateIs(state: State, vararg states: State, action: () -> T): T {
if (EnumSet.of(state, *states).contains(this.state)) {
return action()
Expand All @@ -126,8 +132,9 @@ internal class PrologIDEModelImpl(override val executor: ExecutorService) : Prol
stdOut = OutputChannel.of { onStdoutPrinted.push(it) },
stdErr = OutputChannel.of { onStderrPrinted.push(it) },
warnings = OutputChannel.of { onWarning.push(it) },
).also {
onNewSolver.push(SolverEvent(Unit, it))
).also { solver ->
this.customizer?.let { it(solver) }
onNewSolver.push(SolverEvent(Unit, solver))
}
}

Expand Down
86 changes: 86 additions & 0 deletions ide/src/main/kotlin/it/unibo/tuprolog/ui/gui/PrologIdeBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package it.unibo.tuprolog.ui.gui

import it.unibo.tuprolog.Info
import javafx.event.EventHandler
import javafx.fxml.FXMLLoader
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.scene.control.Alert
import javafx.scene.control.ButtonType
import javafx.scene.image.Image
import javafx.stage.Stage
import javafx.scene.control.Tab
import it.unibo.tuprolog.solve.library.AliasedLibrary
import javafx.scene.image.ImageView


data class PrologIdeBuilder(
val stage: Stage,
var title: String = "tuProlog IDE",
var icon: Image = TUPROLOG_LOGO,
var onClose: () -> Boolean = {
val alert = Alert(Alert.AlertType.CONFIRMATION)
alert.title = "Close tuProlog IDE"
alert.headerText = "Confirmation"
alert.contentText = "Are you absolutely sure you wanna close the IDE?"
alert.showAndWait().map {
it == ButtonType.OK
}.get()
},
var onAbout: () -> Unit = {
val dialog = Alert(Alert.AlertType.INFORMATION)
dialog.title = "About"
dialog.headerText = "tuProlog IDE v${Info.VERSION}"
dialog.dialogPane.graphic = ImageView(TUPROLOG_LOGO).also {
it.fitWidth = TUPROLOG_LOGO.width * 0.3
it.fitHeight = TUPROLOG_LOGO.height * 0.3
}
dialog.contentText =
"""
|Running on:
| - 2P-Kt v${Info.VERSION}
| - JVM v${System.getProperty("java.version")}
| - JavaFX v${System.getProperty("javafx.runtime.version")}
""".trimMargin()
dialog.showAndWait()
},
var stylesheets: Collection<String> = listOf(JAVA_KEYWORDS_LIGHT, LIGHT_CODE_AREA),
var customLibraries: Collection<AliasedLibrary> = emptyList(),
var customTabs: Collection<Pair<Tab, (PrologIDEModel) -> Unit>> = emptyList()
) {

fun title(title: String) = apply { this.title = title }
fun icon(icon: Image) = apply { this.icon = icon }
fun onClose(onClose: () -> Boolean) = apply { this.onClose = onClose }
fun onAbout(onAbout: () -> Unit) = apply { this.onAbout = onAbout }
fun stylesheets(stylesheets: Collection<String>) = apply { this.stylesheets = stylesheets }
fun customLibraries(customLibraries: Collection<AliasedLibrary>) = apply { this.customLibraries = customLibraries }
fun customTabs(customTabs: Collection<Pair<Tab, (PrologIDEModel) -> Unit>>) =
apply { this.customTabs = customTabs }

fun show() {
val loader = FXMLLoader(javaClass.getResource("PrologIDEView.fxml"))
val root = loader.load<Parent>()
stage.scene = Scene(root)
stage.title = this.title
stage.icons.add(this.icon)
stage.onCloseRequest = EventHandler { e -> if (!this.onClose()) e.consume() }
stage.scene.stylesheets.addAll(this.stylesheets)

val controller = loader.getController() as PrologIDEController
controller.setOnAbout(this.onAbout)
controller.setOnClose { if (this.onClose()) this.stage.close() }
customTabs.forEach {
controller.addTab(it.first)
}

controller.customizeModel {
it.customizeSolver {
customLibraries.forEach { lib -> it.loadLibrary(lib) }
}
customTabs.forEach { tab -> tab.second(it) }
}

this.stage.show()
}
}

0 comments on commit 9a1b510

Please sign in to comment.