line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Tk::ResizeButton;
|
2
|
|
|
|
|
|
|
#------------------------------------------------
|
3
|
|
|
|
|
|
|
# automagically updated versioning variables -- CVS modifies these!
|
4
|
|
|
|
|
|
|
#------------------------------------------------
|
5
|
|
|
|
|
|
|
our $Revision = '$Revision: 1.3 $';
|
6
|
|
|
|
|
|
|
our $CheckinDate = '$Date: 2003/02/17 16:46:54 $';
|
7
|
|
|
|
|
|
|
our $CheckinUser = '$Author: xpix $';
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# we need to clean these up right here
|
10
|
|
|
|
|
|
|
$Revision =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
11
|
|
|
|
|
|
|
$CheckinDate =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
12
|
|
|
|
|
|
|
$CheckinUser =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#-------------------------------------------------
|
15
|
|
|
|
|
|
|
#-- package Tk::ResizeButton ---------------------
|
16
|
|
|
|
|
|
|
#-------------------------------------------------
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 NAME
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Tk::ResizeButton - provides a resizeable button to be used in an HList
|
21
|
|
|
|
|
|
|
column header.
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use Tk;
|
26
|
|
|
|
|
|
|
use Tk::HList;
|
27
|
|
|
|
|
|
|
use Tk::ResizeButton;
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $mw = MainWindow->new();
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# CREATE MY HLIST
|
32
|
|
|
|
|
|
|
my $hlist = $mw->Scrolled('HList',
|
33
|
|
|
|
|
|
|
-columns=>2,
|
34
|
|
|
|
|
|
|
-header => 1
|
35
|
|
|
|
|
|
|
)->pack(-side => 'left', -expand => 'yes', -fill => 'both');
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# CREATE COLUMN HEADER 0
|
38
|
|
|
|
|
|
|
my $headerstyle = $hlist->ItemStyle('window', -padx => 0, -pady => 0);
|
39
|
|
|
|
|
|
|
my $header0 = $hlist->ResizeButton(
|
40
|
|
|
|
|
|
|
-text => 'Test Name',
|
41
|
|
|
|
|
|
|
-relief => 'flat', -pady => 0,
|
42
|
|
|
|
|
|
|
-command => sub { print "Hello, world!\n";},
|
43
|
|
|
|
|
|
|
-widget => \$hlist,
|
44
|
|
|
|
|
|
|
-column => 0
|
45
|
|
|
|
|
|
|
);
|
46
|
|
|
|
|
|
|
$hlist->header('create', 0,
|
47
|
|
|
|
|
|
|
-itemtype => 'window',
|
48
|
|
|
|
|
|
|
-widget => $header0,
|
49
|
|
|
|
|
|
|
-style=>$headerstyle
|
50
|
|
|
|
|
|
|
);
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# CREATE COLUMN HEADER 1
|
53
|
|
|
|
|
|
|
my $header1 = $hlist->ResizeButton(
|
54
|
|
|
|
|
|
|
-text => 'Status',
|
55
|
|
|
|
|
|
|
-relief => 'flat',
|
56
|
|
|
|
|
|
|
-pady => 0,
|
57
|
|
|
|
|
|
|
-command => sub { print "Hello, world!\n";},
|
58
|
|
|
|
|
|
|
-widget => \$hlist,
|
59
|
|
|
|
|
|
|
-column => 1
|
60
|
|
|
|
|
|
|
);
|
61
|
|
|
|
|
|
|
$hlist->header('create', 1,
|
62
|
|
|
|
|
|
|
-itemtype => 'window',
|
63
|
|
|
|
|
|
|
-widget => $header1,
|
64
|
|
|
|
|
|
|
-style =>$headerstyle
|
65
|
|
|
|
|
|
|
);
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
The ResizeButton widget provides a resizeable button widget for use
|
70
|
|
|
|
|
|
|
in an HList column header. When placed in the column header, the
|
71
|
|
|
|
|
|
|
edge of the widget can be selected and dragged to a new location to
|
72
|
|
|
|
|
|
|
change the size of the HList column. When resizing the column, a
|
73
|
|
|
|
|
|
|
column bar will also be placed over the HList indicating the eventual
|
74
|
|
|
|
|
|
|
size of the HList column. A command can also be bound to the button
|
75
|
|
|
|
|
|
|
to do things like sorting the column.
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
The widget takes all the options that Button does. In addition,
|
78
|
|
|
|
|
|
|
the following options must be specified:
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=over 4
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item B<-widget>
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
A reference to the HList widget must by provided via the -widget
|
85
|
|
|
|
|
|
|
option. This allows the ResizeButton to update the column width
|
86
|
|
|
|
|
|
|
after resizing.
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item B<-column>
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
The column number that this ResizeButton is associated with must
|
91
|
|
|
|
|
|
|
also be provided to resize the appropriate column.
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=back
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 AUTHOR
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
B
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head1 UPDATES
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Updated by Slaven Rezic and Frank Herrmann
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=over 4
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=item position columnbar correctly and only use MoveColumnBar to move it instead
|
107
|
|
|
|
|
|
|
of destroying it and re-creating with CreateColumnBar
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=item use Subwidget('scrolled') if it exists
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=item don't give error if -command is not specified
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=item don't let the user hide columns (minwidth?)
|
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=back
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head1 KEYWORDS
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
Tk::HList
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=cut
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
#########################################################################
|
124
|
|
|
|
|
|
|
# Tk::ResizeButton
|
125
|
|
|
|
|
|
|
# Summary: This widget creates a button for use in an HList header which
|
126
|
|
|
|
|
|
|
# provides methods for resizing a column. This was heavily
|
127
|
|
|
|
|
|
|
# leveraged from Columns.pm by Damion Wilson.
|
128
|
|
|
|
|
|
|
# Author: Shaun Wandler
|
129
|
|
|
|
|
|
|
# Date: $Date: 2003/02/17 16:46:54 $
|
130
|
|
|
|
|
|
|
# Revision: $Revision: 1.3 $
|
131
|
|
|
|
|
|
|
#########################################################################=
|
132
|
|
|
|
|
|
|
#####
|
133
|
|
|
|
|
|
|
#
|
134
|
|
|
|
|
|
|
# Updated by Slaven Rezic and Frank Herrmann
|
135
|
|
|
|
|
|
|
#
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# XXX needs lot of work:
|
138
|
|
|
|
|
|
|
# * position columnbar correctly and only use MoveColumnBar to move it instead
|
139
|
|
|
|
|
|
|
# of destroying it and re-creating with CreateColumnBar
|
140
|
|
|
|
|
|
|
# * use Subwidget('scrolled') if it exists
|
141
|
|
|
|
|
|
|
# * don't give error if -command is not specified
|
142
|
|
|
|
|
|
|
# * don't let the user hide columns (minwidth?)
|
143
|
|
|
|
|
|
|
|
144
|
1
|
|
|
1
|
|
796
|
use base qw(Tk::Derived Tk::Button);
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1707
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Construct Tk::Widget 'ResizeButton';
|
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
sub ClassInit {
|
149
|
|
|
|
|
|
|
my ( $class, $mw ) = @_;
|
150
|
|
|
|
|
|
|
$class->SUPER::ClassInit($mw);
|
151
|
|
|
|
|
|
|
$mw->bind( $class, '', 'ButtonRelease' );
|
152
|
|
|
|
|
|
|
$mw->bind( $class, '', 'ButtonPress' );
|
153
|
|
|
|
|
|
|
$mw->bind( $class, '', 'ButtonOver' );
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
return $class;
|
156
|
|
|
|
|
|
|
}
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub Populate {
|
159
|
|
|
|
|
|
|
my ( $this, $args ) = @_;
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# CREATE THE RESIZE CONTROLS
|
162
|
|
|
|
|
|
|
my $l_Widget;
|
163
|
|
|
|
|
|
|
for ( my $i = 0 ; $i < 2 ; ++$i ) {
|
164
|
|
|
|
|
|
|
$l_Widget = $this->Component(
|
165
|
|
|
|
|
|
|
'Frame' => 'Trim_' . $i,
|
166
|
|
|
|
|
|
|
-background => 'white',
|
167
|
|
|
|
|
|
|
-relief => 'raised',
|
168
|
|
|
|
|
|
|
-borderwidth => 2,
|
169
|
|
|
|
|
|
|
-width => 2,
|
170
|
|
|
|
|
|
|
)->place(
|
171
|
|
|
|
|
|
|
'-x' => -( $i * 3 + 2 ),
|
172
|
|
|
|
|
|
|
'-relheight' => 1.0,
|
173
|
|
|
|
|
|
|
'-anchor' => 'ne',
|
174
|
|
|
|
|
|
|
'-height' => -4,
|
175
|
|
|
|
|
|
|
'-relx' => 1.0,
|
176
|
|
|
|
|
|
|
'-y' => 2,
|
177
|
|
|
|
|
|
|
);
|
178
|
|
|
|
|
|
|
}
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
$l_Widget->bind( '' => sub { $this->ButtonRelease(1); } );
|
181
|
|
|
|
|
|
|
$l_Widget->bind( '' => sub { $this->ButtonPress(1); } );
|
182
|
|
|
|
|
|
|
$l_Widget->bind( '' => sub { $this->ButtonOver(1); } );
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
$this->SUPER::Populate($args);
|
185
|
|
|
|
|
|
|
$this->ConfigSpecs(
|
186
|
|
|
|
|
|
|
-widget => [ [ 'SELF', 'PASSIVE' ], 'Widget', 'Widget', undef ],
|
187
|
|
|
|
|
|
|
-column => [ [ 'SELF', 'PASSIVE' ], 'Column', 'Column', 0 ],
|
188
|
|
|
|
|
|
|
-minwidth => [ [ 'SELF', 'PASSIVE' ], 'minWidth', 'minWidth', 50 ],
|
189
|
|
|
|
|
|
|
);
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Keep track of last trim widget
|
192
|
|
|
|
|
|
|
$this->{'m_LastTrim'} = $l_Widget;
|
193
|
|
|
|
|
|
|
}
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub ButtonPress {
|
196
|
|
|
|
|
|
|
my ( $this, $p_Trim ) = ( shift, @_ );
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
$this->{'m_relief'} = $this->cget( -relief );
|
199
|
|
|
|
|
|
|
if ( $this->ButtonEdgeSelected() || $p_Trim ) {
|
200
|
|
|
|
|
|
|
$this->{'m_EdgeSelected'} = 1;
|
201
|
|
|
|
|
|
|
$this->{m_X} = $this->pointerx() - $this->rootx();
|
202
|
|
|
|
|
|
|
CreateColumnBar($this);
|
203
|
|
|
|
|
|
|
} else {
|
204
|
|
|
|
|
|
|
$this->configure( -relief => 'sunken' );
|
205
|
|
|
|
|
|
|
$this->{m_X} = -1;
|
206
|
|
|
|
|
|
|
}
|
207
|
|
|
|
|
|
|
}
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub ButtonRelease {
|
210
|
|
|
|
|
|
|
my ( $this, $p_Trim ) = ( shift, @_ );
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
$this->{'m_EdgeSelected'} = 0;
|
213
|
|
|
|
|
|
|
$this->configure( -relief => $this->{'m_relief'} );
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
if ( $this->{columnBar} ) {
|
216
|
|
|
|
|
|
|
$this->{columnBar}->destroy;
|
217
|
|
|
|
|
|
|
undef $this->{columnBar};
|
218
|
|
|
|
|
|
|
}
|
219
|
|
|
|
|
|
|
if ( $this->{m_X} >= 0 ) {
|
220
|
|
|
|
|
|
|
my $l_NewWidth = ( $this->pointerx() - $this->rootx() );
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
my $hlist = $this->cget( -widget );
|
223
|
|
|
|
|
|
|
my $col = $this->cget( -column );
|
224
|
|
|
|
|
|
|
$$hlist->columnWidth( $col, $l_NewWidth + 5 )
|
225
|
|
|
|
|
|
|
if(($l_NewWidth + 5) > $this->cget( -minwidth ));
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
$this->GeometryRequest( $l_NewWidth, $this->reqheight(), );
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
} elsif ( !$this->ButtonEdgeSelected() ) {
|
230
|
|
|
|
|
|
|
$this->Callback( -command );
|
231
|
|
|
|
|
|
|
}
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
$this->{m_X} = -1;
|
234
|
|
|
|
|
|
|
}
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# CHECK IF THE RESIZE CONTROL IS SELECTED
|
237
|
|
|
|
|
|
|
sub ButtonEdgeSelected {
|
238
|
|
|
|
|
|
|
my ($this) = @_;
|
239
|
|
|
|
|
|
|
{
|
240
|
|
|
|
|
|
|
return ( $this->pointerx() - $this->{m_LastTrim}->rootx() ) > -1;
|
241
|
|
|
|
|
|
|
}
|
242
|
|
|
|
|
|
|
}
|
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# CHANGE THE CURSOR OVER THE RESIZE CONTROL
|
245
|
|
|
|
|
|
|
sub ButtonOver {
|
246
|
|
|
|
|
|
|
my ( $this, $p_Trim ) = @_;
|
247
|
|
|
|
|
|
|
my ($cursor);
|
248
|
|
|
|
|
|
|
my $hlist = $this->cget( -widget );
|
249
|
|
|
|
|
|
|
if ( $this->{'m_EdgeSelected'} || $this->ButtonEdgeSelected() || $p_Trim ) {
|
250
|
|
|
|
|
|
|
if ( $this->{columnBar} ) {
|
251
|
|
|
|
|
|
|
$this->{columnBar}->destroy;
|
252
|
|
|
|
|
|
|
CreateColumnBar($this);
|
253
|
|
|
|
|
|
|
}
|
254
|
|
|
|
|
|
|
$cursor = 'sb_h_double_arrow';
|
255
|
|
|
|
|
|
|
} else {
|
256
|
|
|
|
|
|
|
$cursor = 'left_ptr';
|
257
|
|
|
|
|
|
|
}
|
258
|
|
|
|
|
|
|
$this->configure( -cursor => $cursor );
|
259
|
|
|
|
|
|
|
}
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# Create a column bar which displays on top of the HList widget
|
262
|
|
|
|
|
|
|
# to indicate the eventual size of the column.
|
263
|
|
|
|
|
|
|
sub CreateColumnBar {
|
264
|
|
|
|
|
|
|
my ($this) = @_;
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
my $hlist = $this->cget( -widget );
|
267
|
|
|
|
|
|
|
my $height = $$hlist->height() - $this->height();
|
268
|
|
|
|
|
|
|
my $x = $$hlist->pointerx() - $$hlist->rootx();
|
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# my $x = $this->rootx + $this->width - $$hlist->rootx;
|
271
|
|
|
|
|
|
|
$this->{columnBar} = $$hlist->Frame(
|
272
|
|
|
|
|
|
|
-background => 'white',
|
273
|
|
|
|
|
|
|
-relief => 'raised',
|
274
|
|
|
|
|
|
|
-borderwidth => 2,
|
275
|
|
|
|
|
|
|
-width => 2,
|
276
|
|
|
|
|
|
|
);
|
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
#FIXFIX: Some fudge factors were used here to place the column
|
279
|
|
|
|
|
|
|
# bar at the correct place. It appears that hlist->rootx is
|
280
|
|
|
|
|
|
|
# relative to the scrollbar, while when placing the columnbar
|
281
|
|
|
|
|
|
|
# the x location is relative to hlist widget. This definitely
|
282
|
|
|
|
|
|
|
# doesn't work when using a non-scrolled hlist.
|
283
|
|
|
|
|
|
|
$this->{columnBar}->place(
|
284
|
|
|
|
|
|
|
'-x' => $x,
|
285
|
|
|
|
|
|
|
'-height' => $height - 5,
|
286
|
|
|
|
|
|
|
'-relx' => 0.0,
|
287
|
|
|
|
|
|
|
'-rely' => 0.0,
|
288
|
|
|
|
|
|
|
'-y' => $this->height() + 5,
|
289
|
|
|
|
|
|
|
);
|
290
|
|
|
|
|
|
|
}
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
1;
|