[1] | 1 | #!/bin/sh |
---|
| 2 | # ---------------------------------------------------------------------- |
---|
| 3 | # USER INTERFACE DRIVER |
---|
| 4 | # |
---|
| 5 | # This driver program loads a tool description from a tool.xml file, |
---|
[11] | 6 | # and produces a user interface automatically to drive an application. |
---|
| 7 | # The user can set up input, click and button to launch a tool, and |
---|
| 8 | # browse through output. |
---|
[1] | 9 | # |
---|
| 10 | # RUN AS FOLLOWS: |
---|
[2080] | 11 | # wish main.tcl ?-tool <toolfile>? |
---|
[1] | 12 | # |
---|
[11] | 13 | # If the <toolfile> is not specified, it defaults to "tool.xml" in |
---|
| 14 | # the current working directory. |
---|
[1] | 15 | # |
---|
| 16 | # ====================================================================== |
---|
| 17 | # AUTHOR: Michael McLennan, Purdue University |
---|
[2080] | 18 | # Copyright (c) 2004-2011 Purdue Research Foundation |
---|
[115] | 19 | # |
---|
| 20 | # See the file "license.terms" for information on usage and |
---|
| 21 | # redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
[1] | 22 | # ====================================================================== |
---|
[365] | 23 | package require Itcl |
---|
[2081] | 24 | package require Img |
---|
[1] | 25 | package require Rappture |
---|
[158] | 26 | package require RapptureGUI |
---|
[1] | 27 | |
---|
[22] | 28 | option add *MainWin.mode desktop startupFile |
---|
[1] | 29 | option add *MainWin.borderWidth 0 startupFile |
---|
[44] | 30 | option add *MainWin.anchor fill startupFile |
---|
[1] | 31 | |
---|
| 32 | # "web site" look |
---|
| 33 | option add *MainWin.bgScript { |
---|
| 34 | rectangle 0 0 200 <h> -outline "" -fill #5880BB |
---|
| 35 | rectangle 200 0 300 <h> -outline "" -fill #425F8B |
---|
| 36 | rectangle 300 0 <w> <h> -outline "" -fill #324565 |
---|
| 37 | } startupFile |
---|
| 38 | |
---|
| 39 | # "clean" look |
---|
| 40 | option add *MainWin.bgScript "" startupFile |
---|
| 41 | option add *MainWin.bgColor white startupFile |
---|
[9] | 42 | option add *Tooltip.background white |
---|
[11] | 43 | option add *Editor.background white |
---|
| 44 | option add *Gauge.textBackground white |
---|
| 45 | option add *TemperatureGauge.textBackground white |
---|
[13] | 46 | option add *Switch.textBackground white |
---|
[23] | 47 | option add *Progress.barColor #ffffcc |
---|
[413] | 48 | option add *Balloon.titleBackground #6666cc |
---|
| 49 | option add *Balloon.titleForeground white |
---|
[676] | 50 | option add *Balloon*Label.font -*-helvetica-medium-r-normal-*-12-* |
---|
| 51 | option add *Balloon*Radiobutton.font -*-helvetica-medium-r-normal-*-12-* |
---|
| 52 | option add *Balloon*Checkbutton.font -*-helvetica-medium-r-normal-*-12-* |
---|
[413] | 53 | option add *ResultSet.controlbarBackground #6666cc |
---|
| 54 | option add *ResultSet.controlbarForeground white |
---|
| 55 | option add *ResultSet.activeControlBackground #ccccff |
---|
| 56 | option add *ResultSet.activeControlForeground black |
---|
| 57 | option add *Radiodial.length 3i |
---|
[464] | 58 | option add *BugReport*banner*foreground white |
---|
| 59 | option add *BugReport*banner*background #a9a9a9 |
---|
| 60 | option add *BugReport*banner*highlightBackground #a9a9a9 |
---|
[676] | 61 | option add *BugReport*banner*font -*-helvetica-bold-r-normal-*-18-* |
---|
[1275] | 62 | option add *hubcntls*Button.padX 0 widgetDefault |
---|
| 63 | option add *hubcntls*Button.padY 0 widgetDefault |
---|
| 64 | option add *hubcntls*Button.relief flat widgetDefault |
---|
| 65 | option add *hubcntls*Button.overRelief raised widgetDefault |
---|
| 66 | option add *hubcntls*Button.borderWidth 1 widgetDefault |
---|
| 67 | option add *hubcntls*Button.font \ |
---|
| 68 | -*-helvetica-medium-r-normal-*-8-* widgetDefault |
---|
[1] | 69 | |
---|
[17] | 70 | switch $tcl_platform(platform) { |
---|
| 71 | unix - windows { |
---|
| 72 | event add <<PopupMenu>> <ButtonPress-3> |
---|
| 73 | } |
---|
| 74 | macintosh { |
---|
| 75 | event add <<PopupMenu>> <Control-ButtonPress-1> |
---|
| 76 | } |
---|
| 77 | } |
---|
| 78 | |
---|
[464] | 79 | # install a better bug handler |
---|
| 80 | Rappture::bugreport::install |
---|
[52] | 81 | # fix the "grab" command to support a stack of grab windows |
---|
| 82 | Rappture::grab::init |
---|
| 83 | |
---|
[1] | 84 | # |
---|
| 85 | # Process command line args to get the names of files to load... |
---|
| 86 | # |
---|
[11] | 87 | Rappture::getopts argv params { |
---|
| 88 | value -tool tool.xml |
---|
[1399] | 89 | list -load "" |
---|
[1159] | 90 | value -nosim 0 |
---|
[1] | 91 | } |
---|
| 92 | |
---|
[1159] | 93 | set loadobjs {} |
---|
| 94 | foreach runfile $params(-load) { |
---|
| 95 | if {![file exists $runfile]} { |
---|
| 96 | puts stderr "can't find run: \"$runfile\"" |
---|
| 97 | exit 1 |
---|
| 98 | } |
---|
| 99 | set status [catch {Rappture::library $runfile} result] |
---|
| 100 | lappend loadobjs $result |
---|
| 101 | } |
---|
| 102 | |
---|
[1] | 103 | # open the XML file containing the tool parameters |
---|
[11] | 104 | if {![file exists $params(-tool)]} { |
---|
[1159] | 105 | # check to see if the user specified any run.xml files to load. |
---|
| 106 | # if so, we can use that as the tool.xml. if we can find where |
---|
| 107 | # the original application was installed using the xml tag |
---|
| 108 | # tool.version.application.directory(top), the user can |
---|
| 109 | # run new simulations, otherwise they can only revisualize the |
---|
| 110 | # run.xml files they are loading. |
---|
| 111 | set pseudotool "" |
---|
[1206] | 112 | if {0 == [llength $loadobjs]} { |
---|
[1159] | 113 | puts stderr "can't find tool \"$params(-tool)\"" |
---|
| 114 | exit 1 |
---|
| 115 | } |
---|
[1206] | 116 | # search the loadfiles for the install location |
---|
| 117 | # we could just use run.xml files as tool.xml, but |
---|
| 118 | # if there are loaders or notes, they will still need |
---|
| 119 | # examples/ and docs/ dirs from the install location |
---|
| 120 | foreach runobj $loadobjs { |
---|
| 121 | set tdir [$runobj get tool.version.application.directory(tool)] |
---|
| 122 | if {[file isdirectory $tdir] && \ |
---|
| 123 | [file exists $tdir/tool.xml]} { |
---|
| 124 | set pseudotool $tdir/tool.xml |
---|
| 125 | break |
---|
[1159] | 126 | } |
---|
| 127 | } |
---|
| 128 | if {![file exists $pseudotool]} { |
---|
| 129 | # we didn't find a tool.xml file, |
---|
| 130 | # use info from a runfile to build gui |
---|
| 131 | # disable simulation, because no tool.xml |
---|
| 132 | set pseudotool [lindex $params(-load) 0] |
---|
| 133 | array set params [list -nosim true] |
---|
| 134 | } |
---|
| 135 | if {![file exists $pseudotool]} { |
---|
| 136 | puts stderr "can't find tool \"$params(-tool)\"" |
---|
| 137 | exit 1 |
---|
| 138 | } |
---|
| 139 | array set params [list -tool $pseudotool] |
---|
[1] | 140 | } |
---|
[1159] | 141 | |
---|
[11] | 142 | set xmlobj [Rappture::library $params(-tool)] |
---|
| 143 | |
---|
| 144 | set installdir [file dirname $params(-tool)] |
---|
| 145 | if {"." == $installdir} { |
---|
| 146 | set installdir [pwd] |
---|
[1] | 147 | } |
---|
| 148 | |
---|
[11] | 149 | set tool [Rappture::Tool ::#auto $xmlobj $installdir] |
---|
[1] | 150 | |
---|
| 151 | # ---------------------------------------------------------------------- |
---|
[728] | 152 | # CHECK JOB FAILURE REPORTING |
---|
| 153 | # |
---|
| 154 | # If this tool might fail when it launches jobs (i.e., Rappture |
---|
| 155 | # can't check some inputs, such as strings), then disable the |
---|
| 156 | # automatic ticket submission for job failures |
---|
| 157 | # ---------------------------------------------------------------------- |
---|
| 158 | set val [$tool xml get tool.reportJobFailures] |
---|
[1547] | 159 | if { "" != $val} { |
---|
[728] | 160 | if {[catch {Rappture::bugreport::shouldReport jobfailures $val} result]} { |
---|
| 161 | puts stderr "WARNING for reportJobFailures: $result" |
---|
| 162 | } |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | # ---------------------------------------------------------------------- |
---|
[413] | 166 | # LOAD RESOURCE SETTINGS |
---|
| 167 | # |
---|
| 168 | # Try to load the $SESSIONDIR/resources file, which contains |
---|
| 169 | # middleware settings, such as the application name and the |
---|
| 170 | # filexfer settings. |
---|
| 171 | # ---------------------------------------------------------------------- |
---|
| 172 | Rappture::resources::load |
---|
| 173 | |
---|
| 174 | # ---------------------------------------------------------------------- |
---|
[50] | 175 | # INITIALIZE THE DESKTOP CONNECTION |
---|
| 176 | # |
---|
| 177 | # If there's a SESSION ID, then this must be running within the |
---|
| 178 | # nanoHUB. Try to initialize the server handling the desktop |
---|
| 179 | # connection. |
---|
| 180 | # ---------------------------------------------------------------------- |
---|
| 181 | Rappture::filexfer::init |
---|
| 182 | |
---|
| 183 | # ---------------------------------------------------------------------- |
---|
[1] | 184 | # MAIN WINDOW |
---|
| 185 | # ---------------------------------------------------------------------- |
---|
| 186 | wm withdraw . |
---|
| 187 | Rappture::MainWin .main -borderwidth 0 |
---|
[11] | 188 | .main configure -title [$tool xml get tool.title] |
---|
| 189 | wm withdraw .main |
---|
[1] | 190 | |
---|
[56] | 191 | # if the FULLSCREEN variable is set, then nanoHUB wants us to go full screen |
---|
| 192 | if {[info exists env(FULLSCREEN)]} { |
---|
| 193 | .main configure -mode web |
---|
| 194 | } |
---|
| 195 | |
---|
[11] | 196 | # |
---|
| 197 | # The main window has a pager that acts as a notebook for the |
---|
| 198 | # various parts. This notebook as at least two pages--an input |
---|
| 199 | # page and an output (analysis) page. If there are <phase>'s |
---|
| 200 | # for input, then there are more pages in the notebook. |
---|
| 201 | # |
---|
[1] | 202 | set win [.main component app] |
---|
[52] | 203 | Rappture::Postern $win.postern |
---|
| 204 | pack $win.postern -side bottom -fill x |
---|
| 205 | |
---|
[11] | 206 | Rappture::Pager $win.pager |
---|
| 207 | pack $win.pager -expand yes -fill both |
---|
[1] | 208 | |
---|
[1275] | 209 | # |
---|
| 210 | # Add a place for about/questions in the breadcrumbs area of this pager. |
---|
| 211 | # |
---|
| 212 | set app [$tool xml get tool.id] |
---|
| 213 | set url [Rappture::Tool::resources -huburl] |
---|
| 214 | if {"" != $url && "" != $app} { |
---|
| 215 | set f [$win.pager component breadcrumbarea] |
---|
| 216 | frame $f.hubcntls |
---|
| 217 | pack $f.hubcntls -side right -padx 4 |
---|
| 218 | label $f.hubcntls.icon -image [Rappture::icon ask] -highlightthickness 0 |
---|
| 219 | pack $f.hubcntls.icon -side left |
---|
| 220 | button $f.hubcntls.about -text "About this tool" \ |
---|
| 221 | -command [list Rappture::filexfer::webpage "$url/tools/$app"] |
---|
| 222 | pack $f.hubcntls.about -side top -anchor w |
---|
| 223 | button $f.hubcntls.questions -text Questions? \ |
---|
| 224 | -command [list Rappture::filexfer::webpage "$url/resources/$app/questions"] |
---|
| 225 | pack $f.hubcntls.questions -side top -anchor w |
---|
| 226 | } |
---|
| 227 | |
---|
| 228 | # |
---|
| 229 | # Load up the components in the various phases of input. |
---|
| 230 | # |
---|
[11] | 231 | set phases [$tool xml children -type phase input] |
---|
| 232 | if {[llength $phases] > 0} { |
---|
| 233 | set plist "" |
---|
| 234 | foreach name $phases { |
---|
| 235 | lappend plist input.$name |
---|
[1] | 236 | } |
---|
[11] | 237 | set phases $plist |
---|
| 238 | } else { |
---|
| 239 | set phases input |
---|
| 240 | } |
---|
[1] | 241 | |
---|
[11] | 242 | foreach comp $phases { |
---|
| 243 | set title [$tool xml get $comp.about.label] |
---|
| 244 | if {$title == ""} { |
---|
| 245 | set title "Input #auto" |
---|
[1] | 246 | } |
---|
[11] | 247 | $win.pager insert end -name $comp -title $title |
---|
[1] | 248 | |
---|
[11] | 249 | # |
---|
| 250 | # Build the page of input controls for this phase. |
---|
| 251 | # |
---|
| 252 | set f [$win.pager page $comp] |
---|
| 253 | Rappture::Page $f.cntls $tool $comp |
---|
| 254 | pack $f.cntls -expand yes -fill both |
---|
[1] | 255 | } |
---|
| 256 | |
---|
[1268] | 257 | # let components (loaders) in the newly created pages settle |
---|
| 258 | update |
---|
| 259 | |
---|
[1] | 260 | # ---------------------------------------------------------------------- |
---|
| 261 | # OUTPUT AREA |
---|
| 262 | # ---------------------------------------------------------------------- |
---|
[1267] | 263 | |
---|
| 264 | # adjust the title of the page here. |
---|
| 265 | # to adjust the button text, look in analyzer.tcl |
---|
[1143] | 266 | set simtxt [$xmlobj get tool.action.label] |
---|
| 267 | if {"" == $simtxt} { |
---|
| 268 | set simtxt "Simulate" |
---|
| 269 | } |
---|
| 270 | $win.pager insert end -name analyzer -title $simtxt |
---|
[11] | 271 | set f [$win.pager page analyzer] |
---|
[942] | 272 | $win.pager page analyzer -command [subst { |
---|
[1206] | 273 | if { !$params(-nosim) } { |
---|
| 274 | $win.pager busy yes |
---|
| 275 | update |
---|
| 276 | $f.analyze simulate -ifneeded |
---|
| 277 | $win.pager busy no |
---|
| 278 | } |
---|
[942] | 279 | }] |
---|
[1] | 280 | |
---|
[1159] | 281 | Rappture::Analyzer $f.analyze $tool -simcontrol auto -notebookpage about |
---|
[11] | 282 | pack $f.analyze -expand yes -fill both |
---|
| 283 | |
---|
[22] | 284 | $tool notify add analyzer * [list $f.analyze reset] |
---|
[11] | 285 | |
---|
[1] | 286 | # ---------------------------------------------------------------------- |
---|
[11] | 287 | # Finalize the arrangement |
---|
[1] | 288 | # ---------------------------------------------------------------------- |
---|
[11] | 289 | if {[llength [$win.pager page]] == 2} { |
---|
| 290 | set style [$xmlobj get tool.layout] |
---|
| 291 | set screenw [winfo screenwidth .] |
---|
[9] | 292 | |
---|
[11] | 293 | update idletasks |
---|
| 294 | set w0 [winfo reqwidth [$win.pager page @0]] |
---|
| 295 | set w1 [winfo reqwidth [$win.pager page @1]] |
---|
[9] | 296 | |
---|
[1547] | 297 | if { $style != "wizard" } { |
---|
| 298 | # If only two windows and they're small enough, put them up |
---|
| 299 | # side-by-side |
---|
| 300 | if {$w0+$w1 < $screenw } { |
---|
| 301 | $win.pager configure -arrangement side-by-side |
---|
| 302 | $f.analyze configure -holdwindow [$win.pager page @0] |
---|
| 303 | } |
---|
[9] | 304 | } |
---|
[1639] | 305 | set type [$tool xml get tool.control] |
---|
| 306 | if {$type == ""} { |
---|
| 307 | set type [$tool xml get tool.control.type] |
---|
| 308 | } |
---|
[1657] | 309 | set arrangement [$win.pager cget -arrangement] |
---|
[1571] | 310 | if { $type == "" } { |
---|
| 311 | if { $arrangement != "side-by-side" } { |
---|
[1639] | 312 | set type auto |
---|
[1571] | 313 | } |
---|
| 314 | } |
---|
[1657] | 315 | if { $arrangement != "side-by-side" && |
---|
| 316 | ($type == "manual" || $type == "auto" || $style == "wizard") } { |
---|
[1547] | 317 | # in "auto" mode, we don't need a simulate button |
---|
| 318 | $f.analyze configure -simcontrol off |
---|
| 319 | } else { |
---|
| 320 | # not in "auto" mode but side-by-side, we always need the button |
---|
| 321 | $f.analyze configure -simcontrol on |
---|
| 322 | } |
---|
[1288] | 323 | } elseif {[llength [$win.pager page]] > 2} { |
---|
| 324 | # We have phases, so we shouldn't allow the "Simulate" button. |
---|
| 325 | # If it pops up, there are two ways to push simulate and duplicate |
---|
| 326 | # links for "About" and "Questions?". |
---|
| 327 | $f.analyze configure -simcontrol off |
---|
[1] | 328 | } |
---|
[1159] | 329 | |
---|
| 330 | # load previous xml runfiles |
---|
| 331 | if {0 != [llength $params(-load)]} { |
---|
| 332 | foreach runobj $loadobjs { |
---|
[1206] | 333 | # this doesn't seem to work with loaders |
---|
| 334 | # loaders seem to get their value after this point |
---|
| 335 | # may need to tell loader elements to update its value |
---|
| 336 | $tool load $runobj |
---|
[1159] | 337 | $f.analyze load $runobj |
---|
| 338 | } |
---|
[1206] | 339 | # don't need simulate button if we cannot simulate |
---|
[1159] | 340 | if {$params(-nosim)} { |
---|
| 341 | $f.analyze configure -simcontrol off |
---|
| 342 | } |
---|
[1206] | 343 | $f.analyze configure -notebookpage analyze |
---|
| 344 | $win.pager current analyzer |
---|
[1159] | 345 | } |
---|
| 346 | |
---|
[11] | 347 | wm deiconify .main |
---|