summaryrefslogtreecommitdiff
path: root/gdb/gdbtk/library/gdbtoolbar.itcl
blob: 1d3a78703a0eeb5a67ffd5f2ff3be87157146274 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# GDBToolBar
# Copyright 2000 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License (GPL) as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# ----------------------------------------------------------------------
# Implements a toolbar.
#
#   PUBLIC ATTRIBUTES:
#
#
#   METHODS:
#
#     configure ....... used to change public attributes
#
#   PRIVATE METHODS
#
#   X11 OPTION DATABASE ATTRIBUTES
#
#
# ----------------------------------------------------------------------

itcl::class GDBToolBar {
  inherit itk::Widget

  # ------------------------------------------------------------------
  #  CONSTRUCTOR - create widget
  # ------------------------------------------------------------------
  constructor {args} {

    # Make a subframe so that the menu can't accidentally conflict
    # with a name created by some subclass.
    set ButtonFrame [frame $itk_interior.t]

    pack $ButtonFrame $itk_interior -fill both -expand true

    eval itk_initialize $args
  }

  # ------------------------------------------------------------------
  #  DESTRUCTOR - destroy window containing widget
  # ------------------------------------------------------------------
  destructor {

    #destroy $this
  }

  # ------------------------------------------------------------------
  #  METHOD:  show - show the toolbar
  # ------------------------------------------------------------------
  public method show {} {

    if {[llength $button_list]} {
      eval standard_toolbar $ButtonFrame $button_list
    }
  }

  # ------------------------------------------------------------------
  #  METHOD:  set_class_state - standard method to control state by class
  # ------------------------------------------------------------------
  public method set_class_state {enable_list} {
    debug "Enable list is: $enable_list"

    foreach {type state} $enable_list {
      # debug $type
      if {[info exists button_classes($type)]} {
        set class_list $button_classes($type)
        if {[llength $class_list]} {
          # debug "$type $state \{$class_list\}"
	  foreach button $class_list {
            # debug "$type $button $state"
	    itemconfigure $button -state $state
	  }
        }
      }
    }
  }

  ####################################################################
  # Methods that deal with buttons.
  ####################################################################

  # ------------------------------------------------------------------
  #  METHOD:  add - Add something.
  #                 It can be a button a separator or a label.
  #
  #  type - what we want to add
  #  args - arguments appropriate to what is being added
  #
  # ------------------------------------------------------------------
  method add {type args} {

    switch $type {
      button {
        eval toolbar_add_button $args
      }
      label {
        eval toolbar_add_label $args
      }
      separator {
        toolbar_add_button_separator
      }
      custom {
        eval toolbar_add_custom $args
      }
      default {
        error "Invalid item type: $type"
      }
    }
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_add_button - Creates a button, and inserts
  #                      it at the end of the button list.  Call this when
  #                      the toolbar is being set up, but has not yet been
  #                      made.
  # ------------------------------------------------------------------
  private method toolbar_add_button {name class command balloon args} {
    
    lappend button_list \
            [eval _register_button 1 \$name \$class \$command \$balloon $args]
    
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_add_label - Create a label to be inserted
  #                        in the toolbar.
  # ------------------------------------------------------------------

  private method toolbar_add_label {name text balloon args} {
    set lname $ButtonFrame.$name
    set Buttons($name) $lname
    set Buttons($lname,align) $button_align
    eval label $lname -text \$text $args
    balloon register $lname $balloon
    lappend button_list $lname    
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_add_custom - Create a user defined widget
  #                   to be inserted in the toolbar.
  # ------------------------------------------------------------------

  private method toolbar_add_custom {name createCmd balloon args} {
    set wname $ButtonFrame.$name
    set Buttons($name) $wname
    set Buttons($wname,align) $button_align

    eval $createCmd $wname $args
    balloon register $wname $balloon

    lappend button_list $wname
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_add_button_separator - 
  # ------------------------------------------------------------------

  private method toolbar_add_button_separator {} {
    lappend button_list -
  }
 
  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  _register_button - Creates all the bookkeeping
  #           for a button,  without actually inserting it in the toolbar.
  #           If the button will not be immediately inserted (INS == 0),
  #           sets its bindings and appearences to the same of a
  #           standard_toolbar button.
  # ------------------------------------------------------------------
  private method _register_button {ins name class command balloon args} {
    set bname $ButtonFrame.$name
    set Buttons($name) $bname
    set Buttons($bname,align) $button_align

    eval button $bname -command \$command $args
    balloon register $bname $balloon
    foreach elem $class {
      switch $elem {
	None {}
	default { 
	  lappend button_classes($elem) $name
	}
      }
    }

   # If the button is not going to be inserted now...
   if {! $ins} {
     # This is a bit of a hack, but I need to bind the standard_toolbar bindings
     # and appearances to these externally, since I am not inserting them in 
     # the original toolbar...
     # FIXME:  Have to add a method to the libgui toolbar to do this.

     # Make sure the button acts the way we want, not the default Tk way.
     $bname configure -takefocus 0 -highlightthickness 0 \
                      -relief flat -borderwidth 1	
     set index [lsearch -exact [bindtags $bname] Button]
     bindtags $bname [lreplace [bindtags $bname] $index $index ToolbarButton]
    }

    return $bname
  }
 
  # ------------------------------------------------------------------
  #  METHOD:  create - Creates all the bookkeeping for a button,
  #           without actually inserting it in the toolbar.
  # ------------------------------------------------------------------
  method create {name class command balloon args} {

    return [eval _register_button 0 \$name \$class \$command \$balloon $args]
  }

  # ------------------------------------------------------------------
  #  METHOD:  itemconfigure - 
  # ------------------------------------------------------------------
  
  method itemconfigure {button args} {
    eval $Buttons($button) configure $args
  }

  # ------------------------------------------------------------------
  #  METHOD:  itembind - 
  # ------------------------------------------------------------------
  
  method itembind {button key cmd} {
    eval [list bind $Buttons($button) $key $cmd]
  }

  # ------------------------------------------------------------------
  #  METHOD:  itemballoon - 
  # ------------------------------------------------------------------
  
  method itemballoon {button text} {
    eval [list balloon register $Buttons($button) $text]
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_insert_button - Inserts button "name" before
  #           button "before".
  #           The toolbar must be made, and the buttons must have been
  #           created before you run this.
  # ------------------------------------------------------------------
  private method toolbar_insert_button {name before} {

    if {[string first "-" $name] == 0} {
      set name [string range $name 1 end]
      set add_sep 1
    } else {
      set add_sep 0
    }

    if {![info exists Buttons($name)] || ![info exists Buttons($before)]} {
      error "toolbar_insert_buttons called with non-existant button"
    }

    set before_col [gridCGet $Buttons($before) -column]
    set before_row [gridCGet $Buttons($before) -row]

    set slaves [grid slaves $ButtonFrame]

    set incr [expr 1 + $add_sep]
    foreach slave $slaves {
      set slave_col [gridCGet $slave -column]
      if {$slave_col >= $before_col} {
	grid configure $slave -column [expr $slave_col + $incr]
      }
    }
    if {$add_sep} {
      grid $Buttons(-$name) -column $before_col -row $before_row
    }

    # Now grid our button.  Have to put in the pady since this button
    # may not have been originally inserted by the libgui toolbar
    # proc.

    grid $Buttons($name) -column [expr $before_col + $add_sep] \
      -row $before_row -pady 2
    
  }

  # ------------------------------------------------------------------
  #  PRIVATE METHOD:  toolbar_remove_button -
  # ------------------------------------------------------------------

  private method toolbar_remove_button {name} {

    if {[string first "-" $name] == 0} {
      set name [string range $name 1 end]
      set remove_sep 1
    } else {
      set remove_sep 0
    }

    if {![info exists Buttons($name)] } {
      error "toolbar_remove_buttons called with non-existant button $name"
    }

    set name_col [gridCGet $Buttons($name) -column]
    set name_row [gridCGet $Buttons($name) -row]
    
    grid remove $Buttons($name)
    if {$remove_sep} {
      set Buttons(-$name) [grid slaves $ButtonFrame \
			     -column [expr $name_col - 1] \
			    -row $name_row]
      grid remove $Buttons(-$name)
    }

    set slaves [grid slaves $ButtonFrame -row $name_row]
    foreach slave $slaves {
      set slave_col [gridCGet $slave -column]
      if {($slave_col > $name_col)
          && ! ([info exists Buttons($slave,align)]
              && $Buttons($slave,align) == "right")} {
	grid configure $slave -column [expr $slave_col - 1 - $remove_sep]
      }
    }    
  }

  # ------------------------------------------------------------------
  #  METHOD:  toolbar_button_right_justify - 
  # ------------------------------------------------------------------
  
  method toolbar_button_right_justify {} {
    lappend button_list --
    set button_align "right"
  }

  # ------------------------------------------------------------------
  #  METHOD:  toolbar_swap_button_lists - 
  # ------------------------------------------------------------------

  method toolbar_swap_button_lists {in_list out_list} {
    # Now swap out the buttons...
    set first_out [lindex $out_list 0]
    if {[info exists Buttons($first_out)] && [grid info $Buttons($first_out)] != ""} {
      foreach button $in_list {
	toolbar_insert_button $button $first_out
      }
      foreach button $out_list {
	toolbar_remove_button $button
      }
    } elseif {[info exists Buttons($first_out)]} {
      debug "Error in swap_button_list - $first_out not gridded..."
    } else {
      debug "Button $first_out is not in button list"
    }
  }

  ####################################################################
  #
  #  PRIVATE DATA
  #
  ####################################################################

  # This is the list of buttons that are being built up
  #
  private variable button_list {}

  # This is an array of buttons names -> Tk Window names
  # and also of Tk Window names -> column position in grid
  private variable Buttons

  # This array holds the button classes.  The key is the class name,
  # and the value is the list of buttons belonging to this class.
  private variable button_classes

  # Tell if we are inserting buttons left or right justified
  private variable button_align "left"

  #The frame to contain the buttons:
  private variable ButtonFrame

  ####################################################################
  #
  #  PROTECTED DATA
  #
  ####################################################################

  # None.

  ####################################################################
  #
  #  PUBLIC DATA
  #
  ####################################################################

  # None.
}