//
// Copyright (c) 2011, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 14 Jan 11 Andy Frank Creation
//
using fwt
using gfx
**
** WebDialog extends Dialog to add features specific to Browsers.
**
@NoDoc
@Js
class WebDialog : Dialog
{
** Constructor.
new make(Window? parent) : super(parent)
{
onClose.add |e|
{
r := e.data
if (r == Dialog.ok || r == Dialog.yes)
onCommit.fire(Event { id=EventId.close; widget=e.widget; data=r })
}
}
**
** Convenience to construct a message Widget to display
** a heading message along with optional summary text.
** Summary text will wrap if needed at given width in
** pixels.
**
static Widget msg(Image? icon, Str header, Str? summary := null, Int width := 325)
{
fh := Desktop.sysFont.toBold
fs := Desktop.sysFontSmall
html := "<div style='font:bold ${fh.size}px $fh.name'>$header.toXml</div>"
if (summary != null)
html += "<div style='margin-top:6px; font:${fs.size}px $fs.name'>$summary.toXml</div>"
Widget pane := HtmlPane { it.width=width; it.html=html }
if (icon != null) pane = GridPane
{
hgap = 12
numCols = 2
valignCells = Valign.top
Label { image=icon; font=Font("1pt Arial") },
pane,
}
return pane
}
** Set to false in onValidate to cancel close action.
Bool invalid := false
** Event callback to validate dialog content before commit is called.
EventListeners onValidate := EventListeners() { private set }
** Event callback when dialog is closed with a commit command.
EventListeners onCommit := EventListeners() { private set }
** Insets around body widget.
Insets insetsBody := Insets(16)
** Widget displayed across bottom of dialog opposite command buttons.
Widget? aux := null
** Return command used to toggle 'details' display.
static Command toggleDetails() { ToggleDetailsCommand() }
** Override how content is constructed.
override This buildContent()
{
// build body widget if necessary
body := this.body
if (body == null) body = Label {}
if (body isnot Widget) throw Err("body is not Widget: $body.typeof")
// detach body if already built
((Widget)body).parent?.remove(body)
// build buttons from commands
if (commands == null) commands := Command[,]
buttons := layoutButtons(commands)
// build overall
this.content = EdgePane
{
center = EdgePane
{
center = InsetPane
{
insets = insetsBody
body,
}
bottom = InsetPane
{
insets = Insets(0, 14, 14, 14)
EdgePane { left=aux; right=buttons },
}
}
}
return this
}
** Layout buttons in parent Widget for dialog.
@NoDoc
Widget layoutButtons(Command[] cmds)
{
buttons := GridPane
{
numCols = cmds.size
halignCells = Halign.fill
uniformRows = true
uniformCols = true
hgap = 2
}
cmds.each |c|
{
b := Button.makeCommand(c) { insets=Insets(0,10,0,10) }
if (c == defCommand) setDefButton(b)
buttons.add(ConstraintPane { minw=70; b, })
}
return buttons
}
** Toggle details widget.
internal Void _toggleDetails(Bool visible)
{
if (details == null) return
if (details is Err) details = ((Err)details).traceToStr
if (details is Str) details = ConstraintPane { minw=350; Text
{
multiLine = true
editable = false
prefRows = 20
font = Desktop.sysFontMonospace
text = details.toStr
}, }
if (details isnot Widget)
throw ArgErr("details not Err, Str, or Widget: ${Type.of(details)}")
content->bottom = details
((Widget)details).visible = visible
relayout
}
}
**************************************************************************
** ToggleDetailsCommand
**************************************************************************
@Js
internal class ToggleDetailsCommand : Command
{
new make() : super.makeLocale(Dialog#.pod, "details")
{
mode = CommandMode.toggle
}
override Void invoked(Event? e)
{
dlg := (WebDialog)widgets.first.window
dlg._toggleDetails(selected)
}
}