OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tix/] [library/] [PanedWin.tcl] - Blame information for rev 1782

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
# PanedWin.tcl --
2
#
3
#       This file implements the TixPanedWindow widget
4
#
5
# Copyright (c) 1996, Expert Interface Technologies
6
#
7
# See the file "license.terms" for information on usage and redistribution
8
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9
#
10
 
11
 
12
tixWidgetClass tixPanedWindow {
13
    -classname TixPanedWindow
14
    -superclass tixPrimitive
15
    -method {
16
        add delete forget manage panecget paneconfigure panes setsize
17
    }
18
    -flag {
19
        -command -dynamicgeometry -handleactivebg -handlebg -orient
20
        -orientation -panebd -paneborderwidth -panerelief
21
        -separatoractivebg -separatorbg
22
    }
23
    -static {
24
        -orientation
25
    }
26
    -configspec {
27
        {-command command Command ""}
28
        {-dynamicgeometry dynamicGeometry DynamicGeometry 1 tixVerifyBoolean}
29
        {-handleactivebg handleActiveBg HandleActiveBg #ececec}
30
        {-handlebg handleBg Background #d9d9d9}
31
        {-orientation orientation Orientation vertical}
32
        {-paneborderwidth paneBorderWidth PaneBorderWidth 1}
33
        {-panerelief paneRelief PaneRelief raised}
34
        {-separatoractivebg separatorActiveBg SeparatorActiveBg red}
35
        {-separatorbg separatorBg Background #d9d9d9}
36
    }
37
    -alias {
38
        {-panebd -paneborderwidth}
39
        {-orient -orientation}
40
    }
41
}
42
 
43
#----------------------------------------------------------------------
44
# ClassInitialization:
45
#----------------------------------------------------------------------
46
 
47
proc tixPanedWindow:InitWidgetRec {w} {
48
    upvar #0 $w data
49
 
50
    tixChainMethod $w InitWidgetRec
51
 
52
    set data(items)       ""
53
    set data(nItems)      0
54
    set data(totalsize)   0
55
    set data(movePending) 0
56
 
57
    set data(repack)      0
58
    set data(counter)     0
59
 
60
    set data(maxReqW)     1
61
    set data(maxReqH)     1
62
}
63
 
64
proc tixPanedWindow:ConstructWidget {w} {
65
    upvar #0 $w data
66
 
67
    tixChainMethod $w ConstructWidget
68
    # Do nothing
69
}
70
 
71
proc tixPanedWindow:SetBindings {w} {
72
    upvar #0 $w data
73
 
74
    tixChainMethod $w SetBindings
75
 
76
    bind $w <Configure> [list tixPanedWindow:MasterGeomProc $w ""]
77
}
78
 
79
#----------------------------------------------------------------------
80
# ConfigOptions:
81
#----------------------------------------------------------------------
82
proc tixPanedWindow:config-handlebg {w arg} {
83
    upvar #0 $w data
84
 
85
    for {set i 1} {$i < $data(nItems)} {incr i} {
86
        $data(btn,$i) config -bg $arg
87
    }
88
}
89
 
90
#----------------------------------------------------------------------
91
# PublicMethods:
92
#----------------------------------------------------------------------
93
 
94
 
95
# method: add
96
#
97
#    Adds a new pane into the PanedWindow.
98
#
99
# options -size -max -min -allowresize
100
#
101
proc tixPanedWindow:add {w name args} {
102
    upvar #0 $w data
103
 
104
    if {[winfo exists $w.$name] && !$data($name,forgotten)} {
105
        error "Pane $name is already managed"
106
    }
107
    # Step 1: Parse the options to get the children's size options
108
 
109
    # The default values
110
    #
111
    if [info exists data($name,forgotten)] {
112
        set option(-size)        $data($name,size)
113
        set option(-min)         $data($name,min)
114
        set option(-max)         $data($name,max)
115
        set option(-allowresize) $data($name,allowresize)
116
        set option(-expand)      $data($name,expand)
117
    } else {
118
        set option(-size)        0
119
        set option(-min)         0
120
        set option(-max)         100000
121
        set option(-allowresize) 1
122
        set option(-expand)      0
123
    }
124
 
125
    set option(-before)      ""
126
    set option(-after)       ""
127
    set option(-at)          ""
128
    set validOpts {-after -allowresize -at -before -expand -max -min -size}
129
 
130
    tixHandleOptions option $validOpts $args
131
 
132
    set data($name,size)        $option(-size)
133
    set data($name,rsize)       $option(-size)
134
    set data($name,min)         $option(-min)
135
    set data($name,max)         $option(-max)
136
    set data($name,allowresize) $option(-allowresize)
137
    set data($name,expand)      $option(-expand)
138
    set data($name,forgotten)   0
139
 
140
    if {$data($name,expand) < 0} {
141
        set data($name,expand) 0
142
    }
143
 
144
    # Step 2: Add the frame and the separator (if necessary)
145
    #
146
    if {![winfo exist $w.$name]} {
147
        # need to check because the frame may have been "forget'ten"
148
        #
149
        frame $w.$name -bd $data(-paneborderwidth) -relief $data(-panerelief)
150
    }
151
 
152
    if {$option(-at) != ""} {
153
        set at [tixGetInt $option(-at)]
154
        if {$at < 0} {
155
            set at 0
156
        }
157
    } elseif {$option(-after) != ""} {
158
        set index [lsearch -exact $data(items) $option(-after)]
159
        if {$index == -1} {
160
            error "Pane $option(-after) doesn't exists"
161
        } else {
162
            set at [incr index]
163
        }
164
    } elseif {$option(-before) != ""} {
165
        set index [lsearch -exact $data(items) $option(-before)]
166
        if {$index == -1} {
167
            error "Pane $option(-before) doesn't exists"
168
        }
169
        set at $index
170
    } else {
171
        set at end
172
    }
173
 
174
    set data(items) [linsert $data(items) $at $name]
175
    incr data(nItems)
176
 
177
    if {$data(nItems) > 1} {
178
        tixPanedWindow:AddSeparator $w
179
    }
180
    set data(w:$name) $w.$name
181
 
182
    # Step 3: Add the new frame. Adjust the window later (do when idle)
183
    #
184
    tixManageGeometry $w.$name "tixPanedWindow:ClientGeomProc $w"
185
    bind $w.$name <Configure> \
186
        [list tixPanedWindow:ClientGeomProc $w "" $w.$name]
187
 
188
    tixPanedWindow:RepackWhenIdle $w
189
 
190
    return $w.$name
191
}
192
 
193
proc tixPanedWindow:manage {w name args} {
194
    upvar #0 $w data
195
 
196
    if {![winfo exists $w.$name]} {
197
        error "Pane $name does not exist"
198
    }
199
    if {!$data($name,forgotten)} {
200
        error "Pane $name is already managed"
201
    }
202
    tixMapWindow $data(w:$name)
203
    eval tixPanedWindow:add $w [list $name] $args
204
}
205
 
206
proc tixPanedWindow:forget {w name} {
207
    upvar #0 $w data
208
 
209
    if {![winfo exists $w.$name]} {
210
        error "Pane $name does not exist"
211
    }
212
    if $data($name,forgotten) {
213
        # It has already been forgotten
214
        #
215
        return
216
    }
217
 
218
    set items ""
219
    foreach item $data(items) {
220
        if {$item != $name} {
221
            lappend items $item
222
        }
223
    }
224
    set data(items) $items
225
    incr data(nItems) -1
226
 
227
    set i $data(nItems)
228
    if {$i > 0} {
229
        destroy $data(btn,$i)
230
        destroy $data(sep,$i)
231
        unset data(btn,$i)
232
        unset data(sep,$i)
233
    }
234
    set data($name,forgotten) 1
235
 
236
    tixUnmapWindow $w.$name
237
 
238
    tixPanedWindow:RepackWhenIdle $w
239
}
240
 
241
proc tixPanedWindow:delete {w name} {
242
    upvar #0 $w data
243
 
244
    if {![winfo exists $w.$name]} {
245
        error "Pane $name does not exist"
246
    }
247
 
248
 
249
    if {!$data($name,forgotten)} {
250
        set items ""
251
        foreach item $data(items) {
252
            if {$item != $name} {
253
                lappend items $item
254
            }
255
        }
256
        set data(items) $items
257
        incr data(nItems) -1
258
 
259
        set i $data(nItems)
260
        if {$i > 0} {
261
            destroy $data(btn,$i)
262
            destroy $data(sep,$i)
263
            unset data(btn,$i)
264
            unset data(sep,$i)
265
        }
266
    }
267
    unset data($name,allowresize)
268
    unset data($name,expand)
269
    unset data($name,forgotten)
270
    unset data($name,max)
271
    unset data($name,min)
272
    unset data($name,rsize)
273
    unset data($name,size)
274
    unset data(w:$name)
275
    destroy $w.$name
276
 
277
    tixPanedWindow:RepackWhenIdle $w
278
}
279
 
280
proc tixPanedWindow:paneconfigure {w name args} {
281
    upvar #0 $w data
282
 
283
    if {![info exists data($name,size)]} {
284
        error "pane \"$name\" does not exist in $w"
285
    }
286
 
287
    set len [llength $args]
288
 
289
    if {$len == 0} {
290
        set value [$data(w:$name) configure]
291
        lappend value [list -allowresize "" "" "" $data($name,allowresize)]
292
        lappend value [list -expand "" "" "" $data($name,expand)]
293
        lappend value [list -max "" "" "" $data($name,max)]
294
        lappend value [list -min "" "" "" $data($name,min)]
295
        lappend value [list -size "" "" "" $data($name,size)]
296
        return $value
297
    }
298
 
299
    if {$len == 1} {
300
        case [lindex $args 0] {
301
            -allowresize {
302
                return [list -allowresize "" "" "" $data($name,allowresize)]
303
            }
304
            -expand {
305
                return [list -expand "" "" "" $data($name,expand)]
306
            }
307
            -min {
308
                return [list -min "" "" "" $data($name,min)]
309
            }
310
            -max {
311
                return [list -max "" "" "" $data($name,max)]
312
            }
313
            -size {
314
                return [list -size "" "" "" $data($name,size)]
315
            }
316
            default {
317
                return [$data(w:$name) configure [lindex $args 0]]
318
            }
319
        }
320
    }
321
 
322
    # By default handle each of the options
323
    #
324
    set option(-allowresize) $data($name,allowresize)
325
    set option(-expand)      $data($name,expand)
326
    set option(-min)         $data($name,min)
327
    set option(-max)         $data($name,max)
328
    set option(-size)        $data($name,size)
329
 
330
    tixHandleOptions -nounknown option {-allowresize -expand -max -min -size} \
331
        $args
332
 
333
    #
334
    # the widget options
335
    set new_args ""
336
    tixForEach {flag value} $args {
337
        case $flag {
338
            {-expand -min -max -allowresize -size} {
339
 
340
            }
341
            default {
342
                lappend new_args $flag
343
                lappend new_args $value
344
            }
345
        }
346
    }
347
 
348
    if {[llength $new_args] >= 2} {
349
        eval $data(w:$name) configure $new_args
350
    }
351
 
352
    #
353
    # The add-on options
354
    set data($name,allowresize) $option(-allowresize)
355
    set data($name,expand)      $option(-expand)
356
    set data($name,max)         $option(-max)
357
    set data($name,min)         $option(-min)
358
    set data($name,rsize)       $option(-size)
359
    set data($name,size)        $option(-size)
360
 
361
    # 
362
    # Integrity check
363
    if {$data($name,expand) < 0} {
364
        set data($name,expand) 0
365
    }
366
    if {$data($name,size) < $data($name,min)} {
367
        set data($name,size) $data($name,min)
368
    }
369
    if {$data($name,size) > $data($name,max)} {
370
        set data($name,size) $data($name,max)
371
    }
372
 
373
    tixPanedWindow:RepackWhenIdle $w
374
    return ""
375
}
376
 
377
proc tixPanedWindow:panecget {w name option} {
378
    upvar #0 $w data
379
 
380
    if {![info exists data($name,size)]} {
381
        error "pane \"$name\" does not exist in $w"
382
    }
383
 
384
    case $option {
385
        {-min -max -allowresize -size} {
386
            regsub \\\- $option "" option
387
            return "$data($name,$option)"
388
        }
389
        default {
390
            return [$data(w:$name) cget $option]
391
        }
392
    }
393
}
394
 
395
# return the name of all panes
396
proc tixPanedWindow:panes {w} {
397
    upvar #0 $w data
398
 
399
    return $data(items)
400
}
401
 
402
# set the size of a pane, specifying which direction it should
403
# grow/shrink
404
proc tixPanedWindow:setsize {w item size {direction next}} {
405
    upvar #0 $w data
406
 
407
    set posn [lsearch $data(items) $item]
408
    if {$posn == -1} {
409
        error "pane \"$item\" does not exist"
410
    }
411
 
412
    set diff [expr $size - $data($item,size)]
413
    if {$diff == 0} {
414
        return
415
    }
416
 
417
    if {$posn == 0 && $direction == "prev"} {
418
        set direction next
419
    }
420
    if {$posn == [expr $data(nItems)-1] && $direction == "next"} {
421
        set direction prev
422
    }
423
 
424
    if {$data(-orientation) == "vertical"} {
425
        set rx [winfo rooty $data(w:$item)]
426
    } else {
427
        set rx [winfo rootx $data(w:$item)]
428
    }
429
    if {$direction == "prev"} {
430
        set rx [expr $rx - $diff]
431
    } elseif {$data(-orientation) == "vertical"} {
432
        set rx [expr $rx + [winfo height $data(w:$item)] + $diff]
433
        incr posn
434
    } else {
435
        set rx [expr $rx + [winfo width $data(w:$item)] + $diff]
436
        incr posn
437
    }
438
 
439
    # Set up the panedwin in a proper state
440
    #
441
    tixPanedWindow:BtnDown $w $posn 1
442
    tixPanedWindow:BtnMove $w $posn $rx 1
443
    tixPanedWindow:BtnUp $w $posn 1
444
 
445
    return $data(items)
446
}
447
 
448
#----------------------------------------------------------------------
449
# PrivateMethods:
450
#----------------------------------------------------------------------
451
 
452
proc tixPanedWindow:AddSeparator {w} {
453
    global tcl_platform
454
 
455
    upvar #0 $w data
456
 
457
    set n [expr $data(nItems)-1]
458
 
459
    # CYGNUS LOCAL: On Windows, use relief ridge and a thicker line.
460
    if {$tcl_platform(platform) == "windows"} then {
461
      set relief "ridge"
462
      set thickness 4
463
    } else {
464
      set relief "sunken"
465
      set thickness 2
466
    }
467
    if {$data(-orientation) == "vertical"} {
468
        set data(sep,$n) [frame $w.sep$n -relief $relief \
469
            -bd 1 -height $thickness -width 10000 -bg $data(-separatorbg)]
470
    } else {
471
        set data(sep,$n) [frame $w.sep$n -relief $relief \
472
            -bd 1 -width $thickness -height 10000 -bg $data(-separatorbg)]
473
    }
474
 
475
    set data(btn,$n) [frame $w.btn$n -relief raised \
476
        -bd 1 -width 9 -height 9 \
477
        -bg $data(-handlebg)]
478
 
479
    if {$data(-orientation) == "vertical"} {
480
        set cursor sb_v_double_arrow
481
    } else {
482
        set cursor sb_h_double_arrow
483
    }
484
    $data(sep,$n) config -cursor $cursor
485
    $data(btn,$n) config -cursor $cursor
486
 
487
    foreach wid "$data(btn,$n) $data(sep,$n)" {
488
        bind $wid \
489
            <ButtonPress-1>   "tixPanedWindow:BtnDown $w $n"
490
        bind $wid \
491
            <ButtonRelease-1> "tixPanedWindow:BtnUp   $w $n"
492
        bind $wid \
493
            <Any-Enter>       "tixPanedWindow:HighlightBtn $w $n"
494
        bind $wid \
495
            <Any-Leave>       "tixPanedWindow:DeHighlightBtn $w $n"
496
    }
497
 
498
    if {$data(-orientation) == "vertical"} {
499
        bind  $data(btn,$n) <B1-Motion> \
500
            "tixPanedWindow:BtnMove $w $n %Y"
501
    } else {
502
        bind  $data(btn,$n) <B1-Motion> \
503
            "tixPanedWindow:BtnMove $w $n %X"
504
    }
505
 
506
    if {$data(-orientation) == "vertical"} {
507
#       place $data(btn,$n) -relx 0.90 -y [expr "$data(totalsize)-5"]
508
#       place $data(sep,$n) -x 0 -y [expr "$data(totalsize)-1"] -relwidth 1
509
    } else {
510
#       place $data(btn,$n) -rely 0.90 -x [expr "$data(totalsize)-5"]
511
#       place $data(sep,$n) -y 0 -x [expr "$data(totalsize)-1"] -relheight 1
512
    }
513
}
514
 
515
proc tixPanedWindow:BtnDown {w item {fake 0}} {
516
    upvar #0 $w data
517
 
518
    if {$data(-orientation) == "vertical"} {
519
        set spec -height
520
    } else {
521
        set spec -width
522
    }
523
 
524
    if {!$fake} {
525
        for {set i 1} {$i < $data(nItems)} {incr i} {
526
            $data(sep,$i) config -bg $data(-separatoractivebg) $spec 1
527
        }
528
        update idletasks
529
        $data(btn,$item) config -relief sunken
530
    }
531
 
532
    tixPanedWindow:GetMotionLimit $w $item $fake
533
 
534
    if {!$fake} {
535
        grab -global $data(btn,$item)
536
    }
537
    set data(movePending) 0
538
}
539
 
540
proc tixPanedWindow:Min2 {a b} {
541
    if {$a < $b} {
542
        return $a
543
    } else {
544
        return $b
545
    }
546
}
547
 
548
proc tixPanedWindow:GetMotionLimit {w item fake} {
549
    upvar #0 $w data
550
 
551
    set curBefore 0
552
    set minBefore 0
553
    set maxBefore 0
554
 
555
    for {set i 0} {$i < $item} {incr i} {
556
        set name [lindex $data(items) $i]
557
        incr curBefore $data($name,size)
558
        incr minBefore $data($name,min)
559
        incr maxBefore $data($name,max)
560
    }
561
 
562
    set curAfter 0
563
    set minAfter 0
564
    set maxAfter 0
565
    while {$i < $data(nItems)} {
566
        set name [lindex $data(items) $i]
567
        incr curAfter $data($name,size)
568
        incr minAfter $data($name,min)
569
        incr maxAfter $data($name,max)
570
        incr i
571
    }
572
 
573
    set beforeToGo [tixPanedWindow:Min2 \
574
        [expr "$curBefore-$minBefore"] [expr "$maxAfter-$curAfter"]]
575
 
576
    set afterToGo [tixPanedWindow:Min2 \
577
        [expr "$curAfter-$minAfter"] [expr "$maxBefore-$curBefore"]]
578
 
579
    set data(beforeLimit) [expr "$curBefore-$beforeToGo"]
580
    set data(afterLimit)  [expr "$curBefore+$afterToGo"]
581
    set data(curSize)     $curBefore
582
 
583
    if {!$fake} {
584
        tixPanedWindow:PlotHandles $w 1
585
    }
586
}
587
 
588
# Compress the motion so that update is quick even on slow machines
589
#
590
# rootp = root position (either rootx or rooty)
591
proc tixPanedWindow:BtnMove {w item rootp {fake 0}} {
592
    upvar #0 $w data
593
 
594
    set data(rootp) $rootp
595
 
596
    if {$fake} {
597
        tixPanedWindow:BtnMoveCompressed $w $item $fake
598
    } else {
599
        if {$data(movePending) == 0} {
600
            after 2 tixPanedWindow:BtnMoveCompressed $w $item
601
            set data(movePending) 1
602
        }
603
    }
604
}
605
 
606
proc tixPanedWindow:BtnMoveCompressed {w item {fake 0}} {
607
    if {![winfo exists $w]} {
608
        return
609
    }
610
 
611
    upvar #0 $w data
612
 
613
    if {$data(-orientation) == "vertical"} {
614
        set p [expr $data(rootp)-[winfo rooty $w]]
615
    } else {
616
        set p [expr $data(rootp)-[winfo rootx $w]]
617
    }
618
 
619
    if {$p == $data(curSize)} {
620
        set data(movePending) 0
621
        return
622
    }
623
 
624
    if {$p < $data(beforeLimit)} {
625
        set p $data(beforeLimit)
626
    }
627
    if {$p >= $data(afterLimit)} {
628
        set p $data(afterLimit)
629
    }
630
    tixPanedWindow:CalculateChange $w $item $p $fake
631
 
632
    if {!$fake} {
633
        # Force the redraw to happen
634
        #
635
        update idletasks
636
    }
637
    set data(movePending) 0
638
}
639
 
640
# Calculate the change in response to mouse motions
641
#
642
proc tixPanedWindow:CalculateChange {w item p {fake 0}} {
643
    upvar #0 $w data
644
 
645
    if {$p < $data(curSize)} {
646
        tixPanedWindow:MoveBefore $w $item $p
647
    } elseif {$p > $data(curSize)} {
648
        tixPanedWindow:MoveAfter $w $item $p
649
    }
650
 
651
    if {!$fake} {
652
        tixPanedWindow:PlotHandles $w 1
653
    }
654
}
655
 
656
proc tixPanedWindow:MoveBefore {w item p} {
657
    upvar #0 $w data
658
 
659
    set n [expr "$data(curSize)-$p"]
660
 
661
    # Shrink the frames before
662
    #
663
    set from [expr $item-1]
664
    set to   0
665
    tixPanedWindow:Iterate $w $from $to tixPanedWindow:Shrink $n
666
 
667
    # Adjust the frames after
668
    #
669
    set from $item
670
    set to   [expr "$data(nItems)-1"]
671
    tixPanedWindow:Iterate $w $from $to tixPanedWindow:Grow $n
672
 
673
    set data(curSize) $p
674
}
675
 
676
proc tixPanedWindow:MoveAfter {w item p} {
677
    upvar #0 $w data
678
 
679
    set n    [expr "$p-$data(curSize)"]
680
 
681
    # Shrink the frames after
682
    #
683
    set from $item
684
    set to   [expr "$data(nItems)-1"]
685
    tixPanedWindow:Iterate $w $from $to tixPanedWindow:Shrink $n
686
 
687
    # Graw the frame before
688
    #
689
    set from [expr $item-1]
690
    set to   0
691
    tixPanedWindow:Iterate $w $from $to tixPanedWindow:Grow $n
692
 
693
    set data(curSize) $p
694
}
695
 
696
proc tixPanedWindow:CancleLines {w} {
697
    upvar #0 $w data
698
 
699
    if [info exists data(lines)] {
700
        foreach line $data(lines) {
701
            set x1 [lindex $line 0]
702
            set y1 [lindex $line 1]
703
            set x2 [lindex $line 2]
704
            set y2 [lindex $line 3]
705
 
706
            tixTmpLine $x1 $y1 $x2 $y2 $w
707
        }
708
 
709
        catch {unset data(lines)}
710
    }
711
}
712
 
713
proc tixPanedWindow:PlotHandles {w transient} {
714
    global tcl_platform
715
 
716
    upvar #0 $w data
717
 
718
    set totalsize 0
719
    set i 0
720
 
721
    if {$data(-orientation) == "vertical"} {
722
        set btnp [expr [winfo width $w]-13]
723
    } else {
724
        set h [winfo height $w]
725
        if {$h > 18} {
726
            set btnp 9
727
        } else {
728
            set btnp [expr $h-9]
729
        }
730
    }
731
 
732
    set firstpane [lindex $data(items) 0]
733
    set totalsize $data($firstpane,size)
734
 
735
    if {$transient} {
736
        tixPanedWindow:CancleLines $w
737
        set data(lines) ""
738
    }
739
 
740
    for {set i 1} {$i < $data(nItems)} {incr i} {
741
        if {! $transient} {
742
            if {$data(-orientation) == "vertical"} {
743
                # CYGNUS LOCAL: Don't use buttons on Windows
744
                if {$tcl_platform(platform) != "windows"} then {
745
                    place $data(btn,$i) -x $btnp -y [expr "$totalsize-4"]
746
                }
747
                place $data(sep,$i) -x 0 -y [expr "$totalsize-1"] -relwidth 1
748
            } else {
749
                # CYGNUS LOCAL: Don't use buttons on Windows
750
                if {$tcl_platform(platform) != "windows"} then {
751
                    place $data(btn,$i) -y $btnp -x [expr "$totalsize-5"]
752
                }
753
                place $data(sep,$i) -y 0 -x [expr "$totalsize-1"] -relheight 1
754
            }
755
        } else {
756
            if {$data(-orientation) == "vertical"} {
757
                set x1 [winfo rootx $w]
758
                set x2 [expr $x1 + [winfo width $w]]
759
                set y  [expr $totalsize-1+[winfo rooty $w]]
760
 
761
                tixTmpLine $x1 $y $x2 $y $w
762
                lappend data(lines) [list $x1 $y $x2 $y]
763
            } else {
764
                set y1 [winfo rooty $w]
765
                set y2 [expr $y1 + [winfo height $w]]
766
                set x  [expr $totalsize-1+[winfo rootx $w]]
767
 
768
                tixTmpLine $x $y1 $x $y2 $w
769
                lappend data(lines) [list $x $y1 $x $y2]
770
            }
771
        }
772
 
773
        set name [lindex $data(items) $i]
774
        incr totalsize $data($name,size)
775
    }
776
}
777
 
778
proc tixPanedWindow:BtnUp {w item {fake 0}} {
779
    upvar #0 $w data
780
 
781
    if {!$fake} {
782
        tixPanedWindow:CancleLines $w
783
    }
784
 
785
    tixPanedWindow:UpdateSizes $w
786
 
787
    if {!$fake} {
788
        $data(btn,$item) config -relief raised
789
        grab release $data(btn,$item)
790
    }
791
}
792
 
793
 
794
proc tixPanedWindow:HighlightBtn {w item} {
795
    upvar #0 $w data
796
 
797
    $data(btn,$item) config -background $data(-handleactivebg)
798
}
799
 
800
proc tixPanedWindow:DeHighlightBtn {w item} {
801
    upvar #0 $w data
802
 
803
    $data(btn,$item) config -background $data(-handlebg)
804
}
805
 
806
#----------------------------------------------------------------------
807
#
808
#
809
# Geometry management routines
810
#
811
#
812
#----------------------------------------------------------------------
813
 
814
# update the sizes of each pane according to the data($name,size) variables
815
#
816
proc tixPanedWindow:UpdateSizes {w} {
817
    global tcl_platform
818
 
819
    upvar #0 $w data
820
 
821
    set data(totalsize) 0
822
 
823
    set mw [winfo width  $w]
824
    set mh [winfo height $w]
825
 
826
    for {set i 0} {$i < $data(nItems)} {incr i} {
827
        set name [lindex $data(items) $i]
828
 
829
        if {$data($name,size) > 0} {
830
            if {$data(-orientation) == "vertical"} {
831
                tixMoveResizeWindow $w.$name 0 $data(totalsize) \
832
                    $mw $data($name,size)
833
                tixMapWindow $w.$name
834
                raise $w.$name
835
            } else {
836
                tixMoveResizeWindow $w.$name $data(totalsize) 0 \
837
                    $data($name,size) $mh
838
                tixMapWindow $w.$name
839
                raise $w.$name
840
            }
841
        } else {
842
            tixUnmapWindow $w.$name
843
        }
844
        incr data(totalsize) $data($name,size)
845
    }
846
 
847
    # Reset the color and width of the separator
848
    #
849
    if {$data(-orientation) == "vertical"} {
850
        set spec -height
851
    } else {
852
        set spec -width
853
    }
854
 
855
    # CYGNUS LOCAL: On Windows, use a thicker line.
856
    if {$tcl_platform(platform) == "windows"} then {
857
        set thickness 4
858
    } else {
859
        set thickness 2
860
    }
861
 
862
    for {set i 1} {$i < $data(nItems)} {incr i} {
863
        $data(sep,$i) config -bg $data(-separatorbg) $spec $thickness
864
        raise $data(sep,$i)
865
        raise $data(btn,$i)
866
    }
867
 
868
 
869
    # Invoke the callback command
870
    #
871
    if {$data(-command) != ""} {
872
        set sizes ""
873
        foreach item $data(items) {
874
            lappend sizes $data($item,size)
875
        }
876
        set bind(specs) ""
877
        tixEvalCmdBinding $w $data(-command) bind [list $sizes]
878
    }
879
}
880
 
881
proc tixPanedWindow:GetNaturalSizes {w} {
882
    upvar #0 $w data
883
 
884
    set data(totalsize) 0
885
    set totalreq 0
886
 
887
    if {$data(-orientation) == "vertical"} {
888
        set majorspec height
889
        set minorspec width
890
    } else {
891
        set majorspec width
892
        set minorspec height
893
    }
894
 
895
    set minorsize 0
896
    foreach name $data(items) {
897
        if {[winfo manager $w.$name] != "tixGeometry"} {
898
            error "Geometry management error: pane \"$w.$name\" cannot be managed by \"[winfo manager $w.$name]\"\nhint: delete the line \"[winfo manager $w.$name] $w.$name ...\" from your program"
899
        }
900
 
901
        # set the minor size
902
        #
903
        set req_minor [winfo req$minorspec $w.$name]
904
 
905
        if {$req_minor > $minorsize} {
906
            set minorsize $req_minor
907
        }
908
 
909
        # Check the natural size against the max, min requirements.
910
        # Change the natural size if necessary
911
        #
912
        if {$data($name,size) <= 1} {
913
            set data($name,size) [winfo req$majorspec $w.$name]
914
        }
915
 
916
        if {$data($name,size) > 1} {
917
            # If we get zero maybe the widget was not initialized yet ...
918
            #
919
            # %% hazard : what if the window is really 1x1?
920
            #
921
            if {$data($name,size) < $data($name,min)} {
922
                set data($name,size) $data($name,min)
923
            }
924
            if {$data($name,size) > $data($name,max)} {
925
                set data($name,size) $data($name,max)
926
            }
927
        }
928
 
929
        # kludge: because a frame always returns req size of {1,1} before
930
        # the packer processes it, we do the following to mark the
931
        # pane as "size unknown"
932
        #
933
#       if {$data($name,size) == 1 && ![winfo ismapped $w.$name]} {
934
#           set data($name,size) 0
935
#       }
936
 
937
        # Add up the total size
938
        #
939
        incr data(totalsize) $data($name,size)
940
 
941
        # Find out the request size
942
        #
943
        if {$data($name,rsize) == 0} {
944
            set rsize [winfo req$majorspec $w.$name]
945
        } else {
946
            set rsize $data($name,rsize)
947
        }
948
 
949
        if {$rsize < $data($name,min)} {
950
            set rsize $data($name,min)
951
        }
952
        if {$rsize > $data($name,max)} {
953
            set rsize $data($name,max)
954
        }
955
 
956
        incr totalreq $rsize
957
    }
958
 
959
    if {$data(-orientation) == "vertical"} {
960
        return "$minorsize $totalreq"
961
    } else {
962
        return "$totalreq $minorsize"
963
    }
964
}
965
 
966
#--------------------------------------------------
967
# Handling resize
968
#--------------------------------------------------
969
proc tixPanedWindow:ClientGeomProc {w type client} {
970
    tixPanedWindow:RepackWhenIdle $w
971
}
972
 
973
#
974
# This monitor the sizes of the master window
975
#
976
proc tixPanedWindow:MasterGeomProc {w master} {
977
    tixPanedWindow:RepackWhenIdle $w
978
}
979
 
980
proc tixPanedWindow:RepackWhenIdle {w} {
981
    if {![winfo exist $w]} {
982
        return
983
    }
984
    upvar #0 $w data
985
 
986
    if {$data(repack) == 0} {
987
        tixWidgetDoWhenIdle tixPanedWindow:Repack $w
988
        set data(repack) 1
989
    }
990
}
991
 
992
#
993
# This monitor the sizes of the master window
994
#
995
proc tixPanedWindow:Repack {w} {
996
    upvar #0 $w data
997
 
998
    # Calculate the desired size of the master
999
    #
1000
    set dim [tixPanedWindow:GetNaturalSizes $w]
1001
 
1002
    if {$data(-width) != 0} {
1003
        set mreqw $data(-width)
1004
    } else {
1005
        set mreqw [lindex $dim 0]
1006
    }
1007
 
1008
    if {$data(-height) != 0} {
1009
        set mreqh $data(-height)
1010
    } else {
1011
        set mreqh [lindex $dim 1]
1012
    }
1013
 
1014
    if !$data(-dynamicgeometry) {
1015
        if {$mreqw < $data(maxReqW)} {
1016
            set mreqw $data(maxReqW)
1017
        }
1018
        if {$mreqh < $data(maxReqH)} {
1019
            set mreqh $data(maxReqH)
1020
        }
1021
        set data(maxReqW) $mreqw
1022
        set data(maxReqH) $mreqh
1023
    }
1024
    if {$mreqw != [winfo reqwidth $w] || $mreqh != [winfo reqheight $w] } {
1025
        if {![info exists data(counter)]} {
1026
            set data(counter) 0
1027
        }
1028
        if {$data(counter) < 50} {
1029
            incr data(counter)
1030
            tixGeometryRequest $w $mreqw $mreqh
1031
            tixWidgetDoWhenIdle tixPanedWindow:Repack $w
1032
            set data(repack) 1
1033
            return
1034
        }
1035
    }
1036
 
1037
    set data(counter) 0
1038
 
1039
    if {$data(nItems) == 0} {
1040
        set data(repack) 0
1041
        return
1042
    }
1043
 
1044
    tixWidgetDoWhenIdle tixPanedWindow:DoRepack $w
1045
}
1046
 
1047
proc tixPanedWindow:DoRepack {w} {
1048
    upvar #0 $w data
1049
 
1050
    if {$data(-orientation) == "vertical"} {
1051
        set newSize [winfo height $w]
1052
    } else {
1053
        set newSize [winfo width $w]
1054
    }
1055
 
1056
    if {$newSize <= 1} {
1057
        # Probably this window is too small to see anyway
1058
        # %%Kludge: I don't know if this always work.
1059
        #
1060
        set data(repack) 0
1061
        return
1062
    }
1063
 
1064
    set totalExp 0
1065
    foreach name $data(items) {
1066
        set totalExp [expr $totalExp + $data($name,expand)]
1067
    }
1068
 
1069
    if {$newSize > $data(totalsize)} {
1070
        # Grow
1071
        #
1072
        set toGrow [expr "$newSize-$data(totalsize)"]
1073
 
1074
        set p [llength $data(items)]
1075
        foreach name $data(items) {
1076
            set toGrow [tixPanedWindow:xGrow $w $name $toGrow $totalExp $p]
1077
            if {$toGrow > 0} {
1078
                set totalExp [expr $totalExp-$data($name,expand)]
1079
                incr p -1
1080
            } else {
1081
                break
1082
            }
1083
        }
1084
    } else {
1085
        # Shrink
1086
        #
1087
        set toShrink [expr "$data(totalsize)-$newSize"]
1088
 
1089
        set usedSize 0
1090
        foreach name $data(items) {
1091
            set toShrink [tixPanedWindow:xShrink $w $name $toShrink \
1092
                $totalExp $newSize $usedSize]
1093
            if {$toShrink > 0} {
1094
                set totalExp [expr $totalExp-$data($name,expand)]
1095
                incr usedSize $data($name,size)
1096
            } else {
1097
                break
1098
            }
1099
        }
1100
    }
1101
 
1102
    tixPanedWindow:UpdateSizes $w
1103
    tixPanedWindow:PlotHandles $w 0
1104
 
1105
    set data(repack) 0
1106
}
1107
 
1108
#--------------------------------------------------
1109
# Shrink and grow items
1110
#--------------------------------------------------
1111
# 
1112
#   toGrow: how much free area to grow into
1113
#        p: == 1 if $name is the last in the list of items
1114
# totalExp: used to calculate the amount of the free area that this
1115
#           window can grow into
1116
#
1117
proc tixPanedWindow:xGrow {w name toGrow totalExp p} {
1118
    upvar #0 $w data
1119
 
1120
    if {$p == 1} {
1121
        set canGrow $toGrow
1122
    } else {
1123
        if {$totalExp == 0} {
1124
            set canGrow 0
1125
        } else {
1126
            set canGrow [expr int($toGrow * $data($name,expand) / $totalExp)]
1127
        }
1128
    }
1129
 
1130
    if {[expr $canGrow + $data($name,size)] > $data($name,max)} {
1131
        set canGrow [expr $data($name,max) - $data($name,size)]
1132
    }
1133
 
1134
    incr data($name,size) $canGrow
1135
    incr toGrow -$canGrow
1136
 
1137
    return $toGrow
1138
}
1139
 
1140
proc tixPanedWindow:xShrink {w name toShrink totalExp newSize usedSize} {
1141
    upvar #0 $w data
1142
 
1143
    if {$totalExp == 0} {
1144
        set canShrink 0
1145
    } else {
1146
        set canShrink [expr int($toShrink * $data($name,expand) / $totalExp)]
1147
    }
1148
 
1149
    if {[expr $data($name,size) - $canShrink] < $data($name,min)} {
1150
        set canShrink [expr $data($name,size) -$data($name,min)]
1151
    }
1152
    if {[expr $usedSize + $data($name,size) - $canShrink] > $newSize} {
1153
        set data($name,size) [expr $newSize - $usedSize]
1154
        return 0
1155
    } else {
1156
        incr data($name,size) -$canShrink
1157
        incr toShrink -$canShrink
1158
 
1159
        return $toShrink
1160
    }
1161
}
1162
 
1163
#--------------------------------------------------
1164
# Shrink and grow items
1165
#--------------------------------------------------
1166
proc tixPanedWindow:Shrink {w name n} {
1167
    upvar #0 $w data
1168
 
1169
    set canShrink [expr "$data($name,size) - $data($name,min)"]
1170
 
1171
    if {$canShrink > $n} {
1172
        incr data($name,size) -$n
1173
        return 0
1174
    } elseif {$canShrink > 0} {
1175
        set data($name,size) $data($name,min)
1176
        incr n -$canShrink
1177
    }
1178
    return $n
1179
}
1180
 
1181
proc tixPanedWindow:Grow {w name n} {
1182
    upvar #0 $w data
1183
 
1184
    set canGrow [expr "$data($name,max) - $data($name,size)"]
1185
 
1186
    if {$canGrow > $n} {
1187
        incr data($name,size) $n
1188
        return 0
1189
    } elseif {$canGrow > 0} {
1190
        set data($name,size) $data($name,max)
1191
        incr n -$canGrow
1192
    }
1193
 
1194
    return $n
1195
}
1196
 
1197
proc tixPanedWindow:Iterate {w from to proc n} {
1198
    upvar #0 $w data
1199
 
1200
    if {$from <= $to} {
1201
        for {set i $from} {$i <= $to} {incr i} {
1202
            set n [$proc $w [lindex $data(items) $i] $n]
1203
            if {$n == 0} {
1204
                break
1205
            }
1206
        }
1207
    } else {
1208
        for {set i $from} {$i >= $to} {incr i -1} {
1209
            set n [$proc $w [lindex $data(items) $i] $n]
1210
            if {$n == 0} {
1211
                break
1212
            }
1213
        }
1214
    }
1215
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.