timestamper/griffon-app/views/com/jdblabs/timestamper/gui/TimeStamperMainView.groovy
2013-09-22 15:22:44 -05:00

206 lines
7.4 KiB
Groovy

package com.jdblabs.timestamper.gui
import java.awt.Color
import java.awt.Font
import java.awt.Point
import java.awt.Rectangle
import java.awt.Toolkit
import java.awt.event.KeyEvent
import javax.swing.BoxLayout
import javax.swing.JDialog
import javax.swing.JFileChooser
import javax.swing.SwingConstants
import javax.swing.Timer
import com.jdblabs.timestamper.core.Timeline
import net.miginfocom.swing.MigLayout
/* ========== *
* GUI Events *
* ========== */
taskTextFieldChanged = { evt = null ->
if (evt.keyCode == KeyEvent.VK_ENTER) {
taskTextField.font = taskBoldFont
controller.newTask(taskTextField.text)
}
else if (evt.keyCode == KeyEvent.VK_ESCAPE) {
taskTextField.font = taskBoldFont
taskTextField.text = model.currentMarker.mark
}
else if (!evt.isActionKey())
taskTextField.font = taskThinFont
}
showNotes = { evt = null ->
model.notesDialogMVC.view.dialog.visible = notesVisibleButton.selected
}
showPunchcard = { evt = null ->
model.punchcardDialogMVC.view.dialog.visible = punchcardVisibleButton.selected
}
mousePressed = { evt = null ->
mousePressRelativeToFrame = evt?.point
}
mouseDragged = { evt = null ->
GUIUtil.componentDragged(frame, evt, mousePressRelativeToFrame,
new Rectangle(Toolkit.defaultToolkit.screenSize))
}
/* ============== *
* GUI Definition *
* ============== */
updateTimer = new Timer(1000, action(name: 'GUI Refresh', closure: {
Date currentTime = new Date()
currentTimeLabel.text = Timeline.shortFormat.format(currentTime)
if (model.currentMarker != null) {
long seconds = currentTime.time - model.currentMarker.timestamp.time
seconds /= 1000
long minutes = seconds / 60
seconds = seconds % 60
long hours = minutes / 60
minutes %= 60
long days = hours / 24
hours %= 24
StringBuilder sb = new StringBuilder()
if (days > 0) sb.append(days + "day ")
if (hours > 0) sb.append(hours + "hr ")
if (minutes > 0) sb.append(minutes + "min ")
sb.append(seconds + "sec")
totalTimeLabel.text = sb.toString()
} else totalTimeLabel.text = ""
}))
updateTimer.start()
optionsMenu = popupMenu() {
menuItem(icon: imageIcon('/document-save-16x16.png'), text: 'Save Timeline',
actionPerformed: { model.timelineProperties.save() })
menuItem(icon: imageIcon('/document-save-as-16x16.png'),
text: 'Save a new copy...', actionPerformed: controller.&saveas)
menuItem(icon: imageIcon('/document-open-16x16.png'),
text: 'Load Timeline...', actionPerformed: {
if (fileDialog.showOpenDialog(frame) ==
JFileChooser.APPROVE_OPTION)
controller.load(fileDialog.selectedFile) })
checkBoxMenuItem(text: 'Save on update?',
selected: bind(source: model, sourceProperty: 'timelineProperties',
sourceValue: { model.timelineProperties?.persistOnUpdate }),
actionPerformed: {
model.timelineProperties.persistOnUpdate = it.source.selected })
aboutMenuItem = checkBoxMenuItem(text: 'About...',
actionPerformed: { aboutDialog.visible = aboutMenuItem.selected })
}
fileDialog = fileChooser();
frame = application(title:'TimeStamper',
location:[50,50],
locationByPlatform:true,
minimumSize: [325, 0],
pack:true,
undecorated:true,
iconImage: imageIcon('/appointment-new-32x32.png').image,
iconImages: [imageIcon('/appointment-new-32x32.png').image,
imageIcon('/appointment-new-16x16.png').image],
componentMoved: { evt -> model.absoluteLocation = frame.location }
) {
logger.trace('Building TimeStamperMain GUI')
panel(
border:lineBorder(color:Color.BLACK, thickness:1, parent:true),
layout: new MigLayout('insets 0 5 0 0, fill','', '[]0[]0[]'),
mousePressed: mousePressed,
mouseDragged: mouseDragged
) {
def mainFont = new Font(Font.SANS_SERIF, Font.BOLD, 12)
def timeFont = new Font(Font.SANS_SERIF, Font.BOLD, 14)
label("Current task started at ", font: mainFont)
label(constraints: 'align leading', font: timeFont,
foreground: [0, 102, 102],
text: bind(source: model, sourceProperty: 'currentMarker',
sourceValue: {
model.currentMarker == null ? "00:00:00" :
Timeline.shortFormat.format(model.currentMarker.timestamp)
}))
panel(constraints: 'alignx trailing, aligny top, wrap') {
boxLayout(axis: BoxLayout.X_AXIS)
button(mouseClicked: { evt ->
optionsMenu.show(evt.component, evt.x, evt.y) },
icon: imageIcon('/16-tool-a.png'),
rolloverIcon: imageIcon('/16-tool-a-hover.png'),
border: emptyBorder(0),
contentAreaFilled: false,
hideActionText: true,
toolTipText: 'Options Menu')
button(actionPerformed: controller.&exitGracefully,
icon: imageIcon('/16-em-cross.png'),
rolloverIcon: imageIcon('/16-em-cross-hover.png'),
border: emptyBorder(0),
contentAreaFilled: false,
hideActionText: true,
toolTipText: 'Close Application')
}
taskTextField = textField("Task name",
constraints: "growx, span 2, w 250::",
keyReleased: taskTextFieldChanged,
toolTipText: 'The current task',
text: bind(source: model, sourceProperty: 'currentMarker',
sourceValue: { model.currentMarker?.mark }))
taskThinFont = taskTextField.font
taskBoldFont = taskTextField.font.deriveFont(Font.BOLD)
panel(constraints: 'alignx leading, aligny top, gapright 5px, wrap') {
boxLayout(axis: BoxLayout.X_AXIS)
notesVisibleButton = toggleButton(
actionPerformed: showNotes,
icon: imageIcon('/16-em-pencil.png'),
hideActionText: true,
border: emptyBorder(4),
toolTipText: 'Show/hide task notes.')
punchcardVisibleButton = toggleButton(
actionPerformed: showPunchcard,
icon: imageIcon('/16-file-archive.png'),
hideActionText: true,
border: emptyBorder(4),
toolTipText: 'Show/hide the timeline display.')
}
totalTimeLabel = label("", constraints: 'alignx leading',
font: timeFont, foreground: [0, 153, 0])
currentTimeLabel = label("00:00:00", constraints: 'align trailing',
font: timeFont, foreground: [204, 0, 0])
}
}
aboutDialog = dialog(new JDialog(frame),
visible: false,
locationRelativeTo: null,
pack: true,
undecorated: true,
title: "About TimeStamper v" + app.metadata.'app.version'
) {
panel(layout: new MigLayout('fill'),
border: lineBorder(color: Color.BLACK, thickness: 1)) {
label(font: new Font(Font.SANS_SERIF, Font.PLAIN, 18),
text: "TimeStamper", constraints: 'growx, wrap',
horizontalAlignment: SwingConstants.CENTER)
label(text: "version " + app.metadata.'app.version'
+ " by Jonathan Bernard", constraints: 'growx, wrap',
horizontalAlignment: SwingConstants.CENTER)
textField(text: 'http://www.jdb-labs.com/timestamper',
constraints: 'growx', foreground: [0,0,200], editable: false,
horizontalAlignment: SwingConstants.CENTER)
}
}