Changeset 1527
- Timestamp:
- Jun 22, 2009 12:38:49 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gui/scripts/curve.tcl
r1342 r1527 50 50 itcl::body Rappture::Curve::constructor {xmlobj path} { 51 51 if {![Rappture::library isvalid $xmlobj]} { 52 52 error "bad value \"$xmlobj\": should be LibraryObj" 53 53 } 54 54 set _xmlobj $xmlobj … … 67 67 68 68 foreach name [array names _comp2xy] { 69 69 eval blt::vector destroy $_comp2xy($name) 70 70 } 71 71 } … … 81 81 set rlist "" 82 82 foreach name [array names _comp2xy] { 83 84 85 83 if {[string match $pattern $name]} { 84 lappend rlist $name 85 } 86 86 } 87 87 return $rlist … … 97 97 itcl::body Rappture::Curve::mesh {{what -overall}} { 98 98 if {[info exists _comp2xy($what)]} { 99 99 return [lindex $_comp2xy($what) 0] ;# return xv 100 100 } 101 101 error "bad option \"$what\": should be [join [lsort [array names _comp2xy]] {, }]" … … 111 111 itcl::body Rappture::Curve::values {{what -overall}} { 112 112 if {[info exists _comp2xy($what)]} { 113 113 return [lindex $_comp2xy($what) 1] ;# return yv 114 114 } 115 115 error "bad option \"$what\": should be [join [lsort [array names _comp2xy]] {, }]" … … 125 125 set max "" 126 126 switch -- $which { 127 128 129 130 131 132 133 127 x - xlin { set pos 0; set log 0; set axis xaxis } 128 xlog { set pos 0; set log 1; set axis xaxis } 129 y - ylin - v - vlin { set pos 1; set log 0; set axis yaxis } 130 ylog - vlog { set pos 1; set log 1; set axis yaxis } 131 default { 132 error "bad option \"$which\": should be x, xlin, xlog, y, ylin, ylog, v, vlin, vlog" 133 } 134 134 } 135 135 136 136 blt::vector create tmp zero 137 137 foreach comp [array names _comp2xy] { 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 138 set vname [lindex $_comp2xy($comp) $pos] 139 $vname variable vec 140 141 if {$log} { 142 # on a log scale, use abs value and ignore 0's 143 $vname dup tmp 144 $vname dup zero 145 zero expr {tmp == 0} ;# find the 0's 146 tmp expr {abs(tmp)} ;# get the abs value 147 tmp expr {tmp + zero*max(tmp)} ;# replace 0's with abs max 148 set vmin [blt::vector expr min(tmp)] 149 set vmax [blt::vector expr max(tmp)] 150 } else { 151 set vmin $vec(min) 152 set vmax $vec(max) 153 } 154 155 if {"" == $min} { 156 set min $vmin 157 } elseif {$vmin < $min} { 158 set min $vmin 159 } 160 if {"" == $max} { 161 set max $vmax 162 } elseif {$vmax > $max} { 163 set max $vmax 164 } 165 165 } 166 166 blt::vector destroy tmp zero … … 168 168 set val [$_curve get $axis.min] 169 169 if {"" != $val && "" != $min} { 170 171 172 173 170 if {$val > $min} { 171 # tool specified this min -- don't go any lower 172 set min $val 173 } 174 174 } 175 175 176 176 set val [$_curve get $axis.max] 177 177 if {"" != $val && "" != $max} { 178 179 180 181 178 if {$val < $max} { 179 # tool specified this max -- don't go any higher 180 set max $val 181 } 182 182 } 183 183 … … 194 194 itcl::body Rappture::Curve::hints {{keyword ""}} { 195 195 if {![info exists _hints]} { 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 196 foreach {key path} { 197 group about.group 198 label about.label 199 color about.color 200 style about.style 201 type about.type 202 xlabel xaxis.label 203 xdesc xaxis.description 204 xunits xaxis.units 205 xscale xaxis.scale 206 xmin xaxis.min 207 xmax xaxis.max 208 ylabel yaxis.label 209 ydesc yaxis.description 210 yunits yaxis.units 211 yscale yaxis.scale 212 ymin yaxis.min 213 ymax yaxis.max 214 } { 215 set str [$_curve get $path] 216 if {"" != $str} { 217 set _hints($key) $str 218 } 219 } 220 221 if {[info exists _hints(xlabel)] && "" != $_hints(xlabel) 222 && [info exists _hints(xunits)] && "" != $_hints(xunits)} { 223 set _hints(xlabel) "$_hints(xlabel) ($_hints(xunits))" 224 } 225 if {[info exists _hints(ylabel)] && "" != $_hints(ylabel) 226 && [info exists _hints(yunits)] && "" != $_hints(yunits)} { 227 set _hints(ylabel) "$_hints(ylabel) ($_hints(yunits))" 228 } 229 230 if {[info exists _hints(group)] && [info exists _hints(label)]} { 231 # pop-up help for each curve 232 set _hints(tooltip) $_hints(label) 233 } 234 234 } 235 235 236 236 if {$keyword != ""} { 237 238 239 240 237 if {[info exists _hints($keyword)]} { 238 return $_hints($keyword) 239 } 240 return "" 241 241 } 242 242 return [array get _hints] … … 254 254 # discard any existing data 255 255 foreach name [array names _comp2xy] { 256 256 eval blt::vector destroy $_comp2xy($name) 257 257 } 258 258 catch {unset _comp2xy} … … 263 263 # 264 264 foreach cname [$_curve children -type component] { 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 265 set xv "" 266 set yv "" 267 268 set xydata [$_curve get $cname.xy] 269 if {"" != $xydata} { 270 set xv [blt::vector create \#auto] 271 set yv [blt::vector create \#auto] 272 set tmp [blt::vector create \#auto] 273 $tmp set $xydata 274 $tmp split $xv $yv 275 blt::vector destroy $tmp 276 } 277 278 if {$xv != "" && $yv != ""} { 279 set _comp2xy($cname) [list $xv $yv] 280 incr _counter 281 } 282 282 } 283 283 # Creates lists of x and y marker data. … … 285 285 set _ymarkers {} 286 286 foreach cname [$_curve children -type "marker" xaxis] { 287 288 289 290 291 287 set at [$_curve get "xaxis.$cname.at"] 288 set label [$_curve get "xaxis.$cname.label"] 289 set styles [$_curve get "xaxis.$cname.style"] 290 set data [list $at $label $styles] 291 lappend _xmarkers $data 292 292 } 293 293 foreach cname [$_curve children -type "marker" yaxis] { 294 295 296 297 298 294 set at [$_curve get "yaxis.$cname.at"] 295 set label [$_curve get "yaxis.$cname.label"] 296 set styles [$_curve get "yaxis.$cname.style"] 297 set data [list $at $label $styles] 298 lappend _xmarkers $data 299 299 } 300 300 } -
trunk/gui/scripts/numberentry.tcl
r1342 r1527 43 43 itcl::body Rappture::NumberEntry::constructor {owner path args} { 44 44 if {[catch {$owner isa Rappture::ControlOwner} valid] != 0 || !$valid} { 45 45 error "bad object \"$owner\": should be Rappture::ControlOwner" 46 46 } 47 47 set _owner $owner … … 53 53 set presets "" 54 54 foreach pre [$_owner xml children -type preset $path] { 55 56 57 55 lappend presets \ 56 [$_owner xml get $path.$pre.value] \ 57 [$_owner xml get $path.$pre.label] 58 58 } 59 59 … … 61 61 set units [$_owner xml get $path.units] 62 62 if {$units != ""} { 63 64 65 66 63 set desc [Rappture::Units::description $units] 64 if {[string match temperature* $desc]} { 65 set class Rappture::TemperatureGauge 66 } 67 67 } 68 68 … … 72 72 # 73 73 itk_component add gauge { 74 74 $class $itk_interior.gauge -units $units -presets $presets 75 75 } 76 76 pack $itk_component(gauge) -expand yes -fill both … … 84 84 85 85 if {$class == "Rappture::Gauge" && "" != $min && "" != $max} { 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 86 set color [$_owner xml get $path.about.color] 87 if {$color == ""} { 88 # deprecated. Color should be in "about" 89 set color [$_owner xml get $path.color] 90 } 91 if {$color != ""} { 92 if {$units != ""} { 93 set min [Rappture::Units::convert $min -to $units -units off] 94 set max [Rappture::Units::convert $max -to $units -units off] 95 } 96 # For compatibility. If only one color use white for min 97 if {[llength $color] == 1} { 98 set color [list $min white $max $color] 99 } 100 $itk_component(gauge) configure \ 101 -spectrum [Rappture::Spectrum ::#auto $color -units $units] 102 } 103 103 } 104 104 … … 106 106 set str [$_owner xml get $path.about.icon] 107 107 if {$str != ""} { 108 108 $itk_component(gauge) configure -image [image create photo -data $str] 109 109 } 110 110 … … 131 131 set i [lsearch -exact $args -check] 132 132 if {$i >= 0} { 133 134 133 set onlycheck 1 134 set args [lreplace $args $i $i] 135 135 } 136 136 137 137 if {[llength $args] == 1} { 138 139 140 141 142 143 144 138 if {$onlycheck} { 139 # someday we may add validation... 140 return 141 } 142 set newval [lindex $args 0] 143 $itk_component(gauge) value $newval 144 return $newval 145 145 146 146 } elseif {[llength $args] != 0} { 147 147 error "wrong # args: should be \"value ?-check? ?newval?\"" 148 148 } 149 149 … … 163 163 set label [$_owner xml get $_path.about.label] 164 164 if {"" == $label} { 165 165 set label "Number" 166 166 } 167 167 return $label … … 184 184 185 185 if {$units != "" || $min != "" || $max != ""} { 186 187 188 189 190 191 192 193 194 195 196 197 198 199 186 append str "\n\nEnter a number" 187 188 if {$min != "" && $max != ""} { 189 append str " between $min and $max" 190 } elseif {$min != ""} { 191 append str " greater than $min" 192 } elseif {$max != ""} { 193 append str " less than $max" 194 } 195 196 if {$units != ""} { 197 set desc [Rappture::Units::description $units] 198 append str " with units of $desc" 199 } 200 200 } 201 201 return [string trim $str] … … 218 218 set valid {normal disabled} 219 219 if {[lsearch -exact $valid $itk_option(-state)] < 0} { 220 220 error "bad value \"$itk_option(-state)\": should be [join $valid {, }]" 221 221 } 222 222 $itk_component(gauge) configure -state $itk_option(-state) -
trunk/gui/scripts/xyresult.tcl
r1420 r1527 117 117 private variable initialized_ 0 118 118 } 119 119 120 120 itk::usual XyResult { 121 121 keep -background -foreground -cursor -font … … 135 135 136 136 array set _downloadPopup { 137 137 format csv 138 138 } 139 139 … … 148 148 149 149 itk_component add reset { 150 150 button $f.reset -borderwidth 1 -padx 1 -pady 1 \ 151 151 -highlightthickness 0 \ 152 153 152 -image [Rappture::icon reset-view] \ 153 -command [itcl::code $this _zoom reset] 154 154 } { 155 156 155 usual 156 ignore -borderwidth -highlightthickness 157 157 } 158 158 pack $itk_component(reset) -padx 4 -pady 2 -anchor e 159 159 Rappture::Tooltip::for $itk_component(reset) \ 160 160 "Reset the view to the default zoom level" 161 161 162 162 set f [$itk_component(main) component frame] 163 163 itk_component add plot { 164 165 166 164 blt::graph $f.plot \ 165 -highlightthickness 0 -plotpadx 0 -plotpady 0 \ 166 -rightmargin 10 167 167 } { 168 168 keep -background -foreground -cursor -font 169 169 } 170 170 pack $itk_component(plot) -expand yes -fill both 171 171 172 172 $itk_component(plot) pen configure activeLine \ 173 174 173 -symbol square -pixels 3 -linewidth 2 \ 174 -outline black -fill red -color black 175 175 176 176 # … … 178 178 # 179 179 bind $itk_component(plot) <Motion> \ 180 180 [itcl::code $this _hilite at %x %y] 181 181 bind $itk_component(plot) <Leave> \ 182 182 [itcl::code $this _hilite off %x %y] 183 183 184 184 # … … 206 206 Rappture::Combobox $inner.format -width 15 -editable no 207 207 $inner.format choices insert end \ 208 209 210 211 212 213 214 215 216 217 208 "%.3g" "Auto" \ 209 "%.0f" "X" \ 210 "%.1f" "X.X" \ 211 "%.2f" "X.XX" \ 212 "%.3f" "X.XXX" \ 213 "%.6f" "X.XXXXXX" \ 214 "%.1e" "X.Xe+XX" \ 215 "%.2e" "X.XXe+XX" \ 216 "%.3e" "X.XXXe+XX" \ 217 "%.6e" "X.XXXXXXe+XX" 218 218 grid $inner.formatl -row 4 -column 0 -sticky e 219 219 grid $inner.format -row 4 -column 1 -sticky ew -pady 4 … … 222 222 frame $inner.scales 223 223 radiobutton $inner.scales.linear -text "Linear" \ 224 224 -variable [itcl::scope _axisPopup(scale)] -value "linear" 225 225 pack $inner.scales.linear -side left 226 226 radiobutton $inner.scales.log -text "Logarithmic" \ 227 227 -variable [itcl::scope _axisPopup(scale)] -value "log" 228 228 pack $inner.scales.log -side left 229 229 grid $inner.scalel -row 5 -column 0 -sticky e … … 231 231 232 232 foreach axis {x y} { 233 233 set _axisPopup(format-$axis) "%.3g" 234 234 } 235 235 _axis scale x linear … … 247 247 248 248 itk_component add legend { 249 249 Rappture::XyLegend $inner.legend $itk_component(plot) 250 250 } 251 251 pack $itk_component(legend) -expand yes -fill both 252 252 253 253 after idle [subst { 254 255 254 update idletasks 255 $itk_component(legend) reset 256 256 }] 257 257 … … 278 278 itcl::body Rappture::XyResult::add {curve {settings ""}} { 279 279 array set params { 280 281 282 283 284 285 286 287 280 -color auto 281 -brightness 0 282 -width 1 283 -type "line" 284 -raise 0 285 -linestyle solid 286 -description "" 287 -param "" 288 288 } 289 289 foreach {opt val} $settings { 290 291 292 293 290 if {![info exists params($opt)]} { 291 error "bad setting \"$opt\": should be [join [lsort [array names params]] {, }]" 292 } 293 set params($opt) $val 294 294 } 295 295 296 296 # if type is set to "scatter", then override the width 297 297 if {"scatter" == $params(-type)} { 298 298 set params(-width) 0 299 299 } 300 300 301 301 # if the color is "auto", then select a color from -autocolors 302 302 if {$params(-color) == "auto" || $params(-color) == "autoreset"} { 303 304 305 306 307 308 309 310 311 312 313 303 if {$params(-color) == "autoreset"} { 304 set _autoColorI 0 305 } 306 set color [lindex $itk_option(-autocolors) $_autoColorI] 307 if {"" == $color} { set color black } 308 set params(-color) $color 309 310 # set up for next auto color 311 if {[incr _autoColorI] >= [llength $itk_option(-autocolors)]} { 312 set _autoColorI 0 313 } 314 314 } 315 315 316 316 # convert -linestyle to BLT -dashes 317 317 switch -- $params(-linestyle) { 318 319 320 318 dashed { set params(-linestyle) {4 4} } 319 dotted { set params(-linestyle) {2 4} } 320 default { set params(-linestyle) {} } 321 321 } 322 322 323 323 # if -brightness is set, then update the color 324 324 if {$params(-brightness) != 0} { 325 326 327 328 329 330 331 332 333 334 335 336 325 set params(-color) [Rappture::color::brightness \ 326 $params(-color) $params(-brightness)] 327 328 set bg [$itk_component(plot) cget -plotbackground] 329 foreach {h s v} [Rappture::color::RGBtoHSV $bg] break 330 if {$v > 0.5} { 331 set params(-color) [Rappture::color::brightness_max \ 332 $params(-color) 0.8] 333 } else { 334 set params(-color) [Rappture::color::brightness_min \ 335 $params(-color) 0.2] 336 } 337 337 } 338 338 339 339 set pos [lsearch -exact $curve $_clist] 340 340 if {$pos < 0} { 341 342 343 344 345 346 347 348 341 lappend _clist $curve 342 set _curve2color($curve) $params(-color) 343 set _curve2width($curve) $params(-width) 344 set _curve2dashes($curve) $params(-linestyle) 345 set _curve2raise($curve) $params(-raise) 346 set _curve2desc($curve) $params(-description) 347 348 $_dispatcher event -idle !rebuild 349 349 } 350 350 } … … 360 360 set clist $_clist 361 361 foreach obj $clist { 362 363 364 365 366 367 368 362 if {[info exists _curve2raise($obj)] && $_curve2raise($obj)} { 363 set i [lsearch -exact $clist $obj] 364 if {$i >= 0} { 365 set clist [lreplace $clist $i $i] 366 lappend clist $obj 367 } 368 } 369 369 } 370 370 return $clist … … 379 379 itcl::body Rappture::XyResult::delete {args} { 380 380 if {[llength $args] == 0} { 381 381 set args $_clist 382 382 } 383 383 … … 385 385 set changed 0 386 386 foreach curve $args { 387 388 389 390 391 392 393 394 395 396 397 398 399 400 387 set pos [lsearch -exact $_clist $curve] 388 if {$pos >= 0} { 389 set _clist [lreplace $_clist $pos $pos] 390 catch {unset _curve2color($curve)} 391 catch {unset _curve2width($curve)} 392 catch {unset _curve2dashes($curve)} 393 catch {unset _curve2raise($curve)} 394 foreach elem [array names _elem2curve] { 395 if {$_elem2curve($elem) == $curve} { 396 unset _elem2curve($elem) 397 } 398 } 399 set changed 1 400 } 401 401 } 402 402 403 403 # If anything changed, then rebuild the plot 404 404 if {$changed} { 405 405 $_dispatcher event -idle !rebuild 406 406 } 407 407 408 408 # Nothing left? then start over with auto colors 409 409 if {[llength $_clist] == 0} { 410 410 set _autoColorI 0 411 411 } 412 412 } … … 425 425 lappend allx x ;# fix main x-axis too 426 426 foreach axis $allx { 427 427 _axis scale $axis linear 428 428 } 429 429 … … 431 431 lappend ally y ;# fix main y-axis too 432 432 foreach axis $ally { 433 433 _axis scale $axis linear 434 434 } 435 435 436 436 catch {unset _limits} 437 437 foreach xydata $args { 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 438 # find the axes for this curve (e.g., {x y2}) 439 foreach {map(x) map(y)} [_getAxes $xydata] break 440 441 foreach axis {x y} { 442 # get defaults for both linear and log scales 443 foreach type {lin log} { 444 # store results -- ex: _limits(x2log-min) 445 set id $map($axis)$type 446 foreach {min max} [$xydata limits $axis$type] break 447 if {"" != $min && "" != $max} { 448 if {![info exists _limits($id-min)]} { 449 set _limits($id-min) $min 450 set _limits($id-max) $max 451 } else { 452 if {$min < $_limits($id-min)} { 453 set _limits($id-min) $min 454 } 455 if {$max > $_limits($id-max)} { 456 set _limits($id-max) $max 457 } 458 } 459 } 460 } 461 462 if {[$xydata hints ${axis}scale] == "log"} { 463 _axis scale $map($axis) log 464 } 465 } 466 466 } 467 467 _resetLimits … … 480 480 itcl::body Rappture::XyResult::download {option args} { 481 481 switch $option { 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 482 coming { 483 # nothing to do 484 } 485 controls { 486 set popup .xyresultdownload 487 if {![winfo exists .xyresultdownload]} { 488 # if we haven't created the popup yet, do it now 489 Rappture::Balloon $popup -title "[Rappture::filexfer::label downloadWord] as..." 490 set inner [$popup component inner] 491 label $inner.summary -text "" -anchor w 492 pack $inner.summary -side top 493 radiobutton $inner.csv -text "Data as Comma-Separated Values" \ 494 -variable Rappture::XyResult::_downloadPopup(format) \ 495 -value csv 496 pack $inner.csv -anchor w 497 radiobutton $inner.pdf -text "Image as PDF/PostScript" \ 498 -variable Rappture::XyResult::_downloadPopup(format) \ 499 -value pdf 500 pack $inner.pdf -anchor w 501 radiobutton $inner.jpg -text "Image (draft)" \ 502 -variable Rappture::XyResult::_downloadPopup(format) \ 503 -value jpg 504 pack $inner.jpg -anchor w 505 button $inner.go -text [Rappture::filexfer::label download] \ 506 -command [lindex $args 0] 507 pack $inner.go -pady 4 508 } else { 509 set inner [$popup component inner] 510 } 511 set num [llength [get]] 512 set num [expr {($num == 1) ? "1 result" : "$num results"}] 513 $inner.summary configure -text "[Rappture::filexfer::label downloadWord] $num in the following format:" 514 update idletasks ;# fix initial sizes 515 return $popup 516 } 517 now { 518 set popup .xyresultdownload 519 if {[winfo exists .xyresultdownload]} { 520 $popup deactivate 521 } 522 switch -- $_downloadPopup(format) { 523 csv { 524 # reverse the objects so the selected data appears on top 525 set dlist "" 526 foreach dataobj [get] { 527 set dlist [linsert $dlist 0 $dataobj] 528 } 529 530 # generate the comma-separated value data for these objects 531 set csvdata "" 532 foreach dataobj $dlist { 533 append csvdata "[string repeat - 60]\n" 534 append csvdata " [$dataobj hints label]\n" 535 if {[info exists _curve2desc($dataobj)] 536 && [llength [split $_curve2desc($dataobj) \n]] > 1} { 537 set indent "for:" 538 foreach line [split $_curve2desc($dataobj) \n] { 539 append csvdata " $indent $line\n" 540 set indent " " 541 } 542 } 543 append csvdata "[string repeat - 60]\n" 544 545 append csvdata "[$dataobj hints xlabel], [$dataobj hints ylabel]\n" 546 set first 1 547 foreach comp [$dataobj components] { 548 if {!$first} { 549 # blank line between components 550 append csvdata "\n" 551 } 552 set xv [$dataobj mesh $comp] 553 set yv [$dataobj values $comp] 554 foreach x [$xv range 0 end] y [$yv range 0 end] { 555 append csvdata [format "%20.15g, %20.15g\n" $x $y] 556 } 557 set first 0 558 } 559 append csvdata "\n" 560 } 561 return [list .txt $csvdata] 562 } 563 pdf { 564 set psdata [$itk_component(plot) postscript output \ 565 -decorations no -maxpect 1] 566 567 set cmds { 568 set fout "xy[pid].pdf" 569 exec ps2pdf - $fout << $psdata 570 571 set fid [open $fout r] 572 fconfigure $fid -translation binary -encoding binary 573 set pdfdata [read $fid] 574 close $fid 575 576 file delete -force $fout 577 } 578 if {[catch $cmds result] == 0} { 579 return [list .pdf $pdfdata] 580 } 581 return [list .ps $psdata] 582 } 583 jpg { 584 set img [image create photo] 585 $itk_component(plot) snap $img 586 set bytes [$img data -format "jpeg -quality 100"] 587 set bytes [Rappture::encoding::decode -as b64 $bytes] 588 image delete $img 589 return [list .jpg $bytes] 590 } 591 png { 592 set img [image create photo] 593 $itk_component(plot) snap $img 594 set bytes [$img data -format "png"] 595 set bytes [Rappture::encoding::decode -as b64 $bytes] 596 image delete $img 597 return [list .png $bytes] 598 } 599 } 600 } 601 default { 602 error "bad option \"$option\": should be coming, controls, now" 603 } 604 604 } 605 605 } … … 618 618 eval $g element delete [$g element names] 619 619 foreach axis [$g axis names] { 620 620 $g axis configure $axis -hide yes -checklimits no 621 621 } 622 622 # Presumably you want at least an X-axis and Y-axis displayed. … … 634 634 set anum(y) 0 635 635 foreach xydata [get] { 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 636 foreach ax {x y} { 637 set label [$xydata hints ${ax}label] 638 if {"" != $label} { 639 if {![info exists _label2axis($ax-$label)]} { 640 switch [incr anum($ax)] { 641 1 { set axis $ax } 642 2 { set axis ${ax}2 } 643 default { 644 set axis $ax$anum($ax) 645 catch {$g axis create $axis} 646 } 647 } 648 $g axis configure $axis -title $label -hide no \ 649 -checklimits no 650 set _label2axis($ax-$label) $axis 651 652 # if this axis has a description, add it as a tooltip 653 set desc [string trim [$xydata hints ${ax}desc]] 654 Rappture::Tooltip::text $g-$axis $desc 655 } 656 } 657 } 658 658 } 659 659 … … 664 664 set all "" 665 665 foreach ax {x y} { 666 667 668 669 670 671 672 673 674 675 676 666 lappend all $ax 667 668 set extra "" 669 for {set i 2} {$i <= $anum($ax)} {incr i} { 670 lappend extra ${ax}$i 671 } 672 eval lappend all $extra 673 $g ${ax}2axis use $extra 674 if {$ax == "y"} { 675 $g configure -rightmargin [expr {($extra == "") ? 10 : 0}] 676 } 677 677 } 678 678 679 679 foreach axis $all { 680 681 682 683 684 685 686 687 688 689 690 691 692 693 680 set _axisPopup(format-$axis) "%.3g" 681 682 $g axis bind $axis <Enter> \ 683 [itcl::code $this _axis hilite $axis on] 684 $g axis bind $axis <Leave> \ 685 [itcl::code $this _axis hilite $axis off] 686 $g axis bind $axis <ButtonPress> \ 687 [itcl::code $this _axis click $axis %x %y] 688 $g axis bind $axis <B1-Motion> \ 689 [itcl::code $this _axis drag $axis %x %y] 690 $g axis bind $axis <ButtonRelease> \ 691 [itcl::code $this _axis release $axis %x %y] 692 $g axis bind $axis <KeyPress> \ 693 [list ::Rappture::Tooltip::tooltip cancel] 694 694 } 695 695 … … 699 699 set count 0 700 700 foreach xydata $_clist { 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 701 set label [$xydata hints label] 702 foreach {mapx mapy} [_getAxes $xydata] break 703 704 foreach comp [$xydata components] { 705 set xv [$xydata mesh $comp] 706 set yv [$xydata values $comp] 707 708 if {[info exists _curve2color($xydata)]} { 709 set color $_curve2color($xydata) 710 } else { 711 set color [$xydata hints color] 712 if {"" == $color} { 713 set color black 714 } 715 } 716 717 if {[info exists _curve2width($xydata)]} { 718 set lwidth $_curve2width($xydata) 719 } else { 720 set lwidth 2 721 } 722 723 if {[info exists _curve2dashes($xydata)]} { 724 set dashes $_curve2dashes($xydata) 725 } else { 726 set dashes "" 727 } 728 729 if {([$xv length] <= 1) || ($lwidth == 0)} { 730 set sym square 731 set pixels 2 732 } else { 733 set sym "" 734 set pixels 6 735 } 736 737 set elem "elem[incr count]" 738 set _elem2curve($elem) $xydata 739 740 $g element create $elem -x $xv -y $yv \ 741 -symbol $sym -pixels $pixels -linewidth $lwidth -label $label \ 742 -color $color -dashes $dashes \ 743 -mapx $mapx -mapy $mapy 744 } 745 745 } 746 746 747 747 foreach xydata $_clist { 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 748 set xmin -Inf 749 set ymin -Inf 750 set xmax Inf 751 set ymax Inf 752 # 753 # Create text/line markers for each *axis.marker specified. 754 # 755 foreach m [$xydata xmarkers] { 756 foreach {at label style} $m break 757 set id [$g marker create line -coords [list $at $ymin $at $ymax]] 758 $g marker bind $id <Enter> \ 759 [itcl::code $this _enterMarker $g x-$label $at $ymin $at] 760 $g marker bind $id <Leave> \ 761 [itcl::code $this _leaveMarker $g x-$label] 762 set options [_getLineMarkerOptions $style] 763 if { $options != "" } { 764 eval $g marker configure $id $options 765 } 766 if { $label != "" } { 767 set id [$g marker create text -anchor nw \ 768 -text $label -coords [list $at $ymax]] 769 set options [_getTextMarkerOptions $style] 770 if { $options != "" } { 771 eval $g marker configure $id $options 772 } 773 } 774 } 775 foreach m [$xydata ymarkers] { 776 foreach {at label style} $m break 777 set id [$g marker create line -coords [list $xmin $at $xmax $at]] 778 $g marker bind $id <Enter> \ 779 [itcl::code $this _enterMarker $g y-$label $at $xmin $at] 780 $g marker bind $id <Leave> \ 781 [itcl::code $this _leaveMarker $g y-$label] 782 set options [_getLineMarkerOptions $style] 783 if { $options != "" } { 784 eval $g marker configure $id $options 785 } 786 if { $label != "" } { 787 set id [$g marker create text -anchor se \ 788 -text $label -coords [list $xmax $at]] 789 set options [_getTextMarkerOptions $style] 790 if { $options != "" } { 791 eval $g marker configure $id $options 792 } 793 } 794 } 795 795 } 796 796 $itk_component(legend) reset … … 814 814 # 815 815 foreach axis [$g axis names] { 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 816 if {[info exists _limits(${axis}lin-min)]} { 817 set log [$g axis cget $axis -logscale] 818 if {$log} { 819 set min $_limits(${axis}log-min) 820 if {$min == 0} { set min 1 } 821 set max $_limits(${axis}log-max) 822 if {$max == 0} { set max 1 } 823 824 if {$min == $max} { 825 set logmin [expr {floor(log10(abs(0.9*$min)))}] 826 set logmax [expr {ceil(log10(abs(1.1*$max)))}] 827 } else { 828 set logmin [expr {floor(log10(abs($min)))}] 829 set logmax [expr {ceil(log10(abs($max)))}] 830 if {[string match y* $axis]} { 831 # add a little padding 832 set delta [expr {$logmax-$logmin}] 833 if {$delta == 0} { set delta 1 } 834 set logmin [expr {$logmin-0.05*$delta}] 835 set logmax [expr {$logmax+0.05*$delta}] 836 } 837 } 838 if {$logmin < -300} { 839 set min 1e-300 840 } elseif {$logmin > 300} { 841 set min 1e+300 842 } else { 843 set min [expr {pow(10.0,$logmin)}] 844 } 845 846 if {$logmax < -300} { 847 set max 1e-300 848 } elseif {$logmax > 300} { 849 set max 1e+300 850 } else { 851 set max [expr {pow(10.0,$logmax)}] 852 } 853 } else { 854 set min $_limits(${axis}lin-min) 855 set max $_limits(${axis}lin-max) 856 857 if {[string match y* $axis]} { 858 # add a little padding 859 set delta [expr {$max-$min}] 860 set min [expr {$min-0.05*$delta}] 861 set max [expr {$max+0.05*$delta}] 862 } 863 } 864 if {$min < $max} { 865 $g axis configure $axis -min $min -max $max 866 } else { 867 $g axis configure $axis -min "" -max "" 868 } 869 } else { 870 $g axis configure $axis -min "" -max "" 871 } 872 872 } 873 873 } … … 881 881 itcl::body Rappture::XyResult::_zoom {option args} { 882 882 switch -- $option { 883 884 885 883 reset { 884 _resetLimits 885 } 886 886 } 887 887 } … … 901 901 # middle of a zoom selection. 902 902 if {[info exists ::zoomInfo($g,corner)] && $::zoomInfo($g,corner) == "B" } { 903 903 return; 904 904 } 905 905 set tip "" 906 906 if {$state == "at"} { 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 907 if {[$g element closest $x $y info -interpolate yes]} { 908 # for dealing with xy line plots 909 set elem $info(name) 910 911 # Some elements are generated dynamically and therefore will 912 # not have a curve object associated with them. 913 set mapx [$g element cget $elem -mapx] 914 set mapy [$g element cget $elem -mapy] 915 if {[info exists _elem2curve($elem)]} { 916 foreach {mapx mapy} [_getAxes $_elem2curve($elem)] break 917 } 918 919 # search again for an exact point -- this time don't interpolate 920 set tip "" 921 array unset info 922 if {[$g element closest $x $y info -interpolate no] 923 && $info(name) == $elem} { 924 925 set x [$g axis transform $mapx $info(x)] 926 set y [$g axis transform $mapy $info(y)] 927 928 if {[info exists _elem2curve($elem)]} { 929 set curve $_elem2curve($elem) 930 set yunits [$curve hints yunits] 931 set xunits [$curve hints xunits] 932 } else { 933 set xunits "" 934 set yunits "" 935 } 936 set tip [$g element cget $elem -label] 937 set yval [_axis format y dummy $info(y)] 938 append tip "\n$yval$yunits" 939 set xval [_axis format x dummy $info(x)] 940 append tip " @ $xval$xunits" 941 set tip [string trim $tip] 942 } 943 set state 1 944 } elseif {[$g element closest $x $y info -interpolate no]} { 945 # for dealing with xy scatter plot 946 set elem $info(name) 947 948 # Some elements are generated dynamically and therefore will 949 # not have a curve object associated with them. 950 set mapx [$g element cget $elem -mapx] 951 set mapy [$g element cget $elem -mapy] 952 if {[info exists _elem2curve($elem)]} { 953 foreach {mapx mapy} [_getAxes $_elem2curve($elem)] break 954 } 955 956 set tip "" 957 set x [$g axis transform $mapx $info(x)] 958 set y [$g axis transform $mapy $info(y)] 959 960 if {[info exists _elem2curve($elem)]} { 961 set curve $_elem2curve($elem) 962 set yunits [$curve hints yunits] 963 set xunits [$curve hints xunits] 964 } else { 965 set xunits "" 966 set yunits "" 967 } 968 set tip [$g element cget $elem -label] 969 set yval [_axis format y dummy $info(y)] 970 append tip "\n$yval$yunits" 971 set xval [_axis format x dummy $info(x)] 972 append tip " @ $xval$xunits" 973 set tip [string trim $tip] 974 set state 1 975 } else { 976 set state 0 977 } 978 978 } 979 979 980 980 if {$state} { 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 981 # 982 # Highlight ON: 983 # - activate trace 984 # - multiple axes? dim other axes 985 # - pop up tooltip about data 986 # 987 if { [$g element exists $_hilite(elem)] && $_hilite(elem) != $elem } { 988 $g element deactivate $_hilite(elem) 989 $g crosshairs configure -hide yes 990 Rappture::Tooltip::tooltip cancel 991 } 992 $g element activate $elem 993 set _hilite(elem) $elem 994 995 set mapx [$g element cget $elem -mapx] 996 set mapy [$g element cget $elem -mapy] 997 if {[info exists _elem2curve($elem)]} { 998 foreach {mapx mapy} [_getAxes $_elem2curve($elem)] break 999 } 1000 set allx [$g x2axis use] 1001 if {[llength $allx] > 0} { 1002 lappend allx x ;# fix main x-axis too 1003 foreach axis $allx { 1004 if {$axis == $mapx} { 1005 $g axis configure $axis -color $itk_option(-foreground) \ 1006 -titlecolor $itk_option(-foreground) 1007 } else { 1008 $g axis configure $axis -color $itk_option(-dimcolor) \ 1009 -titlecolor $itk_option(-dimcolor) 1010 } 1011 } 1012 } 1013 set ally [$g y2axis use] 1014 if {[llength $ally] > 0} { 1015 lappend ally y ;# fix main y-axis too 1016 foreach axis $ally { 1017 if {$axis == $mapy} { 1018 $g axis configure $axis -color $itk_option(-foreground) \ 1019 -titlecolor $itk_option(-foreground) 1020 } else { 1021 $g axis configure $axis -color $itk_option(-dimcolor) \ 1022 -titlecolor $itk_option(-dimcolor) 1023 } 1024 } 1025 } 1026 1027 if {"" != $tip} { 1028 $g crosshairs configure -hide no -position @$x,$y 1029 1030 if {$x > 0.5*[winfo width $g]} { 1031 if {$x < 4} { 1032 set tipx "-0" 1033 } else { 1034 set tipx "-[expr {$x-4}]" ;# move tooltip to the left 1035 } 1036 } else { 1037 if {$x < -4} { 1038 set tipx "+0" 1039 } else { 1040 set tipx "+[expr {$x+4}]" ;# move tooltip to the right 1041 } 1042 } 1043 if {$y > 0.5*[winfo height $g]} { 1044 if {$y < 4} { 1045 set tipy "-0" 1046 } else { 1047 set tipy "-[expr {$y-4}]" ;# move tooltip to the top 1048 } 1049 } else { 1050 if {$y < -4} { 1051 set tipy "+0" 1052 } else { 1053 set tipy "+[expr {$y+4}]" ;# move tooltip to the bottom 1054 } 1055 } 1056 Rappture::Tooltip::text $g $tip 1057 Rappture::Tooltip::tooltip show $g $tipx,$tipy 1058 } 1059 1059 } else { 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1060 # 1061 # Highlight OFF: 1062 # - deactivate (color back to normal) 1063 # - put all axes back to normal color 1064 # - take down tooltip 1065 # 1066 if { [$g element exists $_hilite(elem)] } { 1067 $g element deactivate $_hilite(elem) 1068 } 1069 set allx [$g x2axis use] 1070 if {[llength $allx] > 0} { 1071 lappend allx x ;# fix main x-axis too 1072 foreach axis $allx { 1073 $g axis configure $axis -color $itk_option(-foreground) \ 1074 -titlecolor $itk_option(-foreground) 1075 } 1076 } 1077 1078 set ally [$g y2axis use] 1079 if {[llength $ally] > 0} { 1080 lappend ally y ;# fix main y-axis too 1081 foreach axis $ally { 1082 $g axis configure $axis -color $itk_option(-foreground) \ 1083 -titlecolor $itk_option(-foreground) 1084 } 1085 } 1086 1087 $g crosshairs configure -hide yes 1088 1089 # only cancel in plotting area or we'll mess up axes 1090 if {[$g inside $x $y]} { 1091 Rappture::Tooltip::tooltip cancel 1092 } 1093 1094 # There is no currently highlighted element 1095 set _hilite(elem) "" 1096 1096 } 1097 1097 } … … 1118 1118 1119 1119 switch -- $option { 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1120 hilite { 1121 if {[llength $args] != 2} { 1122 error "wrong # args: should be \"_axis hilite axis state\"" 1123 } 1124 set g $itk_component(plot) 1125 set axis [lindex $args 0] 1126 set state [lindex $args 1] 1127 1128 if {$state} { 1129 $g axis configure $axis \ 1130 -color $itk_option(-activecolor) \ 1131 -titlecolor $itk_option(-activecolor) 1132 1133 set x [expr {[winfo pointerx $g]+4}] 1134 set y [expr {[winfo pointery $g]+4}] 1135 Rappture::Tooltip::tooltip pending $g-$axis @$x,$y 1136 } else { 1137 $g axis configure $axis \ 1138 -color $itk_option(-foreground) \ 1139 -titlecolor $itk_option(-foreground) 1140 Rappture::Tooltip::tooltip cancel 1141 } 1142 } 1143 click { 1144 if {[llength $args] != 3} { 1145 error "wrong # args: should be \"_axis click axis x y\"" 1146 } 1147 set axis [lindex $args 0] 1148 set x [lindex $args 1] 1149 set y [lindex $args 2] 1150 set g $itk_component(plot) 1151 1152 set _axis(moved) 0 1153 set _axis(click-x) $x 1154 set _axis(click-y) $y 1155 foreach {min max} [$g axis limits $axis] break 1156 set _axis(min0) $min 1157 set _axis(max0) $max 1158 Rappture::Tooltip::tooltip cancel 1159 } 1160 drag { 1161 if {[llength $args] != 3} { 1162 error "wrong # args: should be \"_axis drag axis x y\"" 1163 } 1164 if {![info exists _axis(moved)]} { 1165 return ;# must have skipped click event -- ignore 1166 } 1167 set axis [lindex $args 0] 1168 set x [lindex $args 1] 1169 set y [lindex $args 2] 1170 set g $itk_component(plot) 1171 1172 if {[info exists _axis(click-x)] && [info exists _axis(click-y)]} { 1173 foreach {x0 y0 pw ph} [$g extents plotarea] break 1174 switch -glob $axis { 1175 x* { 1176 set pix $x 1177 set pix0 $_axis(click-x) 1178 set pixmin $x0 1179 set pixmax [expr {$x0+$pw}] 1180 } 1181 y* { 1182 set pix $y 1183 set pix0 $_axis(click-y) 1184 set pixmin [expr {$y0+$ph}] 1185 set pixmax $y0 1186 } 1187 } 1188 set log [$g axis cget $axis -logscale] 1189 set min $_axis(min0) 1190 set max $_axis(max0) 1191 set dpix [expr {abs($pix-$pix0)}] 1192 set v0 [$g axis invtransform $axis $pixmin] 1193 set v1 [$g axis invtransform $axis [expr {$pixmin+$dpix}]] 1194 if {$log} { 1195 set v0 [expr {log10($v0)}] 1196 set v1 [expr {log10($v1)}] 1197 set min [expr {log10($min)}] 1198 set max [expr {log10($max)}] 1199 } 1200 1201 if {$pix > $pix0} { 1202 set delta [expr {$v1-$v0}] 1203 } else { 1204 set delta [expr {$v0-$v1}] 1205 } 1206 set min [expr {$min-$delta}] 1207 set max [expr {$max-$delta}] 1208 if {$log} { 1209 set min [expr {pow(10.0,$min)}] 1210 set max [expr {pow(10.0,$max)}] 1211 } 1212 $g axis configure $axis -min $min -max $max 1213 1214 # move axis, don't edit on release 1215 set _axis(move) 1 1216 } 1217 } 1218 release { 1219 if {[llength $args] != 3} { 1220 error "wrong # args: should be \"_axis release axis x y\"" 1221 } 1222 if {![info exists _axis(moved)]} { 1223 return ;# must have skipped click event -- ignore 1224 } 1225 set axis [lindex $args 0] 1226 set x [lindex $args 1] 1227 set y [lindex $args 2] 1228 1229 if {!$_axis(moved)} { 1230 # small movement? then treat as click -- pop up axis editor 1231 set dx [expr {abs($x-$_axis(click-x))}] 1232 set dy [expr {abs($y-$_axis(click-y))}] 1233 if {$dx < 2 && $dy < 2} { 1234 _axis edit $axis 1235 } 1236 } else { 1237 # one last movement 1238 _axis drag $axis $x $y 1239 } 1240 catch {unset _axis} 1241 } 1242 edit { 1243 if {[llength $args] != 1} { 1244 error "wrong # args: should be \"_axis edit axis\"" 1245 } 1246 set axis [lindex $args 0] 1247 set _axisPopup(current) $axis 1248 1249 # apply last value when deactivating 1250 $itk_component(hull).axes configure -deactivatecommand \ 1251 [itcl::code $this _axis changed $axis focus] 1252 1253 # fix axis label controls... 1254 set label [$itk_component(plot) axis cget $axis -title] 1255 $inner.label delete 0 end 1256 $inner.label insert end $label 1257 bind $inner.label <KeyPress-Return> \ 1258 [itcl::code $this _axis changed $axis label] 1259 bind $inner.label <FocusOut> \ 1260 [itcl::code $this _axis changed $axis label] 1261 1262 # fix min/max controls... 1263 foreach {min max} [$itk_component(plot) axis limits $axis] break 1264 $inner.min delete 0 end 1265 $inner.min insert end $min 1266 bind $inner.min <KeyPress-Return> \ 1267 [itcl::code $this _axis changed $axis min] 1268 bind $inner.min <FocusOut> \ 1269 [itcl::code $this _axis changed $axis min] 1270 1271 $inner.max delete 0 end 1272 $inner.max insert end $max 1273 bind $inner.max <KeyPress-Return> \ 1274 [itcl::code $this _axis changed $axis max] 1275 bind $inner.max <FocusOut> \ 1276 [itcl::code $this _axis changed $axis max] 1277 1278 # fix format control... 1279 set fmts [$inner.format choices get -value] 1280 set i [lsearch -exact $fmts $_axisPopup(format-$axis)] 1281 if {$i < 0} { set i 0 } ;# use Auto choice 1282 $inner.format value [$inner.format choices get -label $i] 1283 1284 bind $inner.format <<Value>> \ 1285 [itcl::code $this _axis changed $axis format] 1286 1287 # fix scale control... 1288 if {[$itk_component(plot) axis cget $axis -logscale]} { 1289 set _axisPopup(scale) "log" 1290 $inner.format configure -state disabled 1291 } else { 1292 set _axisPopup(scale) "linear" 1293 $inner.format configure -state normal 1294 } 1295 $inner.scales.linear configure \ 1296 -command [itcl::code $this _axis changed $axis scale] 1297 $inner.scales.log configure \ 1298 -command [itcl::code $this _axis changed $axis scale] 1299 1300 # 1301 # Figure out where the window should pop up. 1302 # 1303 set x [winfo rootx $itk_component(plot)] 1304 set y [winfo rooty $itk_component(plot)] 1305 set w [winfo width $itk_component(plot)] 1306 set h [winfo height $itk_component(plot)] 1307 foreach {x0 y0 pw ph} [$itk_component(plot) extents plotarea] break 1308 switch -glob -- $axis { 1309 x { 1310 set x [expr {round($x + $x0+0.5*$pw)}] 1311 set y [expr {round($y + $y0+$ph + 0.5*($h-$y0-$ph))}] 1312 set dir "above" 1313 } 1314 x* { 1315 set x [expr {round($x + $x0+0.5*$pw)}] 1316 set dir "below" 1317 set allx [$itk_component(plot) x2axis use] 1318 set max [llength $allx] 1319 set i [lsearch -exact $allx $axis] 1320 set y [expr {round($y + ($i+0.5)*$y0/double($max))}] 1321 } 1322 y { 1323 set x [expr {round($x + 0.5*$x0)}] 1324 set y [expr {round($y + $y0+0.5*$ph)}] 1325 set dir "right" 1326 } 1327 y* { 1328 set y [expr {round($y + $y0+0.5*$ph)}] 1329 set dir "left" 1330 set ally [$itk_component(plot) y2axis use] 1331 set max [llength $ally] 1332 set i [lsearch -exact $ally $axis] 1333 set y [expr {round($y + ($i+0.5)*$y0/double($max))}] 1334 set x [expr {round($x+$x0+$pw + ($i+0.5)*($w-$x0-$pw)/double($max))}] 1335 } 1336 } 1337 $itk_component(hull).axes activate @$x,$y $dir 1338 } 1339 changed { 1340 if {[llength $args] != 2} { 1341 error "wrong # args: should be \"_axis changed axis what\"" 1342 } 1343 set axis [lindex $args 0] 1344 set what [lindex $args 1] 1345 if {$what == "focus"} { 1346 set what [focus] 1347 if {[winfo exists $what]} { 1348 set what [winfo name $what] 1349 } 1350 } 1351 1352 switch -- $what { 1353 label { 1354 set val [$inner.label get] 1355 $itk_component(plot) axis configure $axis -title $val 1356 } 1357 min { 1358 set val [$inner.min get] 1359 if {![string is double -strict $val]} { 1360 Rappture::Tooltip::cue $inner.min "Must be a number" 1361 bell 1362 return 1363 } 1364 1365 set max [lindex [$itk_component(plot) axis limits $axis] 1] 1366 if {$val >= $max} { 1367 Rappture::Tooltip::cue $inner.min "Must be <= max ($max)" 1368 bell 1369 return 1370 } 1371 catch { 1372 # can fail in log mode 1373 $itk_component(plot) axis configure $axis -min $val 1374 } 1375 foreach {min max} [$itk_component(plot) axis limits $axis] break 1376 $inner.min delete 0 end 1377 $inner.min insert end $min 1378 } 1379 max { 1380 set val [$inner.max get] 1381 if {![string is double -strict $val]} { 1382 Rappture::Tooltip::cue $inner.max "Should be a number" 1383 bell 1384 return 1385 } 1386 1387 set min [lindex [$itk_component(plot) axis limits $axis] 0] 1388 if {$val <= $min} { 1389 Rappture::Tooltip::cue $inner.max "Must be >= min ($min)" 1390 bell 1391 return 1392 } 1393 catch { 1394 # can fail in log mode 1395 $itk_component(plot) axis configure $axis -max $val 1396 } 1397 foreach {min max} [$itk_component(plot) axis limits $axis] break 1398 $inner.max delete 0 end 1399 $inner.max insert end $max 1400 } 1401 format { 1402 set fmt [$inner.format translate [$inner.format value]] 1403 set _axisPopup(format-$axis) $fmt 1404 1405 # force a refresh 1406 $itk_component(plot) axis configure $axis -min \ 1407 [$itk_component(plot) axis cget $axis -min] 1408 } 1409 scale { 1410 _axis scale $axis $_axisPopup(scale) 1411 1412 if {$_axisPopup(scale) == "log"} { 1413 $inner.format configure -state disabled 1414 } else { 1415 $inner.format configure -state normal 1416 } 1417 1418 foreach {min max} [$itk_component(plot) axis limits $axis] break 1419 $inner.min delete 0 end 1420 $inner.min insert end $min 1421 $inner.max delete 0 end 1422 $inner.max insert end $max 1423 } 1424 default { 1425 # be lenient so we can handle the "focus" case 1426 } 1427 } 1428 } 1429 format { 1430 if {[llength $args] != 3} { 1431 error "wrong # args: should be \"_axis format axis widget value\"" 1432 } 1433 set axis [lindex $args 0] 1434 set value [lindex $args 2] 1435 1436 if {[$itk_component(plot) axis cget $axis -logscale]} { 1437 set fmt "%.3g" 1438 } else { 1439 set fmt $_axisPopup(format-$axis) 1440 } 1441 return [format $fmt $value] 1442 } 1443 scale { 1444 if {[llength $args] != 2} { 1445 error "wrong # args: should be \"_axis scale axis type\"" 1446 } 1447 set axis [lindex $args 0] 1448 set type [lindex $args 1] 1449 1450 if {$type == "log"} { 1451 catch {$itk_component(plot) axis configure $axis -logscale 1} 1452 # leave format alone in log mode 1453 $itk_component(plot) axis configure $axis -command "" 1454 } else { 1455 catch {$itk_component(plot) axis configure $axis -logscale 0} 1456 # use special formatting for linear mode 1457 $itk_component(plot) axis configure $axis -command \ 1458 [itcl::code $this _axis format $axis] 1459 } 1460 } 1461 default { 1462 error "bad option \"$option\": should be changed, edit, hilite, or format" 1463 } 1464 1464 } 1465 1465 } … … 1475 1475 itcl::body Rappture::XyResult::_getLineMarkerOptions {style} { 1476 1476 array set lineOptions { 1477 1478 1479 1480 1477 "-color" "-outline" 1478 "-dashes" "-dashes" 1479 "-linecolor" "-outline" 1480 "-linewidth" "-linewidth" 1481 1481 } 1482 1482 set options {} 1483 1483 foreach {name value} $style { 1484 1485 1486 1484 if { [info exists lineOptions($name)] } { 1485 lappend options $lineOptions($name) $value 1486 } 1487 1487 } 1488 1488 return $options … … 1498 1498 itcl::body Rappture::XyResult::_getTextMarkerOptions {style} { 1499 1499 array set textOptions { 1500 1501 1502 1503 1504 1505 1500 "-color" "-outline" 1501 "-textcolor" "-outline" 1502 "-font" "-font" 1503 "-xoffset" "-xoffset" 1504 "-yoffset" "-yoffset" 1505 "-anchor" "-anchor" 1506 1506 } 1507 1507 set options {} 1508 1508 foreach {name value} $style { 1509 1510 1511 1509 if { [info exists textOptions($name)] } { 1510 lappend options $textOptions($name) $value 1511 } 1512 1512 } 1513 1513 return $options … … 1524 1524 # rebuild if needed, so we know about the axes 1525 1525 if {[$_dispatcher ispending !rebuild]} { 1526 1527 1526 $_dispatcher cancel !rebuild 1527 $_dispatcher event -now !rebuild 1528 1528 } 1529 1529 … … 1531 1531 set xlabel [$xydata hints xlabel] 1532 1532 if {[info exists _label2axis(x-$xlabel)]} { 1533 1533 set mapx $_label2axis(x-$xlabel) 1534 1534 } else { 1535 1535 set mapx "x" 1536 1536 } 1537 1537 … … 1539 1539 set ylabel [$xydata hints ylabel] 1540 1540 if {[info exists _label2axis(y-$ylabel)]} { 1541 1541 set mapy $_label2axis(y-$ylabel) 1542 1542 } else { 1543 1543 set mapy "y" 1544 1544 } 1545 1545 … … 1552 1552 itcl::configbody Rappture::XyResult::gridcolor { 1553 1553 if {"" == $itk_option(-gridcolor)} { 1554 1554 $itk_component(plot) grid off 1555 1555 } else { 1556 1557 1556 $itk_component(plot) grid configure -color $itk_option(-gridcolor) 1557 $itk_component(plot) grid on 1558 1558 } 1559 1559 } … … 1564 1564 itcl::configbody Rappture::XyResult::autocolors { 1565 1565 foreach c $itk_option(-autocolors) { 1566 1567 1568 1566 if {[catch {winfo rgb $itk_component(hull) $c}]} { 1567 error "bad color \"$c\"" 1568 } 1569 1569 } 1570 1570 if {$_autoColorI >= [llength $itk_option(-autocolors)]} { 1571 1571 set _autoColorI 0 1572 1572 } 1573 1573 } … … 1576 1576 _leaveMarker $g $name 1577 1577 set id [$g marker create text \ 1578 1579 1580 1581 1578 -coords [list $x $y] \ 1579 -yoffset -1 \ 1580 -anchor s \ 1581 -text $text] 1582 1582 set _markers($name) $id 1583 1583 } … … 1585 1585 itcl::body Rappture::XyResult::_leaveMarker { g name } { 1586 1586 if { [info exists _markers($name)] } { 1587 1588 1589 1590 } 1591 } 1587 set id $_markers($name) 1588 $g marker delete $id 1589 unset _markers($name) 1590 } 1591 } -
trunk/lang/python/Rappture/PyRpLibrary.cc
r1326 r1527 28 28 29 29 static PyObject *ErrorObject; 30 RpLibrary * RpLibraryObject_AsLibrary(PyObject *lib);31 static PyObject * RpLibraryObject_FromLibrary(RpLibrary *lib);32 int boolAsInt(const char * inVal, int*outVal);33 int boolIntFromPyObject ( PyObject * inPyObj, const char*defaultVal,34 const char * argName, int*boolVal);35 int getArgCount ( PyObject * args, PyObject* keywds, int*argc);30 RpLibrary * RpLibraryObject_AsLibrary(PyObject *lib); 31 static PyObject * RpLibraryObject_FromLibrary(RpLibrary *lib); 32 int boolAsInt(const char *inVal, int *outVal); 33 int boolIntFromPyObject ( PyObject *inPyObj, const char *defaultVal, 34 const char *argName, int *boolVal); 35 int getArgCount ( PyObject *args, PyObject *keywds, int *argc); 36 36 37 37 typedef struct { 38 38 PyObject_HEAD 39 RpLibrary *lib;39 RpLibrary *lib; 40 40 } RpLibraryObject; 41 41 … … 87 87 } 88 88 89 static PyObject *89 static PyObject * 90 90 RpLibraryObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 91 91 { … … 149 149 delete(self->lib); 150 150 } 151 self->ob_type->tp_free((PyObject *) self);151 self->ob_type->tp_free((PyObject *) self); 152 152 } 153 153 } … … 169 169 "); 170 170 171 static PyObject *171 static PyObject * 172 172 RpLibraryObject_copy(RpLibraryObject *self, PyObject *args, PyObject *keywds) 173 173 { … … 178 178 PyObject *fromobj = (PyObject *) self; 179 179 180 static char *kwlist[] = { 181 182 183 (char *)"fromobj", 184 180 static char *kwlist[] = { 181 (char *)"topath", 182 (char *)"frompath", 183 (char *)"fromobj", 184 NULL 185 185 }; 186 186 … … 252 252 "); 253 253 254 static PyObject *254 static PyObject * 255 255 RpLibraryObject_element(RpLibraryObject *self, PyObject *args, PyObject *keywds) 256 256 { … … 263 263 264 264 static char *kwlist[] = { 265 (char *)"path", 266 (char *)"as", 267 265 (char *)"path", 266 (char *)"as", 267 NULL 268 268 }; 269 269 … … 340 340 "); 341 341 342 static PyObject *342 static PyObject * 343 343 RpLibraryObject_get(RpLibraryObject *self, PyObject *args, PyObject *keywds) 344 344 { … … 356 356 357 357 static char *kwlist[] = { 358 359 (char *)"decode", 360 358 (char *)"path", 359 (char *)"decode", 360 NULL 361 361 }; 362 362 … … 432 432 "); 433 433 434 static PyObject *434 static PyObject * 435 435 RpLibraryObject_parent(RpLibraryObject *self, PyObject *args, PyObject *keywds) 436 436 { … … 443 443 444 444 static char *kwlist[] = { 445 (char *)"path", 446 (char *)"as", 447 445 (char *)"path", 446 (char *)"as", 447 NULL 448 448 }; 449 449 … … 531 531 "); 532 532 533 static PyObject *533 static PyObject * 534 534 RpLibraryObject_put(RpLibraryObject *self, PyObject *args, PyObject *keywds) 535 535 { … … 555 555 556 556 static char *kwlist[] = { 557 558 559 560 561 562 (char *)"compress", 563 557 (char *)"path", 558 (char *)"value", 559 (char *)"id", 560 (char *)"append", 561 (char *)"type", 562 (char *)"compress", 563 NULL 564 564 }; 565 565 … … 827 827 * used to create a RpLibrary object from a PyObject 828 828 */ 829 RpLibrary *829 RpLibrary * 830 830 RpLibraryObject_AsLibrary(PyObject *lib) 831 831 { 832 RpLibrary *retval = NULL;832 RpLibrary *retval = NULL; 833 833 834 834 if (lib != NULL) { … … 843 843 * used to create a PyObject from a RpLibrary object 844 844 */ 845 PyObject *845 PyObject * 846 846 RpLibraryObject_FromLibrary(RpLibrary *lib) 847 847 { … … 883 883 884 884 int 885 boolAsInt(const char * inVal, int*outVal)885 boolAsInt(const char *inVal, int *outVal) 886 886 { 887 887 int len = 0; … … 936 936 int 937 937 boolIntFromPyObject ( 938 PyObject *inPyObj,939 const char *defaultVal,940 const char *argName,941 int *boolVal938 PyObject *inPyObj, 939 const char *defaultVal, 940 const char *argName, 941 int *boolVal 942 942 ) 943 943 { 944 944 int status = -1; 945 PyObject *inStrObj = NULL;946 char *inStr = NULL;945 PyObject *inStrObj = NULL; 946 char *inStr = NULL; 947 947 948 948 if ( (defaultVal == NULL) || … … 983 983 984 984 int getArgCount ( 985 PyObject *args,986 PyObject *keywds,987 int *argc985 PyObject *args, 986 PyObject *keywds, 987 int *argc 988 988 ) 989 989 { -
trunk/src/core/RpBuffer.cc
r1384 r1527 120 120 if (f == NULL) { 121 121 status.addError("can't open \"%s\": %s", filePath, strerror(errno)); 122 122 return false; 123 123 } 124 124 struct stat stat; 125 125 if (fstat(fileno(f), &stat) < 0) { 126 126 status.addError("can't stat \"%s\": %s", filePath, strerror(errno)); 127 128 } 127 return false; 128 } 129 129 off_t size; 130 130 size = stat.st_size; … … 133 133 if (memblock == NULL) { 134 134 status.addError("can't allocate %d bytes for file \"%s\": %s", 135 135 size, filePath, strerror(errno)); 136 136 fclose(f); 137 137 return false; … … 139 139 140 140 // FIXME: better yet, create an "extend" method in the buffer and returns 141 // 142 // 141 // the address of the char buffer so I can read the data directly 142 // into the buffer. This eliminates memory new/copy/delete ops. 143 143 144 144 size_t nRead; 145 145 nRead = fread(memblock, sizeof(char), size, f); 146 fclose(f); 146 fclose(f); // Close the file. 147 147 148 148 if (nRead != (size_t)size) { 149 149 status.addError("can't read %d bytes from \"%s\": %s", size, filePath, 150 151 return false; 152 } 150 strerror(errno)); 151 return false; 152 } 153 153 154 154 int nBytes; … … 158 158 if (nBytes != size) { 159 159 status.addError("can't append %d bytes from \"%s\" to buffer: %s", 160 161 return false; 162 } 160 size, filePath, strerror(errno)); 161 return false; 162 } 163 163 return true; 164 164 } … … 174 174 if (f != NULL) { 175 175 status.addError("can't open \"%s\": %s\n", filePath, strerror(errno)); 176 176 return false; 177 177 } 178 178 ssize_t nWritten; 179 179 nWritten = fwrite(bytes(), size(), sizeof(char), f); 180 fclose(f); 181 180 fclose(f); // Close the file. 181 182 182 if (nWritten != (ssize_t)size()) { 183 183 status.addError("can't write %d bytes to \"%s\": %s\n", size(), 184 185 184 filePath, strerror(errno)); 185 return false; 186 186 } 187 187 return true; … … 198 198 switch (flags & (RPENC_Z | RPENC_B64)) { 199 199 case 0: 200 201 202 case RPENC_Z: 203 204 205 206 207 208 209 case RPENC_B64: 200 break; 201 202 case RPENC_Z: // Compress only 203 if (!do_compress(status, *this, bout)) { 204 return false; 205 } 206 move(bout); 207 break; 208 209 case RPENC_B64: // Encode only 210 210 if (!do_base64_enc(status, *this, bout)) { 211 211 return false; 212 212 } 213 214 213 move(bout); 214 break; 215 215 216 216 case (RPENC_B64 | RPENC_Z): 217 218 219 220 221 217 218 // It's always compress then encode 219 if (!do_compress(status, *this, bout)) { 220 return false; 221 } 222 222 if (!do_base64_enc(status, bout, *this)) { 223 223 return false; 224 224 } 225 225 break; 226 226 } 227 227 return true; … … 238 238 switch (flags & (RPENC_Z | RPENC_B64)) { 239 239 case 0: 240 241 242 243 244 245 246 247 248 249 250 251 252 253 break; 254 255 case RPENC_Z: 256 257 258 259 260 261 262 case RPENC_B64: 240 if (encoding::isBase64(bytes(), size())) { 241 if (!do_base64_dec(status, *this, bout)) { 242 return false; 243 } 244 move(bout); 245 } 246 bout.clear(); 247 if (encoding::isBinary(bytes(), size())) { 248 if (!do_decompress(status, *this, bout)) { 249 return false; 250 } 251 move(bout); 252 } 253 break; 254 255 case RPENC_Z: // Decompress only 256 if (!do_decompress(status, *this, bout)) { 257 return false; 258 } 259 move(bout); 260 break; 261 262 case RPENC_B64: // Decode only 263 263 if (!do_base64_dec(status, *this, bout)) { 264 264 return false; 265 265 } 266 267 266 move(bout); 267 break; 268 268 269 269 case (RPENC_B64 | RPENC_Z): 270 271 270 271 // It's always decode then decompress 272 272 if (!do_base64_dec(status, *this, bout)) { 273 273 return false; 274 274 } 275 276 277 278 279 275 clear(); 276 if (!do_decompress(status, bout, *this)) { 277 return false; 278 } 279 break; 280 280 } 281 281 return true; … … 285 285 bool 286 286 Buffer::do_compress(Outcome& status, SimpleCharBuffer& bin, 287 287 SimpleCharBuffer& bout) 288 288 { 289 289 int ret=0, flush=0; … … 357 357 bool 358 358 Buffer::do_decompress(Outcome& status, SimpleCharBuffer& bin, 359 359 SimpleCharBuffer& bout) 360 360 { 361 361 int ret; … … 433 433 bool 434 434 Buffer::do_base64_enc(Outcome& status, const SimpleCharBuffer& bin, 435 435 SimpleCharBuffer& bout ) 436 436 { 437 437 int tBufSize = 0; … … 453 453 bool 454 454 Buffer::do_base64_dec(Outcome& status, const SimpleCharBuffer& bin, 455 455 SimpleCharBuffer& bout ) 456 456 { 457 457 int tBufSize = 0; -
trunk/src/core/RpBuffer.h
r1384 r1527 72 72 73 73 enum { CHUNK = 4096 }; 74 74 75 75 bool do_compress(Outcome& status, SimpleCharBuffer& bin, 76 76 SimpleCharBuffer& bout ); 77 77 bool do_decompress( Outcome& status, SimpleCharBuffer& bin, 78 78 SimpleCharBuffer& bout ); 79 79 bool do_base64_enc(Outcome& status, const SimpleCharBuffer& bin, 80 80 SimpleCharBuffer& bout ); 81 81 bool do_base64_dec(Outcome& status, const SimpleCharBuffer& bin, 82 82 SimpleCharBuffer& bout ); 83 83 }; 84 84 85 85 } // namespace Rappture 86 86 87 87 #ifdef __cplusplus 88 88 } -
trunk/src/core/RpLibrary.cc
r1384 r1527 1177 1177 if (retNode) { 1178 1178 // allocate a new rappture library object for the node 1179 retLib = new RpLibrary( retNode,this->tree ); 1179 retLib = new RpLibrary( retNode,this->tree ); 1180 1180 } 1181 1181 } … … 1545 1545 // because base64 character set does not include xml entity chars 1546 1546 if (!Rappture::encoding::decode(status, inData, 0)) { 1547 1548 1547 return retStr; 1548 } 1549 1549 retStr = std::string(inData.bytes(),inData.size()); 1550 1550 } else { … … 1552 1552 if (translateFlag == RPLIB_TRANSLATE) { 1553 1553 translatedContents = ERTranslator.decode(inData.bytes(), 1554 1554 inData.size()); 1555 1555 if (translatedContents == NULL) { 1556 1556 // translation failed 1557 1557 if (!status) { 1558 1558 status.error("Error while translating entity references"); 1559 1559 return retStr; 1560 1560 } 1561 1561 } else { … … 1738 1738 RpLibrary& 1739 1739 RpLibrary::put (std::string path, std::string value, std::string id, 1740 1740 unsigned int append, unsigned int translateFlag) 1741 1741 { 1742 1742 Rappture::EntityRef ERTranslator; … … 1756 1756 // check for binary data 1757 1757 // FIXME: I've already appended a NUL-byte of this assuming that 1758 // 1758 // it's a ASCII string. This test must come before. 1759 1759 if (Rappture::encoding::isBinary(value.c_str(), value.length())) { 1760 1760 putData(path, value.c_str(), value.length(), append); … … 1775 1775 if (!status) { 1776 1776 status.error("Error while translating entity references"); 1777 1777 return *this; 1778 1778 } 1779 1779 } … … 1801 1801 1802 1802 RpLibrary& 1803 RpLibrary::put (std::string path, double value, std::string id, 1804 1803 RpLibrary::put (std::string path, double value, std::string id, 1804 unsigned int append) 1805 1805 { 1806 1806 std::stringstream valStr; … … 1962 1962 1963 1963 if (retNode == NULL) { 1964 1965 1964 status.addError("can't create node from path \"%s\"", path.c_str()); 1965 return *this; 1966 1966 } 1967 1967 if (append == RPLIB_APPEND) { 1968 1969 1970 1971 1972 1973 1974 1968 if ( (contents = scew_element_contents(retNode)) ) { 1969 inData.append(contents); 1970 // base64 decode and un-gzip the data 1971 if (!Rappture::encoding::decode(status, inData, 0)) { 1972 return *this; 1973 } 1974 } 1975 1975 } 1976 1976 if (inData.append(bytes, nbytes) != nbytes) { 1977 1978 1979 } 1977 status.addError("can't append %d bytes", nbytes); 1978 return *this; 1979 } 1980 1980 // gzip and base64 encode the data 1981 1981 flags = RPENC_Z|RPENC_B64|RPENC_HDR; 1982 1982 if (!Rappture::encoding::encode(status, inData,flags)) { 1983 1983 return *this; 1984 1984 } 1985 1985 bytesWritten = (unsigned int) inData.size(); … … 1993 1993 /// Put data from a file into the xml. 1994 1994 /** 1995 * Append flag adds additional nodes, it does not merge same 1995 * Append flag adds additional nodes, it does not merge same 1996 1996 * named nodes together 1997 1997 */ 1998 1998 1999 1999 RpLibrary& 2000 RpLibrary::putFile(std::string path, std::string fileName, 2001 2000 RpLibrary::putFile(std::string path, std::string fileName, 2001 unsigned int compress, unsigned int append) 2002 2002 { 2003 2003 Rappture::Buffer buf; … … 2011 2011 2012 2012 if (!fileBuf.load(err, fileName.c_str())) { 2013 2014 2013 fprintf(stderr, "error loading file: %s\n", err.remark()); 2014 return *this; 2015 2015 } 2016 2016 if (compress == RPLIB_COMPRESS) { 2017 2017 putData(path, fileBuf.bytes(), fileBuf.size(), append); 2018 2018 } else { 2019 2019 /* Always append a NUL-byte to the end of ASCII strings. */ 2020 2020 fileBuf.append("\0", 1); 2021 2021 put(path, fileBuf.bytes(), "", append, RPLIB_TRANSLATE); -
trunk/src/core/RpSimpleBuffer.h
r1398 r1527 67 67 #include <cstring> 68 68 #include <cstdlib> 69 #include <cstdarg> 69 70 70 71 namespace Rappture { … … 88 89 SimpleBuffer<T>& clear(); 89 90 int append(const T* bytes, int nmemb=-1); 91 int appendf(const char *format, ...); 92 int remove(int nmemb); 90 93 size_t read(const T* bytes, size_t nmemb); 91 94 int seek(long offset, int whence); 92 95 int tell() const; 93 size_t set(size_t n bytes);96 size_t set(size_t nmemb); 94 97 SimpleBuffer<T>& rewind(); 95 98 SimpleBuffer<T>& show(); … … 345 348 return 0; 346 349 } 350 351 // FIXME: i think this needs to be division, 352 // need to create test case with array of ints 353 // i'm not sure we can even guess the number 354 // bytes in *bytes. 347 355 348 356 if (nmemb == -1) { … … 351 359 // at the length of the object. 352 360 nbytes = __guesslen(bytes); 353 nmemb = nbytes *sizeof(T);361 nmemb = nbytes/sizeof(T); 354 362 } 355 363 … … 397 405 } 398 406 407 /** 408 * Append formatted bytes to the end of this buffer 409 * @param pointer to bytes to be added 410 * @param number of bytes to be added 411 * @return number of bytes appended. 412 */ 413 template<class T> 414 int 415 SimpleBuffer<T>::appendf(const char *format, ...) 416 { 417 size_t newMembCnt = 0; 418 size_t nbytes = 0; 419 int nmemb = 0; 420 421 char* dest = NULL; 422 size_t size = 0; 423 size_t bytesAdded = 0; 424 va_list arg; 425 426 // User specified NULL format 427 if (format == NULL) { 428 return 0; 429 } 430 431 // FIXME: i think this needs to be division, 432 // need to create test case with array of ints 433 // i'm not sure we can even guess the number 434 // bytes in *bytes. 435 436 437 // add one for terminating null character 438 nbytes = strlen(format) + 1; 439 440 if (nbytes <= 0) { 441 // no data written, invalid option 442 return nbytes; 443 } 444 445 // FIXME: we need ceil of nbytes/sizeof(T), instead we add 1 for safety 446 447 nmemb = nbytes/sizeof(T); 448 if (nmemb == 0) { 449 nmemb++; 450 } 451 452 newMembCnt = (size_t)(_nMembStored + nmemb); 453 454 if (newMembCnt > _nMembAvl) { 455 456 // buffer sizes less than min_size are set to min_size 457 if (newMembCnt < (size_t) _minMembCnt) { 458 newMembCnt = (size_t) _minMembCnt; 459 } 460 461 /* 462 * Allocate a larger buffer for the string if the current one isn't 463 * large enough. Allocate extra space in the new buffer so that there 464 * will be room to grow before we have to allocate again. 465 */ 466 size_t membAvl; 467 membAvl = (_nMembAvl > 0) ? _nMembAvl : _minMembCnt; 468 while (newMembCnt > membAvl) { 469 membAvl += membAvl; 470 } 471 472 /* 473 * reallocate to a larger buffer 474 */ 475 if (set(membAvl) != membAvl) { 476 return 0; 477 } 478 } 479 480 dest = (char*) (_buf + _nMembStored); 481 size = (_nMembAvl-_nMembStored)*sizeof(T); 482 483 va_start(arg,format); 484 bytesAdded = vsnprintf(dest,size,format,arg); 485 va_end(arg); 486 487 // bytesAdded contains the number of bytes that would have 488 // been placed in the buffer if the call was successful. 489 // this value does not include the trailing null character. 490 // so we add one to account for it. 491 492 bytesAdded++; 493 nmemb = bytesAdded/sizeof(T); 494 495 if (bytesAdded > size) { 496 // we did not fit everything in the original buffer 497 // resize and try again. 498 499 // FIXME: round the new size up to the nearest multiple of 256? 500 set(_nMembStored+nmemb); 501 502 // reset dest because it may have moved during reallocation 503 dest = (char*) (_buf + _nMembStored); 504 size = bytesAdded; 505 506 va_start(arg,format); 507 bytesAdded = vsnprintf(dest,size,format,arg); 508 va_end(arg); 509 510 if (bytesAdded > size) { 511 // crystals grow, people grow, data doesn't grow... 512 // issue error 513 fprintf(stderr,"error in appendf while appending data"); 514 } 515 } 516 517 _nMembStored += nmemb; 518 519 // remove the null character added by vsnprintf() 520 // we do this because if we are appending strings, 521 // the embedded null acts as a terminating null char. 522 // this is a generic buffer so if user wants a 523 // terminating null, they should append it. 524 remove(1); 525 526 return nmemb; 527 } 528 529 /** 530 * Remove bytes from the end of this buffer 531 * @param number of bytes to be removed 532 * @return number of bytes removed. 533 */ 534 template<class T> 535 int 536 SimpleBuffer<T>::remove(int nmemb) 537 { 538 if ((_nMembStored - nmemb) < 0){ 539 _nMembStored = 0; 540 _pos = 0; 541 } else { 542 _nMembStored -= nmemb; 543 if (_pos >= _nMembStored) { 544 // move _pos back to the new end of the buffer. 545 _pos = _nMembStored-1; 546 } 547 } 548 549 550 return nmemb; 551 } 552 399 553 400 554 template<class T> … … 412 566 413 567 if (buf == NULL) { 414 fprintf(stderr,"Can't allocate %zu bytes of memory\n",nbytes); 568 fprintf(stderr,"Can't allocate %lu bytes of memory\n", 569 (long unsigned int)nbytes); 415 570 _fileState = false; 416 571 return 0; … … 429 584 430 585 while (curMemb != _nMembStored) { 431 fprintf(stdout,"_buf[%zu] = :%c:\n", curMemb, _buf[curMemb]); 586 fprintf(stdout,"_buf[%lu] = :%c:\n", (long unsigned int)curMemb, 587 _buf[curMemb]); 432 588 curMemb += 1; 433 589 } 434 fprintf(stdout,"_nMembAvl = :% zu:\n",_nMembAvl);590 fprintf(stdout,"_nMembAvl = :%lu:\n", (long unsigned int)_nMembAvl); 435 591 436 592 return *this; … … 445 601 446 602 while (curMemb != _nMembStored) { 447 fprintf(stdout,"_buf[% zu] = :%#lx:\n",curMemb,448 (long unsigned)_buf[curMemb]);603 fprintf(stdout,"_buf[%lu] = :%#x:\n", (long unsigned int)curMemb, 604 (unsigned long)_buf[curMemb]); 449 605 curMemb += 1; 450 606 } 451 fprintf(stdout,"_nMembAvl = :% zu:\n",_nMembAvl);607 fprintf(stdout,"_nMembAvl = :%lu:\n", (long unsigned int)_nMembAvl); 452 608 453 609 return *this; -
trunk/src/core/RpUnits.cc
r1432 r1527 2395 2395 retVal = RpUnitsPreset::addPresetMisc(); 2396 2396 } 2397 else if (group.compare(RP_TYPE_POWER) == 0) { 2398 retVal = RpUnitsPreset::addPresetPower(); 2399 } 2397 2400 2398 2401 return retVal; … … 2426 2429 result += addPresetMagnetic(); 2427 2430 result += addPresetMisc(); 2431 result += addPresetPower(); 2428 2432 2429 2433 return 0; … … 2940 2944 RpUnits* amu = NULL; 2941 2945 RpUnits* bel = NULL; 2946 RpUnits* amp = NULL; 2947 RpUnits* ohm = NULL; 2942 2948 2943 2949 volt = RpUnits::define("V", NULL, RP_TYPE_EPOT, RPUNITS_METRIC); … … 2947 2953 amu = RpUnits::define("amu", NULL, "mass_unit", !RPUNITS_METRIC); 2948 2954 bel = RpUnits::define("B", NULL, "audio_transmission", RPUNITS_METRIC); 2955 amp = RpUnits::define("amp", NULL, "electric_current", RPUNITS_METRIC); 2956 ohm = RpUnits::define("ohm", NULL, "electric_resistance", RPUNITS_METRIC); 2949 2957 2950 2958 // RpUnits* percent = RpUnits::define("%", NULL, RP_TYPE_MISC); 2959 2960 return 0; 2961 } 2962 2963 /**********************************************************************/ 2964 // METHOD: addPresetPower() 2965 /// Add power related units to the dictionary 2966 /** 2967 * Defines the following units: 2968 * watt (W) 2969 * 2970 * Return codes: 0 success, anything else is error 2971 */ 2972 2973 int 2974 RpUnitsPreset::addPresetPower () { 2975 2976 RpUnits* watt = NULL; 2977 2978 // watts are derived units = J/s = kg*m2/s3 = Newton*m/s and Amps*Volt 2979 watt = RpUnits::define("W", NULL, RP_TYPE_POWER, RPUNITS_METRIC); 2951 2980 2952 2981 return 0; … … 2998 3027 return &RpUnitsTypes::hintTypeMisc; 2999 3028 } 3029 else if (type.compare(RP_TYPE_POWER) == 0) { 3030 return &RpUnitsTypes::hintTypePower; 3031 } 3000 3032 else { 3001 3033 return NULL; … … 3177 3209 3178 3210 if ( (unitObj->getType()).compare(RP_TYPE_MISC) == 0 ) { 3211 retVal = true; 3212 } 3213 3214 return retVal; 3215 } 3216 3217 bool 3218 RpUnitsTypes::hintTypePower ( RpUnits* unitObj ) { 3219 3220 bool retVal = false; 3221 3222 if ( (unitObj->getType()).compare(RP_TYPE_POWER) == 0 ) { 3179 3223 retVal = true; 3180 3224 } -
trunk/src/core/RpUnits.h
r1427 r1527 48 48 #define RP_TYPE_MAGNETIC "magnetic" 49 49 #define RP_TYPE_MISC "misc" 50 #define RP_TYPE_POWER "power" 50 51 51 52 … … 87 88 static int addPresetMagnetic(); 88 89 static int addPresetMisc(); 90 static int addPresetPower(); 89 91 }; 90 92 … … 110 112 static bool hintTypeMagnetic ( RpUnits* unitObj ); 111 113 static bool hintTypeMisc ( RpUnits* unitObj ); 114 static bool hintTypePower ( RpUnits* unitObj ); 112 115 113 116 private: … … 520 523 // RP_TYPE_MAGNETIC "magnetic" load units related to magnetics 521 524 // RP_TYPE_MISC "misc" load units related to everything else 525 // RP_TYPE_POWER "power" load units related to power 522 526 // (no other groups have been created) 523 527
Note: See TracChangeset
for help on using the changeset viewer.