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