Skip to content

Commit

Permalink
Add clone event ability (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Apr 6, 2021
1 parent fa3c934 commit 3458251
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 69 deletions.
Expand Up @@ -3,6 +3,7 @@ package com.krystal.bull.gui.dialog
import com.krystal.bull.gui.home.InitEventParams
import com.krystal.bull.gui.{GlobalData, KrystalBullUtil}
import org.bitcoins.core.protocol.tlv.EnumEventDescriptorV0TLV
import org.bitcoins.core.util.TimeUtil
import scalafx.Includes._
import scalafx.geometry.{Insets, Pos}
import scalafx.scene.Node
Expand All @@ -11,39 +12,64 @@ import scalafx.scene.layout.{GridPane, HBox, VBox}
import scalafx.stage.Window
import scalafx.util.StringConverter

import java.util.Date

object CreateEnumEventDialog {

def showAndWait(parentWindow: Window): Option[InitEventParams] = {
def showAndWait(
parentWindow: Window,
initParamsOpt: Option[InitEventParams]): Option[InitEventParams] = {
val descriptorOpt =
initParamsOpt.map(_.descriptorTLV.asInstanceOf[EnumEventDescriptorV0TLV])
val titleStr = initParamsOpt match {
case Some(value) => s"Clone of ${value.sanitizedEventName}"
case None => "Create New Enum Event"
}

val dialog = new Dialog[Option[InitEventParams]]() {
initOwner(parentWindow)
title = "Create Enum Event"
title = titleStr
}

dialog.dialogPane().buttonTypes = Seq(ButtonType.OK, ButtonType.Cancel)
dialog.dialogPane().stylesheets = GlobalData.currentStyleSheets
dialog.resizable = true

val eventNameTF = new TextField()
val datePicker: DatePicker = new DatePicker()
val eventNameTF = new TextField() {
text = initParamsOpt.map(_.sanitizedEventName).getOrElse("")
minWidth = 300
}

val appendDateCheckBox = new CheckBox() {
alignmentInParent = Pos.CenterRight
selected = initParamsOpt.exists(_.hasAppendedDate)
}

val datePicker: DatePicker = new DatePicker() {
minWidth = 300
}

val hourPicker = new ComboBox[Int](1.to(12)) {
value = 12
value = initParamsOpt.map(_.hour).getOrElse(12)
}

val minutePicker = new ComboBox[Int](0.to(59)) {
value = 0
value = initParamsOpt.map(_.minute).getOrElse(0)
converter = new StringConverter[Int] {
override def fromString(string: String): Int = string.toInt

override def toString(t: Int): String = {
if (t < 10) {
s"0$t"
} else t.toString
if (t < 10) s"0$t"
else t.toString
}
}
}

val amOrPmPicker = new ComboBox[String](Vector("AM", "PM")) {
value = "AM"
value = initParamsOpt.map(_.isAM) match {
case Some(true) | None => "AM"
case Some(false) => "PM"
}
}

val outcomeMap: scala.collection.mutable.Map[Int, TextField] =
Expand All @@ -57,9 +83,11 @@ object CreateEnumEventDialog {
vgap = 5
}

def addOutcomeRow(): Unit = {
def addOutcomeRow(string: String = ""): Unit = {

val outcomeTF = new TextField()
val outcomeTF = new TextField() {
text = string
}
val row = nextOutcomeRow
outcomeMap.addOne((row, outcomeTF))

Expand All @@ -72,8 +100,13 @@ object CreateEnumEventDialog {
dialog.dialogPane().getScene.getWindow.sizeToScene()
}

addOutcomeRow()
addOutcomeRow()
descriptorOpt match {
case Some(descriptor) =>
descriptor.outcomes.foreach(outcome => addOutcomeRow(outcome))
case None =>
addOutcomeRow()
addOutcomeRow()
}

val addOutcomeButton: Button = new Button("+") {
onAction = _ => addOutcomeRow()
Expand All @@ -93,6 +126,12 @@ object CreateEnumEventDialog {
add(new Label("Event Name"), 0, row)
add(eventNameTF, 1, row)

if (GlobalData.advancedMode) {
row += 1
add(new Label("Append date to name"), 0, row)
add(appendDateCheckBox, 1, row)
}

row += 1
add(new Label("Maturity Date"), 0, row)
add(datePicker, 1, row)
Expand Down Expand Up @@ -137,14 +176,20 @@ object CreateEnumEventDialog {
// When the OK button is clicked, convert the result to a T.
dialog.resultConverter = dialogButton =>
if (dialogButton == ButtonType.OK) {
val eventName = eventNameTF.text.value

val maturityDate = KrystalBullUtil.toInstant(
datePicker = datePicker,
hourPicker = hourPicker,
minutePicker = minutePicker,
amOrPmPicker = amOrPmPicker)

val eventName = {
val name = eventNameTF.text.value
if (appendDateCheckBox.selected.value) {
val timeStr = TimeUtil.iso8601ToString(Date.from(maturityDate))
s"$name $timeStr"
} else name
}

val outcomeStrs = outcomeMap.values.toVector.distinct
val outcomes = outcomeStrs.flatMap { keyStr =>
if (keyStr.text.value.nonEmpty) {
Expand Down
Expand Up @@ -5,59 +5,93 @@ import com.krystal.bull.gui.home.InitEventParams
import com.krystal.bull.gui.{GUIUtil, GlobalData, KrystalBullUtil}
import org.bitcoins.core.number._
import org.bitcoins.core.protocol.tlv.DigitDecompositionEventDescriptorV0TLV
import org.bitcoins.core.util.TimeUtil
import scalafx.Includes._
import scalafx.geometry.{Insets, Pos}
import scalafx.scene.control._
import scalafx.scene.layout.{GridPane, HBox}
import scalafx.stage.Window
import scalafx.util.StringConverter

import java.util.Date

object CreateNumericEventDialog {

def showAndWait(parentWindow: Window): Option[InitEventParams] = {
def showAndWait(
parentWindow: Window,
initParamsOpt: Option[InitEventParams]): Option[InitEventParams] = {
val descriptorOpt =
initParamsOpt.map(
_.descriptorTLV.asInstanceOf[DigitDecompositionEventDescriptorV0TLV])

val titleStr = initParamsOpt match {
case Some(value) => s"Clone of ${value.sanitizedEventName}"
case None => "Create New Numeric Event"
}

val dialog = new Dialog[Option[InitEventParams]]() {
initOwner(parentWindow)
title = "Create Numeric Event"
title = titleStr
}

dialog.dialogPane().buttonTypes = Seq(ButtonType.OK, ButtonType.Cancel)
dialog.dialogPane().stylesheets = GlobalData.currentStyleSheets
dialog.resizable = true

val eventNameTF = new TextField()
val datePicker: DatePicker = new DatePicker()
val eventNameTF = new TextField() {
text = initParamsOpt.map(_.sanitizedEventName).getOrElse("")
minWidth = 300
}

val appendDateCheckBox = new CheckBox() {
alignmentInParent = Pos.CenterRight
selected = initParamsOpt.exists(_.hasAppendedDate)
}

val datePicker: DatePicker = new DatePicker() {
minWidth = 300
}

val hourPicker = new ComboBox[Int](1.to(12)) {
value = 12
value = initParamsOpt.map(_.hour).getOrElse(12)
}
val minutePicker = new ComboBox[Int](0.to(59)) {
value = 0
value = initParamsOpt.map(_.minute).getOrElse(0)
converter = new StringConverter[Int] {
override def fromString(string: String): Int = string.toInt

override def toString(t: Int): String = {
if (t < 10) {
s"0$t"
} else t.toString
if (t < 10) s"0$t"
else t.toString
}
}
}

val amOrPmPicker = new ComboBox[String](Vector("AM", "PM")) {
value = "AM"
value = initParamsOpt.map(_.isAM) match {
case Some(true) | None => "AM"
case Some(false) => "PM"
}
}

val maxTF = new TextField()
val maxTF = new TextField() {
text = descriptorOpt.map(_.maxNum.toString()).getOrElse("")
}
GUIUtil.setNumericInput(maxTF)

val isSignedCheckBox = new CheckBox() {
alignmentInParent = Pos.Center
selected = descriptorOpt.exists(_.minNum != 0)
}

val unitTF = new TextField() {
text = descriptorOpt.map(_.unit.normStr).getOrElse("")
}

val unitTF = new TextField()
val precisionTF = new TextField() {
text = "0"
text = descriptorOpt.map(_.precision.toLong.toString).getOrElse("0")
}

GUIUtil.setNumericInput(precisionTF)

dialog.dialogPane().content = new GridPane {
Expand All @@ -69,6 +103,12 @@ object CreateNumericEventDialog {
add(new Label("Event Name"), 0, row)
add(eventNameTF, 1, row)

if (GlobalData.advancedMode) {
row += 1
add(new Label("Append date to name"), 0, row)
add(appendDateCheckBox, 1, row)
}

row += 1
add(new Label("Maturity Date"), 0, row)
add(datePicker, 1, row)
Expand Down Expand Up @@ -110,14 +150,21 @@ object CreateNumericEventDialog {
// When the OK button is clicked, convert the result to a T.
dialog.resultConverter = dialogButton =>
if (dialogButton == ButtonType.OK) {
val eventName = eventNameTF.text.value

val maturityDate = KrystalBullUtil.toInstant(
datePicker = datePicker,
hourPicker = hourPicker,
minutePicker = minutePicker,
amOrPmPicker = amOrPmPicker)

val eventName = {
val name = eventNameTF.text.value
if (appendDateCheckBox.selected.value) {
val timeStr = TimeUtil.iso8601ToString(Date.from(maturityDate))
s"$name $timeStr"
} else name
}

val maxNumber = numberFormatter.parse(maxTF.text.value).longValue()

// log 2 of maxNumber gives us how many base 2 digits are needed
Expand Down
41 changes: 11 additions & 30 deletions src/main/scala/com/krystal/bull/gui/home/HomePane.scala
Expand Up @@ -82,18 +82,25 @@ class HomePane(glassPane: VBox) {
columns ++= Seq(labelCol, announcementCol, maturityDateCol, signatureCol)
margin = Insets(10, 0, 10, 0)

val infoItem: MenuItem = new MenuItem("View Event") {
val viewEventItem: MenuItem = new MenuItem("View Event") {
onAction = _ => {
val event = selectionModel.value.getSelectedItem
model.viewEvent(event)
updateTable()
}
}

val cloneEventItem: MenuItem = new MenuItem("Clone Event") {
onAction = _ => {
val event = selectionModel.value.getSelectedItem
model.cloneEvent(event, () => updateTable())
}
}

columnResizePolicy = TableView.ConstrainedResizePolicy

contextMenu = new ContextMenu() {
items += infoItem
items ++= Vector(viewEventItem, cloneEventItem)
}
}
}
Expand Down Expand Up @@ -202,38 +209,12 @@ class HomePane(glassPane: VBox) {
}

private val createEnumEventButton = new Button("Create Enum Event") {
onAction = _ => {
model.createEnumEvent() match {
case Some(params) =>
oracle
.createNewEvent(params.eventName,
params.maturationTime,
params.descriptorTLV)
.map { _ =>
updateTable()
}
case None =>
()
}
}
onAction = _ => model.createEnumEvent(() => updateTable())
}

private val createDigitDecompEventButton = new Button(
"Create Numeric Event") {
onAction = _ => {
model.createNumericEvent() match {
case Some(params) =>
oracle
.createNewEvent(params.eventName,
params.maturationTime,
params.descriptorTLV)
.map { _ =>
updateTable()
}
case None =>
()
}
}
onAction = _ => model.createNumericEvent(() => updateTable())
}

private val createButtons = new HBox() {
Expand Down

0 comments on commit 3458251

Please sign in to comment.