Menu

[r614]: / trunk / Src / UChkListStateMgr.pas  Maximize  Restore  History

Download this file

235 lines (210 with data), 7.6 kB

  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
{
* UChkListStateMgr.pas
*
* Implements a class that modifies the behaviour of an associated check list
* box so that clicks anywhere on a list item will toggle the state of the check
* box. Default behaviour is that only clicks on check box change the state.
*
* $Rev$
* $Date$
*
* ***** BEGIN LICENSE BLOCK *****
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is UChkListStateMgr.pas
*
* The Initial Developer of the Original Code is Peter Johnson
* (http://www.delphidabbler.com/).
*
* Portions created by the Initial Developer are Copyright (C) 2009 Peter
* Johnson. All Rights Reserved.
*
* Contributors:
* NONE
*
* ***** END LICENSE BLOCK *****
}
unit UChkListStateMgr;
interface
uses
// Delphi
Classes, Controls, CheckLst;
type
{
TChkListStateMgr:
Class that modifies the behaviour of an associated check list box so that
clicks anywhere on a list item will toggle the state of the check box.
This overrides standard behaviour which is that only clicks on the check
box toggle the check state.
}
TChkListStateMgr = class(TObject)
private
fCLB: TCheckListBox; // check list box (CLB) being managed
fOnClickCheckSave: TNotifyEvent; // check list's orig OnClickSave handler
fOnMouseDownSave: TMouseEvent; // check list's orig OnMouseDown handler
fOnMouseUpSave: TMouseEvent; // check list's orig OnMouseUp handler
fOnStateChange: TNotifyEvent; // ref to OnStateChange event handler
fCheckClicked: Boolean; // flag indicating if check box clicked
fMouseDownItemIdx: Integer; // index of elem where mouse went down
procedure ToggleState(const Index: Integer);
{Toggles state of check box for a list item. Takes account of greyed state
when AllowGrayed is true. Triggers OnStateChange event.
@param Index [in] Index of list item for which state should be changed.
}
procedure ClickCheckHandler(Sender: TObject);
{Handles check list box's OnClickCheck event. Sets flag to prevent MouseUp
event changing state and triggers state change event. Event is passed list
box's original handler, if any.
@param Sender [in] List box that triggered event.
}
procedure MouseDownHandler(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
{Handles check list box's OnMouseDown event. Records list box item where
mouse went down. Event is passed list box's original handler, if any.
@param Sender [in] List box that triggered event.
}
procedure MouseUpHandler(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
{Handles check list box's OnMouseUp event. Toggles state of check box if
click was not on checkbox and mouse is on same list item as mouse down.
Event is passed list box's original handler, if any.
@param Sender [in] List box that triggered event.
}
procedure StateChange;
{Triggers OnStateChange event.
}
public
constructor Create(const CLB: TCheckListBox);
{Class constructor. Sets up object.
@param CLB [in] Check list box control to be managed.
}
destructor Destroy; override;
{Class desctructor. Restores check list box's event handlers.
}
property OnStateChange: TNotifyEvent
read fOnStateChange write fOnStateChange;
{Event triggered when check box state changes as a result of user changing
it}
end;
implementation
uses
// Delphi
StdCtrls;
{ TChkListStateMgr }
procedure TChkListStateMgr.ClickCheckHandler(Sender: TObject);
{Handles check list box's OnClickCheck event. Sets flag to prevent MouseUp
event changing state and triggers state change event. Event is passed list
box's original handler, if any.
@param Sender [in] List box that triggered event.
}
begin
fCheckClicked := True;
StateChange;
if Assigned(fOnClickCheckSave) then
fOnClickCheckSave(fCLB);
end;
constructor TChkListStateMgr.Create(const CLB: TCheckListBox);
{Class constructor. Sets up object.
@param CLB [in] Check list box control to be managed.
}
begin
Assert(Assigned(CLB), ClassName + '.Create: CLB is nil');
inherited Create;
fCLB := CLB;
fOnClickCheckSave := CLB.OnClickCheck;
fOnMouseDownSave := CLB.OnMouseDown;
fOnMouseUpSave := CLB.OnMouseUp;
CLB.OnClickCheck := ClickCheckHandler;
CLB.OnMouseDown := MouseDownHandler;
CLB.OnMouseUp := MouseUpHandler;
end;
destructor TChkListStateMgr.Destroy;
{Class desctructor. Restores check list box's event handlers.
}
begin
fCLB.OnClickCheck := fOnClickCheckSave;
fCLB.OnMouseDown := fOnMouseDownSave;
fCLB.OnMouseUp := fOnMouseUpSave;
inherited;
end;
procedure TChkListStateMgr.MouseDownHandler(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{Handles check list box's OnMouseDown event. Records list box item where mouse
went down. Event is passed list box's original handler, if any.
@param Sender [in] List box that triggered event.
}
begin
fMouseDownItemIdx := fCLB.ItemAtPos(Point(X, Y), True);
if Assigned(fOnMouseDownSave) then
fOnMouseDownSave(Sender, Button, Shift, X, Y);
end;
procedure TChkListStateMgr.MouseUpHandler(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
{Handles check list box's OnMouseUp event. Toggles state of check box if click
was not on checkbox and mouse is on same list item as mouse down. Event is
passed list box's original handler, if any.
@param Sender [in] List box that triggered event.
}
var
Idx: Integer; // index of item under mouse
begin
// we only change state if:
// 1) check box wasn't clicked: control changes state automatically if so
// 2) mouse is still over same item as when mouse went down
if not fCheckClicked then
begin
Idx := fCLB.ItemAtPos(Point(X, Y), True);
if Idx = fMouseDownItemIdx then
ToggleState(fMouseDownItemIdx)
end
else
fCheckClicked := False;
fMouseDownItemIdx := -1;
if Assigned(fOnMouseUpSave) then
fOnMouseUpSave(Sender, Button, Shift, X, Y);
end;
procedure TChkListStateMgr.StateChange;
{Triggers OnStateChange event.
}
begin
if Assigned(fOnStateChange) then
fOnStateChange(fCLB);
end;
procedure TChkListStateMgr.ToggleState(const Index: Integer);
{Toggles state of check box for a list item. Takes account of greyed state
when AllowGrayed is true. Triggers OnStateChange event.
@param Index [in] Index of list item for which state should be changed.
}
var
State: TCheckBoxState; // new state of check box
begin
if Index >= 0 then
begin
State := fCLB.State[Index];
// this code is based on that in CheckLst unit
case State of
cbUnchecked:
if fCLB.AllowGrayed then
State := cbGrayed
else
State := cbChecked;
cbChecked:
State := cbUnchecked;
cbGrayed:
State := cbChecked;
end;
fCLB.State[Index] := State;
// Notify that state has changed
StateChange;
end;
end;
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.