home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets2.2.0 / scripts / scrolledframe.itk < prev    next >
Text File  |  1999-02-24  |  20KB  |  614 lines

  1. #
  2. # Scrolledframe
  3. # ----------------------------------------------------------------------
  4. # Implements horizontal and vertical scrollbars around a childsite
  5. # frame.  Includes options to control display of scrollbars.
  6. #
  7. # ----------------------------------------------------------------------
  8. #  AUTHOR: Sue Yockey                           syockey@spd.dsccc.com 
  9. #          Mark Ulferts                         mulferts@spd.dsccc.com 
  10. #
  11. #  @(#) $Id: scrolledframe.itk,v 1.1 1998/07/27 18:49:48 stanton Exp $
  12. # ----------------------------------------------------------------------
  13. #            Copyright (c) 1995 DSC Technologies Corporation
  14. # ======================================================================
  15. # Permission to use, copy, modify, distribute and license this software 
  16. # and its documentation for any purpose, and without fee or written 
  17. # agreement with DSC, is hereby granted, provided that the above copyright 
  18. # notice appears in all copies and that both the copyright notice and 
  19. # warranty disclaimer below appear in supporting documentation, and that 
  20. # the names of DSC Technologies Corporation or DSC Communications 
  21. # Corporation not be used in advertising or publicity pertaining to the 
  22. # software without specific, written prior permission.
  23. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  24. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  25. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  26. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  27. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  28. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  29. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  30. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  31. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  32. # SOFTWARE.
  33. # ======================================================================
  34.  
  35. #
  36. # Default resources.
  37. #
  38. option add *Scrolledframe.borderWidth 2 widgetDefault
  39. option add *Scrolledframe.relief sunken widgetDefault
  40. option add *Scrolledframe.scrollMargin 3 widgetDefault
  41. option add *Scrolledframe.vscrollMode static widgetDefault
  42. option add *Scrolledframe.hscrollMode static widgetDefault
  43. option add *Scrolledframe.width 100 widgetDefault
  44. option add *Scrolledframe.height 100 widgetDefault
  45. option add *Scrolledframe.labelPos n widgetDefault
  46.  
  47. #
  48. # Usual options.
  49. #
  50. itk::usual Scrolledframe {
  51.     keep -activebackground -activerelief -background -borderwidth -cursor \
  52.      -elementborderwidth -foreground -highlightcolor -highlightthickness \
  53.      -jump -labelfont -troughcolor
  54. }
  55.  
  56. # ------------------------------------------------------------------
  57. #                            SCROLLEDFRAME
  58. # ------------------------------------------------------------------
  59. class iwidgets::Scrolledframe {
  60.     inherit iwidgets::Labeledwidget
  61.  
  62.     constructor {args} {}
  63.     destructor {}
  64.  
  65.     itk_option define -sbwidth sbWidth Width 15
  66.     itk_option define -scrollmargin scrollMargin ScrollMargin 3
  67.     itk_option define -vscrollmode vscrollMode VScrollMode static
  68.     itk_option define -hscrollmode hscrollMode HScrollMode static
  69.     itk_option define -width width Width 30
  70.     itk_option define -height height Height 30
  71.  
  72.     public method childsite {} 
  73.     public method justify {direction} 
  74.     public method xview {args} 
  75.     public method yview {args} 
  76.  
  77.     protected method _configureCanvas {} 
  78.     protected method _configureFrame {} 
  79.     protected method _scrollFrame {wid first last} 
  80.     protected method _updateFiller {}
  81.     protected method _configureFiller {}
  82.  
  83.     private method _fillerWidth {} 
  84.     private method _horizScrollbarDisplay {mode} 
  85.     private method _vertScrollbarDisplay {mode} 
  86.  
  87.     protected variable _vmode off            ;# Vertical scroll mode
  88.     protected variable _hmode off            ;# Vertical scroll mode
  89.     protected variable _reconfigPlanned ""   ;# non-null, filler update pending
  90.  
  91.     private variable _initialized 0            ;# Initialization flag.
  92. }
  93.  
  94. #
  95. # Provide a lowercased access method for the Scrolledframe class.
  96. proc ::iwidgets::scrolledframe {pathName args} {
  97.     uplevel ::iwidgets::Scrolledframe $pathName $args
  98. }
  99.  
  100. # ------------------------------------------------------------------
  101. #                        CONSTRUCTOR
  102. # ------------------------------------------------------------------
  103. body iwidgets::Scrolledframe::constructor {args} {
  104.     component hull configure -borderwidth 0
  105.     pack propagate $itk_component(shell) no
  106.  
  107.     #
  108.     # Create some frames to hold both the top and bottom halves of 
  109.     # the widget.  The top will contain both the canvas and vertical 
  110.     # scrollbar.  The bottom houses the horizontal scrollbar and 
  111.     # some filler.
  112.     #
  113.     itk_component add topFrame {
  114.     frame $itk_interior.topFrame
  115.     } {
  116.     keep -background -cursor 
  117.     }
  118.     pack $itk_component(topFrame) -fill both -expand yes
  119.     
  120.     #
  121.     # Frame around horizontal scrollbar 
  122.     #
  123.     itk_component add bottomHalf {
  124.     frame $itk_component(topFrame).bottomHalf
  125.     } {
  126.     keep -background -cursor
  127.     }
  128.     pack $itk_component(bottomHalf) -fill x -side bottom
  129.     
  130.     #
  131.     # Frame for horizontal margin between scrolled area & scrollbar
  132.     #
  133.     itk_component add hMargin {
  134.     frame $itk_component(topFrame).hMargin
  135.     } {
  136.     keep -background -cursor
  137.     }
  138.     pack $itk_component(hMargin) -side bottom
  139.  
  140.     #
  141.     # Frame around canvas and vertical scrollbar
  142.     #
  143.     itk_component add topHalf {
  144.     frame $itk_component(topFrame).topHalf
  145.     } {
  146.     keep -background -cursor
  147.     }
  148.     pack $itk_component(topHalf) -fill both -expand yes    
  149.     
  150.     # 
  151.     # Create a frame for the canvas to provide relief for the canvas.
  152.     #
  153.     itk_component add canvasFrame {
  154.     frame $itk_component(topHalf).canvasFrame \
  155.         -relief sunken -borderwidth 2
  156.     } {
  157.     keep -background -borderwidth -cursor -relief 
  158.     }
  159.     
  160.     # 
  161.     # Create a canvas to scroll
  162.     #
  163.     itk_component add scrCanvas {
  164.     canvas $itk_component(canvasFrame).scrCanvas \
  165.         -height 1.0 -width 1.0 \
  166.                 -scrollregion "0 0 1 1" \
  167.         -highlightthickness 0 \
  168.                 -borderwidth 0 -relief flat \
  169.                 -xscrollcommand \
  170.         [code $this _scrollFrame $itk_component(bottomHalf).hSB] \
  171.         -yscrollcommand \
  172.         [code $this _scrollFrame $itk_component(topHalf).vSB]
  173.     } {
  174.     keep -background -cursor
  175.     }
  176.     pack $itk_component(scrCanvas) -fill both -expand yes
  177.     bind $itk_component(scrCanvas) <Configure> [code $this _configureCanvas]
  178.     
  179.     #
  180.     # Create a Frame inside canvas to hold widgets to be scrolled 
  181.     #
  182.     itk_component add scrFrame {
  183.     frame $itk_component(scrCanvas).scrFrame 
  184.     } {
  185.     keep -background -cursor
  186.     }
  187.     pack $itk_component(scrFrame) -fill both -expand yes
  188.     $itk_component(scrCanvas) create window 1 1 -tags frameTag \
  189.             -window $itk_component(scrFrame) -anchor nw
  190.     set itk_interior $itk_component(scrFrame)
  191.     bind $itk_component(scrFrame) <Configure> [code $this _configureFrame]
  192.     
  193.     #
  194.     # Create frame for the vertical margin between the scrolling
  195.     # area and the scrollbar.
  196.     #
  197.     itk_component add vMargin {
  198.     frame $itk_component(topHalf).vMargin -width 0
  199.     } {
  200.     keep -background -cursor
  201.     }
  202.     
  203.     # 
  204.     # Create the vertical scroll bar.
  205.     #
  206.     itk_component add vSB {
  207.     scrollbar $itk_component(topHalf).vSB -orient vertical \
  208.         -command [code $itk_component(scrCanvas) yview]
  209.     } {
  210.     keep -activebackground -activerelief -background -borderwidth \
  211.         -cursor -elementborderwidth \
  212.         -highlightcolor -jump -highlightthickness -relief \
  213.         -repeatdelay -repeatinterval -troughcolor
  214.     rename -highlightbackground -background background Background
  215.     }
  216.     pack $itk_component(vSB) -side right -fill y
  217.     pack $itk_component(vMargin) -side right
  218.     pack $itk_component(canvasFrame) -fill both -expand yes -side left
  219.     
  220.     #
  221.     # Create the horizontal scrollbar.
  222.     #
  223.     itk_component add hSB {
  224.     scrollbar $itk_component(bottomHalf).hSB -orient horizontal \
  225.         -command [code $itk_component(scrCanvas) xview]
  226.     } {
  227.     keep -activebackground -activerelief -background -borderwidth \
  228.         -cursor -elementborderwidth \
  229.         -highlightcolor -jump -highlightthickness -relief \
  230.         -repeatdelay -repeatinterval -troughcolor
  231.     rename -highlightbackground -background background Background
  232.     }
  233.     pack $itk_component(hSB) -side left -fill x -expand yes
  234.     
  235.     #
  236.     # Create the filler frame and compute its width.
  237.     #
  238.     itk_component add filler {
  239.     frame $itk_component(bottomHalf).filler -width [_fillerWidth]
  240.     } {
  241.     keep -background -cursor
  242.     }
  243.     pack $itk_component(filler) -side right 
  244.     
  245.     #
  246.     # Explicitly handle configs that may have been ignored earlier.
  247.     #
  248.     eval itk_initialize $args
  249.     
  250.     bind $itk_component(hMargin) <Configure> [code $this _configureFiller]
  251.     bind $itk_component(vSB) <Configure> [code $this _configureFiller]
  252.     bind $itk_component(vMargin) <Configure> [code $this _configureFiller]
  253.     bind $itk_component(hSB) <Configure> [code $this _configureFiller]
  254.  
  255.     set _initialized 1
  256.     configure -scrollmargin $itk_option(-scrollmargin)
  257. }
  258.  
  259. # ------------------------------------------------------------------
  260. #                           DESTURCTOR
  261. # ------------------------------------------------------------------
  262. body iwidgets::Scrolledframe::destructor {} {
  263.     if {$_reconfigPlanned != ""} {after cancel $_reconfigPlanned}
  264. }
  265.  
  266. # ------------------------------------------------------------------
  267. #                             OPTIONS
  268. # ------------------------------------------------------------------
  269.  
  270. # ------------------------------------------------------------------
  271. # OPTION: -sbwidth
  272. #
  273. # Set the width of the scrollbars.
  274. # ------------------------------------------------------------------
  275. configbody iwidgets::Scrolledframe::sbwidth {
  276.     if {$_initialized} {
  277.     $itk_component(vSB) configure -width $itk_option(-sbwidth)
  278.     $itk_component(hSB) configure -width $itk_option(-sbwidth)
  279.     }
  280. }
  281.  
  282. # ------------------------------------------------------------------
  283. # OPTION: -scrollmargin
  284. #
  285. # Set the distance between the scrollbars and the canvas.
  286. # ------------------------------------------------------------------
  287. configbody iwidgets::Scrolledframe::scrollmargin {
  288.     if {$_initialized} {
  289.     set pixels [winfo pixels $itk_component(hMargin) \
  290.         $itk_option(-scrollmargin)]
  291.     
  292.     if {$_hmode == "on"} {
  293.         $itk_component(hMargin) config -width 1 -height $pixels
  294.     }
  295.     
  296.     if {$_vmode == "on"} {
  297.         $itk_component(vMargin) config -width $pixels -height 1
  298.     }
  299.     
  300.     $itk_component(filler) config -width [_fillerWidth] -height 1
  301.     }
  302. }
  303.  
  304. # ------------------------------------------------------------------
  305. # OPTION: -vscrollmode
  306. #
  307. # Enable/disable display and mode of veritcal scrollbars.
  308. # ------------------------------------------------------------------
  309. configbody iwidgets::Scrolledframe::vscrollmode {
  310.     switch $itk_option(-vscrollmode) {
  311.         static {
  312.             _vertScrollbarDisplay on
  313.         }
  314.     
  315.         dynamic -
  316.         none {
  317.             _vertScrollbarDisplay off
  318.         }
  319.     
  320.         default {
  321.             error "bad vscrollmode option\
  322.             \"$itk_option(-vscrollmode)\": should be\
  323.             static, dynamic, or none"
  324.         }
  325.     }
  326. }
  327.  
  328. # ------------------------------------------------------------------
  329. # OPTION: -hscrollmode
  330. #
  331. # Enable/disable display and mode of horizontal scrollbars.
  332. # ------------------------------------------------------------------
  333. configbody iwidgets::Scrolledframe::hscrollmode {
  334.     switch $itk_option(-hscrollmode) {
  335.         static {
  336.             _horizScrollbarDisplay on
  337.         }
  338.     
  339.         dynamic -
  340.         none {
  341.             _horizScrollbarDisplay off
  342.         }
  343.     
  344.         default {
  345.             error "bad hscrollmode option\
  346.             \"$itk_option(-hscrollmode)\": should be\
  347.             static, dynamic, or none"
  348.         }
  349.     }
  350. }
  351.  
  352. # ------------------------------------------------------------------
  353. # OPTION: -width
  354. #
  355. # Specifies the width of the scrolled frame.  The value may be 
  356. # specified in any of the forms acceptable to Tk_GetPixels.  
  357. # ------------------------------------------------------------------
  358. configbody iwidgets::Scrolledframe::width {
  359.     set pixels \
  360.             [winfo pixels $itk_component(shell) $itk_option(-width)]
  361.     
  362.     $itk_component(shell) config -width $pixels
  363. }
  364.  
  365. # ------------------------------------------------------------------
  366. # OPTION: -height
  367. #
  368. # Specifies the height of the scrolled frame.  The value may be 
  369. # specified in any of the forms acceptable to Tk_GetPixels.  
  370. # ------------------------------------------------------------------
  371. configbody iwidgets::Scrolledframe::height {
  372.     set pixels \
  373.             [winfo pixels $itk_component(shell) $itk_option(-height)]
  374.     
  375.     $itk_component(shell) config -height $pixels
  376. }
  377.  
  378. # ------------------------------------------------------------------
  379. #                            METHODS
  380. # ------------------------------------------------------------------
  381.  
  382. # ------------------------------------------------------------------
  383. # METHOD: childsite
  384. #
  385. # Returns the path name of the child site widget.
  386. # ------------------------------------------------------------------
  387. body iwidgets::Scrolledframe::childsite {} {
  388.     return $itk_component(scrFrame)
  389. }
  390.  
  391. # ------------------------------------------------------------------
  392. # METHOD: justify
  393. #
  394. # Justifies the scrolled region in one of four directions: top,
  395. # bottom, left, or right.
  396. # ------------------------------------------------------------------
  397. body iwidgets::Scrolledframe::justify {direction} {
  398.     if {[winfo ismapped $itk_component(scrCanvas)]} {
  399.     update idletasks
  400.     
  401.     switch $direction {
  402.         left {
  403.         $itk_component(scrCanvas) xview moveto 0
  404.         }
  405.         right {
  406.         $itk_component(scrCanvas) xview moveto 1
  407.         }
  408.         top {
  409.         $itk_component(scrCanvas) yview moveto 0
  410.         }
  411.         bottom {
  412.         $itk_component(scrCanvas) yview moveto 1
  413.         }
  414.         default {
  415.         error "bad justify argument \"$direction\": should be\
  416.             left, right, top, or bottom"
  417.         }
  418.     }
  419.     }
  420. }
  421.  
  422. # ------------------------------------------------------------------
  423. # METHOD: xview index
  424. #
  425. # Adjust the view in the frame so that character position index
  426. # is displayed at the left edge of the widget.
  427. # ------------------------------------------------------------------
  428. body iwidgets::Scrolledframe::xview {args} {
  429.     return [eval $itk_component(scrCanvas) xview $args]
  430. }
  431.  
  432. # ------------------------------------------------------------------
  433. # METHOD: yview index
  434. #
  435. # Adjust the view in the frame so that character position index
  436. # is displayed at the top edge of the widget.
  437. # ------------------------------------------------------------------
  438. body iwidgets::Scrolledframe::yview {args} {
  439.     return [eval $itk_component(scrCanvas) yview $args]
  440. }
  441.  
  442. # ------------------------------------------------------------------
  443. # PRIVATE METHOD: _configureCanvas 
  444. #
  445. # Responds to configure events on the canvas widget.  When canvas 
  446. # changes size, adjust frame size.
  447. # ------------------------------------------------------------------
  448. body iwidgets::Scrolledframe::_configureCanvas {} {
  449.     set sr [$itk_component(scrCanvas) cget -scrollregion]
  450.     set srw [lindex $sr 2]
  451.     set srh [lindex $sr 3]
  452.     
  453.     $itk_component(scrFrame) configure -height $srh -width $srw
  454. }
  455.  
  456. # ------------------------------------------------------------------
  457. # PRIVATE METHOD: _configureFrame 
  458. #
  459. # Responds to configure events on the frame widget.  When the frame 
  460. # changes size, adjust scrolling region size.
  461. # ------------------------------------------------------------------
  462. body iwidgets::Scrolledframe::_configureFrame {} {
  463.     $itk_component(scrCanvas) configure \
  464.         -scrollregion [$itk_component(scrCanvas) bbox frameTag] 
  465. }
  466.  
  467. # ------------------------------------------------------------------
  468. # PRIVATE METHOD: _fillerWidth 
  469. #
  470. # Compute the width of the filler frame based on the vertical 
  471. # scrollbar width plus the margin.
  472. # ------------------------------------------------------------------
  473. body iwidgets::Scrolledframe::_fillerWidth {} {
  474.     if {$_vmode == "on"} {
  475.     return [expr [winfo reqwidth $itk_component(vSB)] + \
  476.         [winfo reqwidth $itk_component(vMargin)]]
  477.     } else {
  478.     return 1
  479.     }
  480. }
  481.  
  482. # ------------------------------------------------------------------
  483. # PROTECTED METHOD: _configureFiller 
  484. #
  485. # Set up to do an update of the filler if one is not all ready 
  486. # planned.
  487. # ------------------------------------------------------------------
  488. body iwidgets::Scrolledframe::_configureFiller {} {
  489.     if {$_reconfigPlanned == ""} {
  490.     set _reconfigPlanned [after idle [code $this _updateFiller]]
  491.     }
  492. }
  493.  
  494. # ------------------------------------------------------------------
  495. # PROTECTED METHOD: _updateFiller 
  496. #
  497. # Update the width of the filler following a configure event on 
  498. # a scrollbar or margin.
  499. # ------------------------------------------------------------------
  500. body iwidgets::Scrolledframe::_updateFiller {} {
  501.     $itk_component(filler) config -width [_fillerWidth] -height 1
  502.     set _reconfigPlanned ""
  503. }
  504.  
  505. # ------------------------------------------------------------------
  506. # PRIVATE METHOD: _horizScrollbarDisplay 
  507. #
  508. # Displays the horizontal scrollbar based on the input mode.
  509. # ------------------------------------------------------------------
  510. body iwidgets::Scrolledframe::_horizScrollbarDisplay {mode} {
  511.     switch $mode  {
  512.     on {
  513.         set _hmode on
  514.         
  515.         $itk_component(hMargin) config -width 1 -height \
  516.             [winfo pixels $itk_component(hMargin) \
  517.             $itk_option(-scrollmargin)]
  518.         
  519.         pack $itk_component(hSB) -side left -fill x -expand yes
  520.     }
  521.     
  522.     off {
  523.         set _hmode off
  524.         
  525.         pack forget $itk_component(hSB)
  526.         
  527.         $itk_component(hMargin) config -width 1 -height 1
  528.         $itk_component(filler) config -width 1 -height 1
  529.     }
  530.     
  531.     default {
  532.         error "invalid argument \"$mode\": should be on or off"
  533.     }
  534.     }
  535. }
  536.  
  537. # ------------------------------------------------------------------
  538. # PRIVATE METHOD: _vertScrollbarDisplay 
  539. #
  540. # Displays the vertical scrollbar based on the input mode.
  541. # ------------------------------------------------------------------
  542. body iwidgets::Scrolledframe::_vertScrollbarDisplay {mode} {
  543.     switch $mode  {
  544.     on {
  545.         set _vmode on
  546.         
  547.         $itk_component(vMargin) config -height 1 -width \
  548.             [winfo pixels $itk_component(vMargin) \
  549.             $itk_option(-scrollmargin)]
  550.  
  551.         pack forget $itk_component(canvasFrame)
  552.         pack forget $itk_component(vMargin)
  553.         pack $itk_component(vSB) -side right -fill y
  554.         pack $itk_component(vMargin) -side right
  555.         pack $itk_component(canvasFrame) -fill both -expand yes -side left
  556.     }
  557.     
  558.     off {
  559.         set _vmode off
  560.         
  561.         pack forget $itk_component(vSB)
  562.         
  563.         $itk_component(vMargin) config -width 1 -height 1
  564.         $itk_component(filler) config -width 1 -height 1
  565.     }
  566.     
  567.     default {
  568.         error "invalid argument \"$mode\": should be on or off"
  569.     }
  570.     }
  571. }
  572.  
  573. # ------------------------------------------------------------------
  574. # PRIVATE METHOD: _scrollFrame 
  575. #
  576. # Performs scrolling and display of scrollbars based on the total 
  577. # and maximum frame size as well as the current -vscrollmode and 
  578. # -hscrollmode settings.  Parameters are automatic scroll parameters.
  579. # ------------------------------------------------------------------
  580. body iwidgets::Scrolledframe::_scrollFrame {wid first last} {
  581.     $wid set $first $last
  582.     
  583.     if {$wid == $itk_component(vSB)} {
  584.     if {$itk_option(-vscrollmode) == "dynamic"} {
  585.         if {($first == 0) && ($last == 1)} {
  586.         if {$_vmode != "off"} {
  587.             _vertScrollbarDisplay off
  588.         }
  589.         
  590.         } else {
  591.         if {$_vmode != "on"} {
  592.             _vertScrollbarDisplay on
  593.         }
  594.         }
  595.     }
  596.     
  597.     } elseif {$wid == $itk_component(hSB)} {
  598.     if {$itk_option(-hscrollmode) == "dynamic"} {
  599.         if {($first == 0) && ($last == 1)} {
  600.         if {$_hmode != "off"} {
  601.             _horizScrollbarDisplay off
  602.         }
  603.         
  604.         } else {
  605.         if {$_hmode != "on"} {
  606.             _horizScrollbarDisplay on
  607.         }
  608.         }
  609.     }
  610.     }
  611. }
  612.