home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / notebook.itk < prev    next >
Text File  |  2003-09-01  |  31KB  |  947 lines

  1. #
  2. # Notebook Widget
  3. # ----------------------------------------------------------------------
  4. # The Notebook command creates a new window (given by the pathName 
  5. # argument) and makes it into a Notebook widget. Additional options, 
  6. # described above may be specified on the command line or in the 
  7. # option database to configure aspects of the Notebook such as its 
  8. # colors, font, and text. The Notebook command returns its pathName 
  9. # argument. At the time this command is invoked, there must not exist 
  10. # a window named pathName, but path Name's parent must exist.
  11. # A Notebook is a widget that contains a set of pages. It displays one 
  12. # page from the set as the selected page. When a page is selected, the 
  13. # page's contents are displayed in the page area. When first created a 
  14. # Notebook has no pages. Pages may be added or deleted using widget commands 
  15. # described below.
  16. # A special option may be provided to the Notebook. The -auto option 
  17. # specifies whether the Nptebook will automatically handle the unpacking 
  18. # and packing of pages when pages are selected. A value of true signifies 
  19. # that the notebook will automatically manage it. This is the default 
  20. # value. A value of false signifies the notebook will not perform automatic 
  21. # switching of pages.
  22. #
  23. # WISH LIST:
  24. #   This section lists possible future enhancements.
  25. #
  26. # ----------------------------------------------------------------------
  27. #  AUTHOR: Bill W. Scott                 EMAIL: bscott@spd.dsccc.com
  28. #
  29. #  @(#) $Id: notebook.itk,v 1.4 2001/08/15 18:33:31 smithc Exp $
  30. # ----------------------------------------------------------------------
  31. #            Copyright (c) 1995 DSC Technologies Corporation
  32. # ======================================================================
  33. # Permission to use, copy, modify, distribute and license this software 
  34. # and its documentation for any purpose, and without fee or written 
  35. # agreement with DSC, is hereby granted, provided that the above copyright 
  36. # notice appears in all copies and that both the copyright notice and 
  37. # warranty disclaimer below appear in supporting documentation, and that 
  38. # the names of DSC Technologies Corporation or DSC Communications 
  39. # Corporation not be used in advertising or publicity pertaining to the 
  40. # software without specific, written prior permission.
  41. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  42. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  43. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  44. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  45. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  46. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  47. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  48. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  49. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  50. # SOFTWARE.
  51. # ======================================================================
  52.  
  53. #
  54. # Default resources.
  55. #
  56. option add *Notebook.background          #d9d9d9      widgetDefault
  57. option add *Notebook.auto                true         widgetDefault
  58.  
  59. #
  60. # Usual options.
  61. #
  62. itk::usual Notebook {
  63.     keep -background -cursor
  64. }
  65.  
  66. # ------------------------------------------------------------------
  67. #                            NOTEBOOK
  68. # ------------------------------------------------------------------
  69. itcl::class iwidgets::Notebook {
  70.     inherit itk::Widget
  71.     
  72.     constructor {args} {}
  73.     
  74.     itk_option define -background background Background #d9d9d9 
  75.     itk_option define -auto auto Auto true 
  76.     itk_option define -scrollcommand scrollCommand ScrollCommand {}
  77.     
  78.     public method add { args }
  79.     public method childsite { args }
  80.     public method delete { args } 
  81.     public method index { args } 
  82.     public method insert { args } 
  83.     public method prev { } 
  84.     public method next { } 
  85.     public method pageconfigure { args } 
  86.     public method pagecget { index option }
  87.     public method select { index } 
  88.     public method view { args } 
  89.     
  90.     private method _childSites { } 
  91.     private method _scrollCommand { } 
  92.     private method _index { pathList index select} 
  93.     private method _createPage { args } 
  94.     private method _deletePages { fromPage toPage } 
  95.     private method _configurePages { args } 
  96.     private method _tabCommand { } 
  97.     
  98.     private variable _currPage -1  ;# numerical index of current page selected
  99.     private variable _pages {}     ;# list of Page components
  100.     private variable _uniqueID 0   ;# one-up number for unique page numbering
  101.     
  102. }
  103.  
  104. #
  105. # Provide a lowercase access method for the Notebook class
  106. #
  107. proc ::iwidgets::notebook {pathName args} {
  108.     uplevel ::iwidgets::Notebook $pathName $args
  109. }
  110.  
  111. # ------------------------------------------------------------------
  112. #                      CONSTRUCTOR
  113. # ------------------------------------------------------------------
  114. itcl::body iwidgets::Notebook::constructor {args}  {
  115.     #
  116.     # Create the outermost frame to maintain geometry.
  117.     #
  118.     itk_component add cs {
  119.     frame $itk_interior.cs 
  120.     } {
  121.     keep -cursor -background -width -height
  122.     }
  123.     pack $itk_component(cs) -fill both -expand yes
  124.     pack propagate $itk_component(cs) no
  125.     
  126.     eval itk_initialize $args
  127.     
  128.     # force bg of all pages to reflect Notebook's background.
  129.     _configurePages -background $itk_option(-background)
  130. }
  131.  
  132. # ------------------------------------------------------------------
  133. #                      OPTIONS
  134. # ------------------------------------------------------------------
  135. # ------------------------------------------------------------------
  136. # OPTION -background
  137. #
  138. # Sets the bg color of all the pages in the Notebook.
  139. # ------------------------------------------------------------------
  140. itcl::configbody iwidgets::Notebook::background {
  141.     if {$itk_option(-background) != {}} {
  142.     _configurePages -background $itk_option(-background)
  143.     }
  144. }
  145.  
  146. # ------------------------------------------------------------------
  147. # OPTION -auto
  148. #
  149. # Determines whether pages are automatically unpacked and
  150. # packed when pages get selected.
  151. # ------------------------------------------------------------------
  152. itcl::configbody iwidgets::Notebook::auto {
  153.     if {$itk_option(-auto) != {}} {
  154.     }
  155. }
  156.  
  157. # ------------------------------------------------------------------
  158. # OPTION -scrollcommand
  159. #
  160. # Command string to be invoked when the notebook 
  161. # has any changes to its current page, or number of pages.
  162. # typically for scrollbars.
  163. # ------------------------------------------------------------------
  164. itcl::configbody iwidgets::Notebook::scrollcommand {
  165.     if {$itk_option(-scrollcommand) != {}} {
  166.     _scrollCommand
  167.     }
  168. }
  169.  
  170. # ------------------------------------------------------------------
  171. # METHOD: add add ?<option> <value>...?
  172. # Creates a page and appends it to the list of pages.
  173. # processes pageconfigure for the page added.
  174. # ------------------------------------------------------------------
  175. itcl::body iwidgets::Notebook::add { args } {
  176.     # The args list should be an even # of params, if not then
  177.     # prob missing value for last item in args list. Signal error.
  178.     set len [llength $args]
  179.     if {$len % 2} {
  180.     error "value for \"[lindex $args [expr {$len - 1}]]\" missing"
  181.     }
  182.     
  183.     # add a Page component
  184.     set pathName [eval _createPage $args]
  185.     lappend _pages $pathName
  186.     
  187.     # update scroller
  188.     _scrollCommand 
  189.     
  190.     # return childsite for the Page component
  191.     return [eval $pathName childsite]
  192. }
  193.  
  194. # ------------------------------------------------------------------
  195. # METHOD: childsite ?<index>?
  196. #
  197. # If index is supplied, returns the child site widget corresponding 
  198. # to the page index.  If called with no arguments, returns a list 
  199. # of all child sites
  200. # ------------------------------------------------------------------
  201. itcl::body iwidgets::Notebook::childsite { args } {
  202.     set len [llength $args]
  203.     
  204.     switch $len {
  205.     0 {
  206.         # ... called with no arguments, return a list
  207.         if { [llength $args] == 0 } {
  208.         return [_childSites]
  209.         }
  210.     }
  211.     1 {
  212.         set index [lindex $args 0]
  213.         # ... otherwise, return child site for the index given
  214.         # empty notebook
  215.         if { $_pages == {} } {
  216.         error "can't get childsite,\
  217.             no pages in the notebook \"$itk_component(hull)\""
  218.         }
  219.         
  220.         set index [_index $_pages $index $_currPage]
  221.         
  222.         # index out of range
  223.         if { $index < 0 || $index >= [llength $_pages] } {
  224.         error "bad Notebook page index in childsite method:\
  225.             should be between 0 and [expr {[llength $_pages] - 1}]"
  226.         }
  227.         
  228.         set pathName [lindex $_pages $index]
  229.         
  230.         set cs [eval $pathName childsite]
  231.         return $cs
  232.     }
  233.     default {
  234.         # ... too many parameters passed
  235.         error "wrong # args: should be\
  236.             \"$itk_component(hull) childsite ?index?\""
  237.     }
  238.     }
  239. }
  240.  
  241. # ------------------------------------------------------------------
  242. # METHOD: delete <index1> ?<index2>?
  243. # Deletes a page or range of pages from the notebook
  244. # ------------------------------------------------------------------
  245. itcl::body iwidgets::Notebook::delete { args } {
  246.     # empty notebook
  247.     if { $_pages == {} } {
  248.     error "can't delete page, no pages in the notebook\
  249.         \"$itk_component(hull)\""
  250.     }
  251.     
  252.     set len [llength $args]
  253.     switch -- $len {
  254.     1 {
  255.         set fromPage [_index $_pages [lindex $args 0] $_currPage]
  256.         
  257.         if { $fromPage < 0 || $fromPage >= [llength $_pages] } {
  258.         error "bad Notebook page index in delete method:\
  259.             should be between 0 and [expr {[llength $_pages] - 1}]"
  260.         }
  261.         
  262.         set toPage $fromPage
  263.         _deletePages $fromPage $toPage
  264.     }
  265.     
  266.     2 {
  267.         set fromPage [_index $_pages [lindex $args 0] $_currPage]
  268.         
  269.         if { $fromPage < 0 || $fromPage >= [llength $_pages] } {
  270.         error "bad Notebook page index1 in delete method:\
  271.             should be between 0 and [expr {[llength $_pages] - 1}]"
  272.         }
  273.         
  274.         set toPage [_index $_pages [lindex $args 1] $_currPage]
  275.         
  276.         if { $toPage < 0 || $toPage >= [llength $_pages] } {
  277.         error "bad Notebook page index2 in delete method:\
  278.             should be between 0 and [expr {[llength $_pages] - 1}]"
  279.         error "bad Notebook page index2"
  280.         }
  281.         
  282.         if { $fromPage > $toPage } {
  283.         error "bad Notebook page index1 in delete method:\
  284.             index1 is greater than index2"
  285.         }
  286.         
  287.         _deletePages $fromPage $toPage
  288.         
  289.     }
  290.     
  291.     default {
  292.         # ... too few/many parameters passed
  293.         error "wrong # args: should be\
  294.             \"$itk_component(hull) delete index1 ?index2?\""
  295.     }
  296.     }
  297. }
  298.  
  299. # ------------------------------------------------------------------
  300. # METHOD: index <index>
  301. #
  302. # Given an index identifier returns the numeric index of the page
  303. # ------------------------------------------------------------------
  304. itcl::body iwidgets::Notebook::index { args } {
  305.     if { [llength $args] != 1 } {
  306.     error "wrong # args: should be\
  307.         \"$itk_component(hull) index index\""
  308.     }
  309.     
  310.     set index $args
  311.     
  312.     set number [_index $_pages $index $_currPage]
  313.     
  314.     return $number
  315. }
  316.  
  317. # ------------------------------------------------------------------
  318. # METHOD: insert <index> ?<option> <value>...?
  319. #
  320. # Inserts a page before a index. The before page may
  321. # be specified as a label or a page position. 
  322. # ------------------------------------------------------------------
  323. itcl::body iwidgets::Notebook::insert { args } {
  324.     # ... Error: no args passed
  325.     set len [llength $args]
  326.     if { $len == 0 } {
  327.     error "wrong # args: should be\
  328.         \"$itk_component(hull) insert index ?option value?\""
  329.     }
  330.     
  331.     # ... set up index and args 
  332.     set index [lindex $args 0]
  333.     set args [lrange $args 1 $len]
  334.     
  335.     # ... Error: unmatched option value pair (len is odd)
  336.     # The args list should be an even # of params, if not then
  337.     # prob missing value for last item in args list. Signal error.
  338.     set len [llength $args]
  339.     if { $len % 2 } {
  340.     error "value for \"[lindex $args [expr {$len - 1}]]\" missing"
  341.     }
  342.     
  343.     # ... Error: catch notebook empty
  344.     if { $_pages == {} } {
  345.     error "can't insert page, no pages in the notebook\
  346.         \"$itk_component(hull)\""
  347.     }
  348.     
  349.     # ok, get the page
  350.     set page [_index $_pages $index $_currPage]
  351.     
  352.     # ... Error: catch bad value for before page.
  353.     if { $page < 0 || $page >= [llength $_pages] } {
  354.     error "bad Notebook page index in insert method:\
  355.         should be between 0 and [expr {[llength $_pages] - 1}]"
  356.     }
  357.     
  358.     # ... Start the business of inserting
  359.     # create the new page and get its path name...
  360.     set pathName [eval _createPage $args]
  361.     
  362.     # grab the name of the page currently selected. (to keep in sync)
  363.     set currPathName [lindex $_pages $_currPage]
  364.     
  365.     # insert pathName before $page
  366.     set _pages [linsert $_pages $page $pathName]
  367.     
  368.     # keep the _currPage in sync with the insert.
  369.     set _currPage [lsearch -exact $_pages $currPathName]
  370.     
  371.     # give scrollcommand chance to update
  372.     _scrollCommand 
  373.     
  374.     # give them child site back...
  375.     return [eval $pathName childsite]
  376. }
  377.  
  378. # ------------------------------------------------------------------
  379. # METHOD: prev
  380. #
  381. # Selects the previous page. Wraps at first back to last page.
  382. # ------------------------------------------------------------------
  383. itcl::body iwidgets::Notebook::prev { } {
  384.     # catch empty notebook
  385.     if { $_pages == {} } {
  386.     error "can't move to previous page,\
  387.         no pages in the notebook \"$itk_component(hull)\""
  388.     }
  389.     
  390.     # bump to the previous page and wrap if necessary
  391.     set prev [expr {$_currPage - 1}]
  392.     if { $prev < 0 } {
  393.     set prev [expr {[llength $_pages] - 1}]
  394.     }
  395.     
  396.     select $prev
  397.     
  398.     return $prev
  399. }
  400.  
  401. # ------------------------------------------------------------------
  402. # METHOD: next
  403. #
  404. # Selects the next page. Wraps at last back to first page.
  405. # ------------------------------------------------------------------
  406. itcl::body iwidgets::Notebook::next { } {
  407.     # catch empty notebook
  408.     if { $_pages == {} } {
  409.     error "can't move to next page,\
  410.         no pages in the notebook \"$itk_component(hull)\""
  411.     }
  412.     
  413.     # bump to the next page and wrap if necessary
  414.     set next [expr {$_currPage + 1}]
  415.     if { $next >= [llength $_pages] } {
  416.     set next 0
  417.     }
  418.     
  419.     select $next
  420.     
  421.     return $next
  422. }
  423.  
  424. # ------------------------------------------------------------------
  425. # METHOD: pageconfigure <index> ?<option> <value>...?
  426. #
  427. # Performs configure on a given page denoted by index.  Index may 
  428. # be a page number or a pattern matching the label associated with 
  429. # a page.
  430. # ------------------------------------------------------------------
  431. itcl::body iwidgets::Notebook::pageconfigure { args } {
  432.     # ... Error: no args passed
  433.     set len [llength $args]
  434.     if { $len == 0 } {
  435.     error "wrong # args: should be\
  436.         \"$itk_component(hull) pageconfigure index ?option value?\""
  437.     }
  438.     
  439.     # ... set up index and args 
  440.     set index [lindex $args 0]
  441.     set args [lrange $args 1 $len]
  442.     
  443.     set page [_index $_pages $index $_currPage]
  444.     
  445.     # ... Error: page out of range
  446.     if { $page < 0 || $page >= [llength $_pages] } {
  447.     error "bad Notebook page index in pageconfigure method:\
  448.         should be between 0 and [expr {[llength $_pages] - 1}]"
  449.     }
  450.     
  451.     # Configure the page component
  452.     set pathName [lindex $_pages $page]
  453.     return [eval $pathName configure $args]
  454. }
  455.  
  456. # ------------------------------------------------------------------
  457. # METHOD: pagecget <index> <option>
  458. #
  459. # Performs cget on a given page denoted by index.  Index may 
  460. # be a page number or a pattern matching the label associated with 
  461. # a page.
  462. # ------------------------------------------------------------------
  463. itcl::body iwidgets::Notebook::pagecget { index option } {
  464.     set page [_index $_pages $index $_currPage]
  465.     
  466.     # ... Error: page out of range
  467.     if { $page < 0 || $page >= [llength $_pages] } {
  468.     error "bad Notebook page index in pagecget method:\
  469.         should be between 0 and [expr {[llength $_pages] - 1}]"
  470.     }
  471.     
  472.     # Get the page info.
  473.     set pathName [lindex $_pages $page]
  474.     return [$pathName cget $option]
  475. }
  476.  
  477. # ------------------------------------------------------------------
  478. # METHOD: select <index>
  479. #
  480. # Select a page by index.  Hide the last _currPage if it existed.
  481. # Then show the new one if it exists.  Returns the currently 
  482. # selected page or -1 if tried to do a select select when there is 
  483. # no selection.
  484. # ------------------------------------------------------------------
  485. itcl::body iwidgets::Notebook::select { index } {
  486.     global page$itk_component(hull)
  487.     
  488.     # ... Error: empty notebook
  489.     if { $_pages == {} } {
  490.     error "can't select page $index,\
  491.         no pages in the notebook \"$itk_component(hull)\""
  492.     }
  493.     
  494.     # if there is not current selection just ignore trying this selection
  495.     if { $index == "select" && $_currPage == -1 } {
  496.     return -1
  497.     }
  498.     
  499.     set reqPage [_index $_pages $index $_currPage]
  500.     
  501.     if { $reqPage < 0 || $reqPage >= [llength $_pages] } {
  502.     error "bad Notebook page index in select method:\
  503.         should be between 0 and [expr {[llength $_pages] - 1}]"
  504.     }
  505.     
  506.     # if we already have this page selected, then ignore selection.
  507.     if { $reqPage == $_currPage } {
  508.     return $_currPage
  509.     }
  510.     
  511.     # if we are handling packing and unpacking the unpack if we can
  512.     if { $itk_option(-auto) } {
  513.     # if there is a current page packed, then unpack it
  514.     if { $_currPage != -1 } {
  515.         set currPathName [lindex $_pages $_currPage]
  516.         pack forget $currPathName
  517.     }
  518.     }
  519.     
  520.     # set this now so that the -command cmd can do an 'index select'
  521.     # to operate on this page.
  522.     set _currPage $reqPage
  523.     
  524.     # invoke the command for this page
  525.     set cmd [lindex [pageconfigure $index -command] 4]
  526.     eval $cmd
  527.     
  528.     # give scrollcommand chance to update
  529.     _scrollCommand 
  530.     
  531.     # if we are handling packing and unpacking the pack if we can
  532.     if { $itk_option(-auto) } {
  533.     set reqPathName [lindex $_pages $reqPage]
  534.     pack $reqPathName -anchor nw -fill both -expand yes
  535.     }
  536.     
  537.     return $_currPage
  538. }
  539.  
  540.  
  541. # ------------------------------------------------------------------
  542. # METHOD: view
  543. #
  544. # Return the current page
  545. #
  546. #      view <index>
  547. #
  548. # Selects the page denoted by index to be current page
  549. #
  550. #         view 'moveto' <fraction>
  551. #
  552. # Selects the page by using fraction amount
  553. #
  554. #      view 'scroll' <num> <what>
  555. #
  556. # Selects the page by using num as indicator of next or    previous
  557. # ------------------------------------------------------------------
  558. itcl::body iwidgets::Notebook::view { args } {
  559.     set len [llength $args]
  560.     switch -- $len {
  561.     0 {
  562.         # Return current page
  563.         return $_currPage
  564.     }
  565.     1 {
  566.         # Select by index
  567.         select [lindex $args 0]
  568.     }
  569.     2 {
  570.         # Select using moveto
  571.         set arg [lindex $args 0]
  572.         if { $arg == "moveto" } {
  573.         set fraction [lindex $args 1]
  574.         if { [catch { set page \
  575.             [expr {round($fraction/(1.0/[llength $_pages]))}]}]} {
  576.             error "expected floating-point number \
  577.                 but got \"$fraction\""
  578.         }
  579.         if { $page == [llength $_pages] } {
  580.             incr page -1
  581.         }
  582.         
  583.         if { $page >= 0 && $page < [llength $_pages] } {
  584.             select $page
  585.         }
  586.         } else {
  587.         error "expected \"moveto\" but got $arg"
  588.         }
  589.     }
  590.     3 {
  591.         # Select using scroll keyword
  592.         set arg [lindex $args 0]
  593.         if { $arg == "scroll" } {
  594.         set amount [lindex $args 1]
  595.         # check for integer value
  596.         if { ! [regexp {^[-]*[0-9]*$} $amount] } {
  597.             error "expected integer but got \"$amount\""
  598.         }
  599.         set page [expr {$_currPage + $amount}]
  600.         if { $page >= 0 && $page < [llength $_pages] } {
  601.             select $page
  602.         }
  603.         
  604.         } else {
  605.         error "expected \"scroll\" but got $arg"
  606.         }
  607.     }
  608.     default {
  609.         set arg [lindex $args 0]
  610.         if { $arg == "moveto" } {
  611.         error "wrong # args: should be\
  612.             \"$itk_component(hull) view moveto fraction\""
  613.         } elseif { $arg == "scroll" } {
  614.         error "wrong # args: should be\
  615.             \"$itk_component(hull) view scroll units|pages\""
  616.         } else {
  617.         error "wrong # args: should be\
  618.             \"$itk_component(hull) view index\""
  619.         }
  620.     }
  621.     }
  622. }
  623.  
  624. # ------------------------------------------------------------------
  625. # PRIVATE METHOD: _childSites
  626. #
  627. # Returns a list of child sites for all pages in the notebook.
  628. # ------------------------------------------------------------------
  629. itcl::body iwidgets::Notebook::_childSites { } {
  630.     # empty notebook
  631.     if { $_pages == {} } {
  632.     error "can't get childsite list,\
  633.         no pages in the notebook \"$itk_component(hull)\""
  634.     }
  635.     
  636.     set csList {}
  637.     
  638.     foreach pathName $_pages { 
  639.     lappend csList [eval $pathName childsite]
  640.     }
  641.     
  642.     return $csList
  643. }
  644.  
  645. # ------------------------------------------------------------------
  646. # PRIVATE METHOD: _scrollCommand
  647. #
  648. # If there is a -scrollcommand set up, then call the tcl command
  649. # and suffix onto it the standard 4 numbers scrollbars get.
  650. #
  651. # Invoke the scrollcommand, this is like the y/xscrollcommand
  652. # it is designed to talk to scrollbars and the the
  653. # tabset also knows how to obey scrollbar protocol.
  654. # ------------------------------------------------------------------
  655. itcl::body iwidgets::Notebook::_scrollCommand { } {
  656.     if { $itk_option(-scrollcommand) != {} } {
  657.         if  { $_currPage != -1 }  {
  658.         set relTop [expr {($_currPage*1.0) / [llength $_pages]}]
  659.         set relBottom [expr {(($_currPage+1)*1.0) / [llength $_pages]}]
  660.         set scrollCommand "$itk_option(-scrollcommand) $relTop $relBottom"
  661.     } else {
  662.         set scrollCommand "$itk_option(-scrollcommand) 0 1"
  663.     }
  664.     uplevel #0 $scrollCommand
  665.     }
  666. }
  667.  
  668. # ------------------------------------------------------------------
  669. # PRIVATE METHOD: _index
  670. #
  671. # pathList : list of path names to search thru if index is a label
  672. # index    : either number, 'select', 'end', or pattern
  673. # select   : current selection
  674. #
  675. # _index takes takes the value $index converts it to
  676. # a numeric identifier. If the value is not already
  677. # an integer it looks it up in the $pathList array.
  678. # If it fails it returns -1
  679. # ------------------------------------------------------------------
  680. itcl::body iwidgets::Notebook::_index { pathList index select} {
  681.     switch -- $index {
  682.     select {
  683.         set number $select
  684.     }
  685.     end {
  686.         set number [expr {[llength $pathList] -1}]
  687.     }
  688.     default {
  689.         # is it a number already?
  690.         if { [regexp {^[0-9]+$} $index] } {
  691.         set number $index
  692.         if { $number < 0 || $number >= [llength $pathList] } {
  693.             set number -1
  694.         }
  695.         
  696.         # otherwise it is a label
  697.         } else {
  698.         # look thru the pathList of pathNames and 
  699.         # get each label and compare with index.
  700.         # if we get a match then set number to postion in $pathList
  701.         # and break out.
  702.         # otherwise number is still -1
  703.         set i 0
  704.         set number -1
  705.         foreach pathName $pathList {
  706.             set label [lindex [$pathName configure -label] 4]
  707.             if { [string match $label $index] } {
  708.             set number $i
  709.             break
  710.             }
  711.             incr i
  712.         }
  713.         }
  714.     }
  715.     }
  716.     
  717.     return $number
  718. }
  719.  
  720. # ------------------------------------------------------------------
  721. # PRIVATE METHOD: _createPage
  722. #
  723. # Creates a page, using unique page naming, propagates background
  724. # and keeps unique id up to date.
  725. # ------------------------------------------------------------------
  726. itcl::body iwidgets::Notebook::_createPage { args } {
  727.     #
  728.     # create an internal name for the page: .n.cs.page0, .n.cs.page1, etc.
  729.     #
  730.     set pathName $itk_component(cs).page$_uniqueID
  731.     
  732.     eval iwidgets::Page $pathName -background $itk_option(-background) $args
  733.     
  734.     incr _uniqueID
  735.     return $pathName
  736.     
  737. }
  738.  
  739. # ------------------------------------------------------------------
  740. # PRIVATE METHOD: _deletePages
  741. #
  742. # Deletes pages from $fromPage to $toPage.
  743. #
  744. # Operates in two passes, destroys all the widgets
  745. # Then removes the pathName from the page list
  746. #
  747. # Also keeps the current selection in bounds.
  748. # ------------------------------------------------------------------
  749. itcl::body iwidgets::Notebook::_deletePages { fromPage toPage } {
  750.     for { set page $fromPage } { $page <= $toPage } { incr page } {
  751.     # kill the widget
  752.     set pathName [lindex $_pages $page]
  753.     destroy $pathName
  754.     }
  755.     
  756.     # physically remove the page
  757.     set _pages [lreplace $_pages $fromPage $toPage]
  758.     
  759.     # If we deleted a selected page set our selection to none
  760.     if { $_currPage >= $fromPage && $_currPage <= $toPage } {
  761.     set _currPage -1
  762.     }
  763.     
  764.     # make sure _currPage stays in sync with new numbering...
  765.     if { $_pages == {} } {
  766.     # if deleted only remaining page,
  767.     # reset current page to undefined
  768.     set _currPage -1
  769.     
  770.     # or if the current page was the last page, it needs come back
  771.     } elseif { $_currPage >= [llength $_pages] } {
  772.     incr _currPage -1
  773.     if { $_currPage < 0 } {
  774.         # but only to zero
  775.         set _currPage 0
  776.     }
  777.     }
  778.     
  779.     # give scrollcommand chance to update
  780.     _scrollCommand 
  781. }
  782.  
  783. # ------------------------------------------------------------------
  784. # PRIVATE METHOD: _configurePages
  785. #
  786. # Does the pageconfigure method on each page in the notebook
  787. # ------------------------------------------------------------------
  788. itcl::body iwidgets::Notebook::_configurePages { args } {
  789.     # make sure we have pages
  790.     if { [catch {set _pages}] } {
  791.     return
  792.     }
  793.     
  794.     # go thru all pages and pageconfigure them.
  795.     foreach pathName $_pages {
  796.     eval "$pathName configure $args"
  797.     }
  798. }
  799.  
  800. # ------------------------------------------------------------------
  801. # PRIVATE METHOD: _tabCommand
  802. #
  803. # Calls the command that was passed in through the 
  804. # $itk_option(-tabcommand) argument.
  805. #
  806. # This method is up for debate... do we need the -tabcommand option?
  807. # ------------------------------------------------------------------
  808. itcl::body iwidgets::Notebook::_tabCommand { } {
  809.     global page$itk_component(hull)
  810.     
  811.     if { $itk_option(-tabcommand) != {} } {
  812.     set newTabCmdStr $itk_option(-tabcommand)
  813.     lappend newTabCmdStr [set page$itk_component(hull)]
  814.     
  815.     #eval $newTabCmdStr
  816.     uplevel #0 $newTabCmdStr
  817.     }
  818. }
  819.     
  820. #
  821. # Page widget
  822. # ------------------------------------------------------------------
  823. #
  824. # The Page command creates a new window (given by the pathName argument) 
  825. # and makes it into a Page widget. Additional options, described above 
  826. # may be specified on the com mand line or in the option database to 
  827. # configure aspects of the Page such as its back ground, cursor, and 
  828. # geometry. The Page command returns its pathName argument. At the time 
  829. # this command is invoked, there must not exist a window named pathName, 
  830. # but path Name's parent must exist.
  831. # A Page is a frame that holds a child site. It is nothing more than a 
  832. # frame widget with some intelligence built in. Its primary purpose is 
  833. # to support the Notebook's concept of a page. It allows another widget 
  834. # like the Notebook to treat a page as a single object. The Page has an 
  835. # associated label and knows how to return its child site.
  836. #
  837. # ------------------------------------------------------------------
  838. #  AUTHOR: Bill W. Scott                 EMAIL: bscott@spd.dsccc.com
  839. #
  840. # ------------------------------------------------------------------
  841. #               Copyright (c) 1995  DSC Communications Corp.
  842. # ======================================================================
  843. # Permission is hereby granted, without written agreement and without
  844. # license or royalty fees, to use, copy, modify, and distribute this
  845. # software and its documentation for any purpose, provided that the
  846. # above copyright notice and the following two paragraphs appear in
  847. # all copies of this software.
  848. #
  849. # IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  850. # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  851. # ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  852. # IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  853. # DAMAGE.
  854. #
  855. # THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  856. # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  857. # FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  858. # ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  859. # PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  860. # ======================================================================
  861. #
  862. # Option database default resources:
  863. #
  864. option add *Page.disabledForeground #a3a3a3     widgetDefault
  865. option add *Page.label              {}       widgetDefault
  866. option add *Page.command            {}       widgetDefault
  867.  
  868. itcl::class iwidgets::Page {
  869.     inherit itk::Widget
  870.     
  871.     constructor {args} {}
  872.     
  873.     itk_option define \
  874.         -disabledforeground disabledForeground DisabledForeground #a3a3a3 
  875.     itk_option define -label label Label {} 
  876.     itk_option define -command command Command {}
  877.     
  878.     public method childsite { } 
  879. }
  880.  
  881. # ------------------------------------------------------------------
  882. #                          CONSTRUCTOR
  883. # ------------------------------------------------------------------
  884. itcl::body iwidgets::Page::constructor {args} {
  885.     #
  886.     # Create the outermost frame to maintain geometry.
  887.     #
  888.     itk_component add cs {
  889.     frame $itk_interior.cs 
  890.     } {
  891.     keep -cursor -background -width -height
  892.     }
  893.     pack $itk_component(cs) -fill both -expand yes 
  894.     pack propagate $itk_component(cs) no
  895.     
  896.     eval itk_initialize $args
  897. }
  898.  
  899. # ------------------------------------------------------------------
  900. #                            OPTIONS
  901. # ------------------------------------------------------------------
  902. # ------------------------------------------------------------------
  903. # OPTION -disabledforeground
  904. #
  905. # Sets the disabledForeground color of this page
  906. # ------------------------------------------------------------------
  907. itcl::configbody iwidgets::Page::disabledforeground {
  908. }
  909.  
  910. # ------------------------------------------------------------------
  911. # OPTION -label
  912. #
  913. # Sets the label of this page.  The label is a string identifier 
  914. # for this page.
  915. # ------------------------------------------------------------------
  916. itcl::configbody iwidgets::Page::label {
  917. }
  918.  
  919. # ------------------------------------------------------------------
  920. # OPTION -command
  921. #
  922. # The Tcl Command to associate with this page.
  923. # ------------------------------------------------------------------
  924. itcl::configbody iwidgets::Page::command {
  925. }
  926.  
  927. # ------------------------------------------------------------------
  928. #                            METHODS
  929. # ------------------------------------------------------------------
  930.  
  931. # ------------------------------------------------------------------
  932. # METHOD: childsite
  933. #
  934. # Returns the child site widget of this page
  935. # ------------------------------------------------------------------
  936. itcl::body iwidgets::Page::childsite { } {
  937.     return $itk_component(cs)
  938. }
  939.  
  940.