# TABDEMO.GUI -- Test the Table widget. reset-server appInitialize tabdemo Tabdemo { *demoObjects:\ toplevel Layout panel \ panel Frame panelMenuFrame \ panelMenuFrame Layout panelMenuBar \ panelMenuBar Command newCol \ panelMenuBar Command newRow \ panelMenuBar Command newTable \ panelMenuBar Command tclShell \ panelMenuBar Command quitButton Tabdemo*background: grey *Tabdemo.geometry: +0+0 *Group.shrinkToFit: True *Command.height: 28 *Command.shadowWidth: 1 *Frame.frameWidth: 1 *Frame.innerOffset: 4 *Frame.highlightThickness: 0 *borderWidth: 0 *Scrollbar2.location: 0 0 17 17 *Scrollbar.beNiceToColormap: False *panel.width: 600 *panel.height: 350 *panel.layout: vertical { \ panelMenuFrame < +inf -inf * > \ 5 < +inf > horizontal { 5 < +inf > }\ } *panelMenuBar.layout: horizontal { \ 2 newRow 1 newCol 1 newTable 1 tclShell 2 < +inf > quitButton 2 \ } *newCol.label: New Col *newRow.label: New Row *newTable.label: New Table *tclShell.label: TclShell *quitButton.label: Quit } ; createObjects demoObjects send quitButton addCallback "send client gkey q ; deactivate unmap" # Utility procedure to test True/False strings in resources. proc true {v} {expr {$v == "true" || $v == "True" || $v == "TRUE"}} # Utility functions. proc min {a b} { expr {($a < $b) ? $a : $b} } proc max {a b} { expr {($a > $b) ? $a : $b} } # Create the Table objects in the OBM. set tabnumber 0 ;# initialize table counter proc doTable args { global tabnumber set tab [ format "tab%d" $tabnumber ] set objs [ tableBuildObjects panel $tab ] # tableSetOption $tab DefLabels no # tableSetOption $tab RowLabels no # tableSetOption $tab ColLabels no # tableSetOption $tab Tracking no # tableSetOption $tab RowScroll no # tableSetOption $tab ColScroll no # tableSetOption $tab DefaultTranslations no tableSetOption $tab RowMultiSelect no tableSetOption $tab ColMultiSelect no # tableSetOption $tab RowLabelCols 2 # tableSetOption $tab ColLabelRows 2 tableSetOption $tab Background bisque3 # Now create the new objects. appExtend $objs createObjects ${tab}Objects # Now construct a layout for the new object. set new "" set panStart "vertical \{ panelMenuFrame < +inf -inf * > 5 < -5 >" for {set i 0} {$i <= $tabnumber} {incr i} { # Send the existing table a small height so they'll ajust to # fit the new table. if {$i < $tabnumber} { send tab${i}TableFrame set height 10 } # Append a layout spec for the table. set new \ [format "%s tab%dTableFrame < +inf -inf * +inf -inf > 5 < -5 >" \ $new $i] } set panEnd "\}" set panelLayout [format "%s %s %s" $panStart $new $panEnd] # Send the panel the new layout incorporating the newly created Table. send panel set layout $panelLayout # Now create the table itself, it should appear as if by magic. tableCreate $tab 12 30 { } # Apply some default test callbacks for selection/edit events. tableAddSelectCallback $tab Row demoSelCB tableAddSelectCallback $tab Col demoSelCB tableAddSelectCallback $tab Cell demoSelCB tableAddUnSelectCallback $tab Row demoUnSelCB tableAddUnSelectCallback $tab Col demoUnSelCB tableAddUnSelectCallback $tab Cell demoUnSelCB tableAddEditCallback $tab demoEditCB # Increment the global table counter. incr tabnumber } ; send newTable addCallback doTable proc demoSelCB { name row col x y args } { print "demoSelCB: name=$name r=$row c=$col x=$x y=$y args='$args'" } proc demoUnSelCB { name row col x y args } { print "demoUnSelCB: name=$name r=$row c=$col x=$x y=$y args='$args'" } proc demoEditCB { name row col str args } { print "demoEditCB: name=$name row=$row col=$col str='$str' args='$args'" } ################################################################################ ################################################################################ # # TABLE WIDGET PROCEDURES -- This interface provides simple access to a # named instance of a Table "meta-widget". The "widget" is actually a # number of widgets (Table, Scrollbars, etc) in a common layout to provide # row/col headings, scrollable data tables, and callbacks for [gs]etting # attributes. The meta-widget is created on-the-fly with a given named # and parent object, it is the callers responsibility to adjust the layout # of the parent to incorporate the new objects. # # The Table widget itself has various quirks and non-standard implem- # entations so features such as editing cells or access to certain callbacks # are not fully implemented in the OBM and hidden here. Most of what's # needed can be handled by these procedures, however these routines may be # used to manage multiple named tables in a GUI. # # # tableBuildObjects parent tab # tableSetOption tab option value # tableAddSelectCallback tab type cbname # tableAddEditCallback tab cbname # tableDestroyObjects tab # # tableCreate tab nrows ncols data # tableSetData tab data # tableSetColumnLabels tab labels # tableSetRowLabels tab labels # # list = tableGetSelected tab type # # tableSetRowLabelsAttr tab attr value # value = tableGetRowLabelsAttr tab attr # tableSetColLabelsAttr tab attr value # value = tableGetColLabelsAttr tab attr # tableSetRowLabelAttr tab row attr value # value = tableGetRowLabelAttr tab row attr # tableSetColLabelAttr tab col attr value # value = tableGetColLabelAttr tab col attr # # attr = tableGetCelllAttr tab row col attr # tableSetCelllAttr tab row col attr value # value = tableGetRowAttr tab row attr # tableSetRowAttr tab row attr value # value = tableGetColAttr tab col attr # tableSetColAttr tab col attr value # # tableDeleteCol tab col # tableDeleteRow tab row # tableAddCol tab col width [where] # tableAddRow tab row [where] # # nrows = tableGetNrows tab # ncols = tableGetNcols tab # height = tableGetHeight tab # width = tableGetWidth tab # # See obm$widget.c for a complete list of the OBM commands available # for this widget, and procedure header comments for details about the # interface here. # ################################################################################ set tabNrows(nmname 0 set tabNcols(name) 0 set tabData(name) 0 set tabColLabs(name) 0 set tabRowHeights(name,j) 0 set tabColWidths(name,i) 0 set tabHeight(name) 0 set tabWidth(name) 0 set tabScrollSize(name,type) 0 set tabScrollPos(name,type) 0 # Meta-widget options, should be set before the tableCreate call. set tabOption(name,RowLabels) yes set tabOption(name,ColLabels) yes set tabOption(name,DefLabels) yes set tabOption(name,Tracking) yes set tabOption(name,RowScroll) yes set tabOption(name,ColScroll) yes set tabOption(name,Editable) yes set tabOption(name,RowSelect) yes set tabOption(name,ColSelect) no set tabOption(name,CellSelect) no set tabOption(name,DefaultTranslations) yes set tabOption(name,Background) grey set tabOption(name,Foreground) black set tabOption(name,HighlightColor) grey90 set tabOption(name,RowLabelCols) 1 set tabOption(name,ColLabelRows) 1 # Selection lists. set tabSelected(name,Row) {} set tabSelected(name,Col) {} set tabSelected(name,Cell) {} set tabSelectionCB(name,Row) {} set tabSelectionCB(name,Col) {} set tabSelectionCB(name,Cell) {} set tabUnSelectionCB(name,Row) {} set tabUnSelectionCB(name,Col) {} set tabUnSelectionCB(name,Cell) {} set tabEditCB(name) {} # TABLEBUILDOBJECTS -- Utility routine to build the object list for the meta- # widget. # # Usage: # tableBuildObjects proc tableBuildObjects { parent tab } { set objDef { *TABObjects: \ PARENT Frame TABTableFrame \ TABTableFrame Layout TABFrameLayout \ TABFrameLayout Layout TABTableLayout \ TABTableLayout Viewport TABTabView \ TABTabView Table TABTab \ TABTableLayout Label TABSpacer \ TABTableLayout Viewport TABRowTabView \ TABRowTabView Table TABRowTab \ TABTableLayout Viewport TABColTabView \ TABColTabView Table TABColTab \ TABFrameLayout Label TABLabel \ TABFrameLayout Scrollbar TABColScroll \ TABFrameLayout Scrollbar TABRowScroll \ \ toplevel TopLevelShell TABEditShell \ TABEditShell Layout TABEditLayout \ TABEditLayout Frame TABEditMenuFrame\ TABEditMenuFrame Layout TABEditMenuBar \ TABEditMenuBar Command TABEditApply \ TABEditMenuBar Command TABEditClear \ TABEditMenuBar Command TABEditCancel \ TABEditLayout Frame TABEditFrame \ TABEditFrame AsciiText TABEditText \ ! Global Table widget resources. *Table.literalWidth: 20 *Table.rowHeight: 20 *Table.shadowWidth: 1 *Table.labelShadowWidth: 1 *Table.tableMargin: 0 *Table.columnMargin: 0 *Table.rowMargin: 0 *Table.internalHeight: 1 *Table.internalWidth: 1 *TABTableFrame*Group.shrinkToFit: True *TABTableFrame*Command.height: 28 *TABTableFrame*Command.shadowWidth: 1 *TABTableFrame*Frame.frameWidth: 1 *TABTableFrame*Frame.innerOffset: 4 *TABTableFrame*Frame.highlightThickness: 0 *TABTableFrame*Frame.borderWidth: 0 *TABTableFrame*Frame.shrinkToFit: True *TABTableFrame*Table.borderWidth: 1 *TABTableFrame*Scrollbar.beNiceToColormap: False *TABTableFrame.height: 10 *TABTableFrame.width: 10 *TABTableFrame*Layout.height: 10 *TABTableFrame*Layout.width: 10 *TABTableFrame*Label.height: 15 *TABTableFrame*Label.label: *TABFrameLayout.TABTableLayout.height: 10 *TABFrameLayout.TABTableLayout.width: 10 *TABFrameLayout.TABTableLayout*Layout.height: 10 *TABFrameLayout.TABTableLayout*Layout.width: 10 *TABFrameLayout.TABTableLayout*Viewport.height: 20 *TABFrameLayout.TABTableLayout*Viewport.width: 20 *TABFrameLayout.TABTableLayout*Table.height: 20 *TABFrameLayout.TABTableLayout*Table.width: 20 ! The following resources enable the scrollbars on the Viewport ! widget but effectively hide them from display. This allows us ! to control the viewport manually from the Table code, e.g. to ! scroll both the column headings and data table. *TABFrameLayout.TABTableLayout*Viewport.allowVert: True *TABFrameLayout.TABTableLayout*Viewport.allowHoriz: True *TABFrameLayout.TABTableLayout*Viewport.forceBars: True *TABFrameLayout.TABTableLayout*Viewport.useBottom: True *TABFrameLayout.TABTableLayout*Viewport.useRight: True *TABFrameLayout.TABTableLayout*Viewport.borderWidth: 1 *TABTableLayout*TABRowTabView*vertical.thickness: 1 *TABTableLayout*TABRowTabView*horizontal.thickness: 1 *TABTableLayout*TABColTabView*vertical.thickness: 1 *TABTableLayout*TABColTabView*horizontal.thickness: 1 *TABTableLayout*TABTabView*vertical.thickness: 1 *TABTableLayout*TABTabView*horizontal.thickness: 1 *TABTableFrame.TABFrameLayout.TABRowScroll.thickness: 15 *TABTableFrame.TABFrameLayout.TABRowScroll.width: 15 *TABTableFrame.TABFrameLayout.TABRowScroll.height: 15 *TABTableFrame.TABFrameLayout.TABRowScroll.orientation: Vertical *TABTableFrame.TABFrameLayout.TABColScroll.thickness: 15 *TABTableFrame.TABFrameLayout.TABColScroll.width: 15 *TABTableFrame.TABFrameLayout.TABColScroll.height: 15 *TABTableFrame.TABFrameLayout.TABColScroll.orientation: Horizontal *TABFrameLayout.layout: horizontal { \ vertical { \ 2 < -2 > \ TABTableLayout < +inf -inf * +inf -inf > \ 2 < -2 > \ horizontal { \ TABLabel 1 < -1 > TABColScroll < +inf -inf * > \ } \ } \ vertical { \ 27 < -27 > TABRowScroll < * +inf -inf > 20 < -20 > \ } \ } *TABTableFrame.TABFrameLayout.TABLabel.label: ( 0, 0) *TABTableFrame.TABFrameLayout.TABLabel.width: 80 *TABTableLayout.layout: horizontal { \ vertical { \ TABSpacer 1 < -1 > TABRowTabView < * +inf -inf > \ } \ 3 < -3 > \ vertical { \ TABColTabView < +inf -inf * > \ 3 < -3 > \ TABTabView < +inf -inf * +inf -inf > \ } \ 3 < -3 > \ } *TABSpacer.height: 24 !---------------------------+ ! Set the editor resources. | !---------------------------+ *TABEditShell.title: Table Value Editor *TABEditShell.width: 275 *TABEditShell.height: 80 *TABEditLayout*borderWidth: 0 *TABEditLayout.layout: vertical { \ TABEditFrame < +inf -inf * +inf -inf > \ -2 \ TABEditMenuFrame < +inf -inf * > \ -2 \ } *TABEditMenuBar.layout: horizontal { \ TABEditApply 5 \ 10 < +inf -inf > \ TABEditClear 5 \ 10 < +inf -inf > \ TABEditCancel 5 \ } *TABEditMenuFrame.height: 80 *TABEditMenuFrame.outerOffset: 0 *TABEditMenuFrame.innerOffset: 5 *TABEditMenuFrame.frameType: chiseled *TABEditMenuFrame.frameWidth: 2 *TABEditFrame.frameType: sunken *TABEditFrame.frameWidth: 2 *TABEditFrame.outerOffset: 5 *TABEditText*scrollVertical: never *TABEditText*scrollHorizontal: whenNeeded *TABEditText*font: 7x13 *TABEditText*editType: edit *TABEditApply.label: Apply *TABEditApply.width: 150 *TABEditClear.label: Clear *TABEditClear.width: 150 *TABEditCancel.label: Cancel *TABEditCancel.width: 150 } regsub -all TAB $objDef $tab tmp1 regsub -all PARENT $tmp1 $parent objs set objs [format "{ %s }" $objs] return $objs } # TABLEDESTROYOBJECTS -- Destroy the specified table and all it's objects. # # Usage: # tableDestroyObjects proc tableDestroyObjects { tab } { destroyObject ${tab}TableFrame } # TABESETOPTION -- Set an option for the Table meta-widget. # # Usage: # tableSetOption