source: tol/tolbase/lib/mkWidgets1.3/Toolbar.tcl @ 3ed16ee

1941-docker-image-to-testdevel
Last change on this file since 3ed16ee was 32535cc, checked in by Jorge Pérez <josp.jorge@…>, 18 years ago

adding more types to config, added mkWidget1.3

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@16 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 12.3 KB
Line 
1package require Metawidget
2
3# name: Toolbar
4# args: args: option-value pairs
5# creates inner widgets and bindings. initializes variables.
6metawidget create Toolbar {
7  # padding of 2 pixel between outer frame and the buttons
8  pack [frame $this.frm -border 2 -relief flat] -side top -fill both -expand 1
9
10  # popup menu for right mouse key
11  menu $this.menu -tearoff 0
12  $this.menu add command -label Top    -command "$this config -side top"
13  $this.menu add command -label Bottom -command "$this config -side bottom"
14  $this.menu add command -label Left   -command "$this config -side left"
15  $this.menu add command -label Right  -command "$this config -side right"
16
17  # this is for X11 only. it's a noop on Windows and Mac
18  bind $this.menu <FocusOut> "$this.menu unpost"
19
20  # new class bindings make Toolbar draggable
21  bind Toolbar$this <1>         "$this _click"
22  bind Toolbar$this <B1-Motion> "$this _drag %X %Y"
23  bind Toolbar$this <3>         "$this.menu post %X %Y; focus $this.menu"
24
25  # buttons get a nice roll-over effect
26  bind Toolbutton$this <Enter> {%W config -relief raised}
27  bind Toolbutton$this <Leave> {%W config -relief flat}
28
29  my wParent [winfo parent $this]
30
31  # set options by calling their member functions
32  -side top
33  -state normal
34} {} -default frm -border 1 -relief raised
35
36# name: _click
37# args: -
38# called when clicked. stores the coordinates of the parent window.
39metawidget proc Toolbar _click {} {
40  my iX1 [expr [winfo rootx [my wParent]]+20]
41  my iY1 [expr [winfo rooty [my wParent]]+20]
42  my iX2 [expr [my iX1]+[winfo width  [my wParent]]-40]
43  my iY2 [expr [my iY1]+[winfo height [my wParent]]-40]
44}
45
46# name: _drag
47# args: iPx, iPy: mouse coordinates
48# called when dragged. detects if the mouse is outside of any of the four
49# sides of the parent window and places the Toolbar accordingly.
50metawidget proc Toolbar _drag { iPx iPy } {
51  if { $iPx < [my iX1] && [my -side] != "left" } {
52    -side left
53  } elseif { $iPx > [my iX2] && [my -side] != "right" } {
54    -side right
55  } elseif { $iPy < [my iY1] && [my -side] != "top" } {
56    -side top
57  } elseif { $iPy > [my iY2] && [my -side] != "bottom" } {
58    -side bottom
59  }
60}
61
62# name: _checkItem
63# args: sTag: item tag
64# throws an exception if the given tag does not exists. tests on
65# existence of a private variable.
66metawidget proc Toolbar _checkItem { sTag } {
67  if { ! [myinfo exists _$sTag.wWidget] } {
68    error "Toolbar $this: Item $sTag does not exist."
69  }
70}
71
72# name: _redraw
73# args: -
74# redraws the Toolbar. computes the values for the -fill and -side options
75# and the first child of the parent. packs the Toolbar before that child.
76metawidget proc Toolbar _redraw {} {
77  set sFill  [mkw.decode [my -side] "top x bottom x left y right y"]
78  set sInner [mkw.decode [my -side] "top left bottom left left top right top"]
79  set sFirst [lindex [pack slaves [my wParent]] 0]
80
81  # pack Toolbar *before* first child (if any)
82  if { $sFirst == {} } {
83    pack $this -side [my -side] -fill $sFill
84  } elseif { [lsearch [bindtags $sFirst] "Statusbar"] != -1 } {
85    pack $this -side [my -side] -fill $sFill -after $sFirst
86  } else {
87    pack $this -side [my -side] -fill $sFill -before $sFirst
88  }
89
90  # pack the buttons inside the Toolbar.
91  foreach sWidget [winfo children $this.frm] {
92    if { [winfo class $sWidget] == "Frame" } {
93      # special treatment for separator frames
94      if { $sFill == "x" } {
95        pack $sWidget -side $sInner -fill y -padx 4 -pady 1
96      } else {
97        pack $sWidget -side $sInner -fill x -padx 1 -pady 4
98      }
99    } else {
100      # all other buttons
101      pack $sWidget -side $sInner -fill both
102    }
103  }
104}
105
106# name: _bindTag
107# args: sWhat: operation (extend or shrink)
108#       wWidget: widget to modify
109#       sBindTag: bindtag to add or remove
110# adds or removes a bindtag to a widget.
111metawidget proc Toolbar _bindTag { sWhat wWidget sBindTag } {
112  bindtags $wWidget [mkw.l$sWhat [bindtags $wWidget] $sBindTag]
113}
114
115# name: _checkButton
116# args: sTag: item tag
117#       iState: optional new state (boolean)
118# handles checkbuttons. makes them look "checked" (=sunken) respectively
119# normal again.
120metawidget proc Toolbar _checkButton { sTag {iState {}} } {
121  # either toggle state or set new state from iState
122  if { $iState == {} } {
123    my _$sTag.iState [expr ! [my _$sTag.iState]]
124  } else {
125    my _$sTag.iState [mkw.complete $iState {on off yes no 1 0}]
126  }
127
128  # change relief and add resp. remove bind tag for roll-over effect
129  if { [my _$sTag.iState] } {
130    [my _$sTag.wWidget] config -relief sunken
131    _bindTag shrink [my _$sTag.wWidget] Toolbutton$this
132  } else {
133    [my _$sTag.wWidget] config -relief flat
134    _bindTag extend [my _$sTag.wWidget] Toolbutton$this
135  }
136}
137
138# name: _radioButton
139# args: sTag: item tag
140# handles radiobuttons. sets all buttons of a group to normal state and
141# then makes the clicked one look checked.
142metawidget proc Toolbar _radioButton { sTag } {
143  set wButton $this.frm._$sTag
144
145  # reset all radiobuttons of the group
146  foreach sGroupTag [my __[my _$sTag.sGroup]] {
147    $this.frm._$sGroupTag config -relief flat
148    _bindTag extend $this.frm._$sGroupTag Toolbutton$this
149  }
150
151  # then check the activated button
152  [my _$sTag.wWidget] config -relief sunken
153  _bindTag shrink [my _$sTag.wWidget] Toolbutton$this
154}
155
156# name: -side
157# args: sSide: side to place Toolbar on
158# option member. repositions the Toolbar.
159metawidget proc Toolbar -side { sSide } {
160  my -side [mkw.complete $sSide {top bottom left right}]
161  _redraw
162}
163
164# name: -state
165# args: sState: new state for the Toolbar
166# option member. lets a Toolbar disappear or disables dragging.
167metawidget proc Toolbar -state { sState } {
168  my -state [mkw.complete $sState {normal fixed withdrawn}]
169
170  switch [my -state] {
171    normal {
172      _bindTag extend $this.frm Toolbar$this
173      -side [my -side]
174    }
175    fixed {
176      _bindTag shrink $this.frm Toolbar$this
177      -side [my -side]
178    }
179    withdrawn {
180      pack forget $this
181    }
182  }
183}
184
185# name: add
186# args: sType: type of new object
187#       sTag: unique item tag
188#       args: option-value pairs
189# adds a new button, checkbutton, radiobutton or separator.
190metawidget proc Toolbar add { sType sTag args } {
191  if { [myinfo exists _$sTag.wWidget] } {
192    error "Toolbar $this: Item $sTag already exists."
193  }
194
195  set sType   [mkw.complete $sType {button checkbutton radiobutton separator}]
196  set wWidget $this.frm._$sTag
197
198  # store item attributes in private variables
199  my _$sTag.sTag    $sTag
200  my _$sTag.sType   $sType
201  my _$sTag.wWidget $wWidget
202  my _$sTag.iState  0
203
204  if { $sType == "separator" } {
205    frame $wWidget -border 1 -relief sunken -width 2 -height 2
206    _bindTag extend $wWidget Toolbar$this
207  } else {
208    button $wWidget -border 1 -relief flat -padx 0 -pady 0 -takefocus 0
209    _bindTag extend $wWidget Toolbutton$this
210
211    if { $sType == "checkbutton" } {
212      bind $wWidget <1> "$this _checkButton $sTag"
213    } elseif { $sType == "radiobutton" } {
214      bind $wWidget <1> "$this _radioButton $sTag"
215
216      # extract -group option and append it to a list
217      set args [mkw.options $args * {-group *}]
218      if { ! [info exists -group] } {
219        set -group default
220      }
221
222      my _$sTag.sGroup ${-group}
223      if { [myinfo exists __${-group}] } {
224        my __${-group} [linsert [my __${-group}] end $sTag]
225      } else {
226        my __${-group} $sTag
227      }
228    }
229  }
230
231  eval itemconf {$sTag} $args
232
233  if { [my -state] != "withdrawn" } {
234    _redraw
235  }
236
237  return $wWidget
238}
239
240# name: delete
241# args: args: list of item tags
242# deletes Toolbar objects.
243metawidget proc Toolbar delete { args } {
244  foreach sTag $args {
245    if { [my _$sTag.sType] == "radiobutton" } {
246      my __[my _$sTag.sGroup] [mkw.lshrink [my __[my _$sTag.sGroup]] $sTag]
247    }
248
249    destroy [my _$sTag.wWidget]
250    unmy _$sTag.sTag _$sTag.sType _$sTag.wWidget _$sTag.iState _$sTag.sGroup
251  }
252
253  _redraw
254}
255
256# name: itemconf
257# args: sTag: item tag
258#       args: option-value pairs
259# configures a Toolbar object.
260metawidget proc Toolbar itemconf { sTag args } {
261  _checkItem $sTag
262  eval {$this.frm._$sTag} config $args
263}
264
265# name: itemcget
266# args: sTag: item tag
267#       sOption: option to query
268# returns an option value of a Toolbar object.
269metawidget proc Toolbar itemcget { sTag sOption } {
270  _checkItem $sTag
271  $this.frm._$sTag cget $sOption
272}
273
274# name: set
275# args: sTag: item tag
276#       iState: new state for checkbuttons
277# similar to invoke, but the button's command is not invoked,
278# just the toolbutton is set.
279metawidget proc Toolbar set_ { sTag {iState {}} } {
280  _checkItem $sTag
281
282  if { [my _$sTag.sType] == "checkbutton" } {
283    _checkButton $sTag $iState
284  } elseif { [my _$sTag.sType] == "radiobutton" } {
285    _radioButton $sTag
286  }
287}
288
289# name: get
290# args: sTag: item tag
291# returns the state of a button. always 0 for regular buttons.
292# 0 or 1 for check- and radiobuttons.
293metawidget proc Toolbar get { sTag } {
294  _checkItem $sTag
295  return [my _$sTag.iState]
296}
297
298# name: invoke
299# args: sTag: item tag
300#       iState: new state for checkbuttons
301# invokes a button. if iState is specified, it sets a checkbutton to the
302# corresponding value. does not apply for buttons and radiobuttons, since
303# there state is always known.
304metawidget proc Toolbar invoke { sTag {iState {}} } {
305  _checkItem $sTag
306  set_ $sTag $iState
307  $this.frm._$sTag invoke
308}
309
310# name: menu
311# args: args: arguments for the regular menu command.
312# simply passes all arguments to the popup menu.
313metawidget proc Toolbar menu_ { args } {
314  eval $this.menu $args
315}
316
317# name: names
318# args: -
319# returns the tags of all toolbar buttons
320metawidget proc Toolbar names { {sPattern *} } {
321  set lTags {}
322
323  foreach sVar [myinfo vars _*.sTag] {
324    if { ! [string match $sPattern [my $sVar]] } continue
325    lappend lTags [my $sVar]
326  }
327
328  return $lTags
329}
330
331metawidget command Toolbar _click       _click
332metawidget command Toolbar _drag        _drag
333metawidget command Toolbar _checkButton _checkButton
334metawidget command Toolbar _radioButton _radioButton
335
336metawidget command Toolbar add          add
337metawidget command Toolbar delete       delete
338metawidget command Toolbar itemconf     itemconf
339metawidget command Toolbar itemcget     itemcget
340metawidget command Toolbar set          set_
341metawidget command Toolbar get          get
342metawidget command Toolbar invoke       invoke
343metawidget command Toolbar menu         menu_
344metawidget command Toolbar names        names
345
346metawidget option Toolbar -side  -side
347metawidget option Toolbar -state -state
348
349proc test {} {
350  wm minsize . 320 250
351
352  image create photo p1 -file ./demos/images/Notebook.gif
353  image create photo p2 -file ./demos/images/Compass.gif
354
355  pack [frame .work -bg gray50] -fill both -expand 1
356  grid [frame .test] -in .work
357
358  pack [text .test.text -width 40 -height 10 -wrap word]
359  toolbar .test.tbar -state fixed -side bottom -relief sunken
360  .test.text insert end "Above are regular buttons, checkbuttons and radiobuttons."
361  .test.text insert end "The Toolbars can be dragged to the four window sides."
362  .test.text insert end "The right mouse button will invoke a menu.\n"
363
364  .test.tbar add button b1 -image p1 -command {.test.text delete 1.0 end }
365  .test.tbar add check  b2 -image p2 -command {
366    if { [.test.tbar get b2] } {
367      .test.text config -bg black -fg white
368    } else {
369      .test.text config -bg white -fg black
370    }
371  }
372
373  toolbar .tbar1
374  .tbar1 add button button1 -image p2 -command {.test.text insert end "button1 clicked\n"; .test.text see end }
375  .tbar1 add button button2 -image p2 -command {.test.text insert end "button2 clicked\n"; .test.text see end }
376  .tbar1 add separator s1
377  .tbar1 add checkbutton check1 -image p1 -command {.test.text insert end "check1 clicked\n"; .test.text see end }
378  .tbar1 add checkbutton check2 -image p1 -command {.test.text insert end "check2 clicked\n"; .test.text see end }
379  .tbar1 add separator s2
380  .tbar1 add radiobutton radio1 -image p1 -command {.test.text insert end "radio1 clicked\n"; .test.text see end }
381  .tbar1 add radiobutton radio2 -image p2 -command {.test.text insert end "radio2 clicked\n"; .test.text see end }
382  .tbar1 add radiobutton radio3 -image p1 -command {.test.text insert end "radio3 clicked\n"; .test.text see end }
383  .tbar1 add radiobutton radio4 -image p2 -command {.test.text insert end "radio4 clicked\n"; .test.text see end }
384
385  toolbar .t2 -side bottom
386  .t2 add button b1 -image p1 -bg red
387  .t2 add button b2 -image p2 -bg green
388  .t2 add button b3 -image p1 -bg yellow
389  .t2 add button b4 -image p2 -bg blue
390  .t2 add button b5 -image p1 -bg white
391  .t2 add button b6 -image p2 -bg black
392}
393
394#test
395
Note: See TracBrowser for help on using the repository browser.