mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-20 04:08:15 +02:00

------------------------------------------------------------------------ r19294 | paul | 2009-04-10 11:17:35 +0800 (Птн, 10 Апр 2009) | 1 line lcl, win32: start optimizations: imglist (all), controls (all), combtrls (statubar) ------------------------------------------------------------------------ r19305 | martin | 2009-04-10 21:53:27 +0800 (Птн, 10 Апр 2009) | 1 line Moved "DoneRegisterCheck" to global LCL ------------------------------------------------------------------------ r19306 | martin | 2009-04-10 22:14:57 +0800 (Птн, 10 Апр 2009) | 1 line Moved "DoneRegisterCheck" to global LCL (more) ------------------------------------------------------------------------ r19307 | martin | 2009-04-10 22:22:44 +0800 (Птн, 10 Апр 2009) | 1 line changed case true => True ------------------------------------------------------------------------ r19308 | paul | 2009-04-10 22:28:28 +0800 (Птн, 10 Апр 2009) | 1 line fix file case ------------------------------------------------------------------------ r19311 | martin | 2009-04-10 23:09:16 +0800 (Птн, 10 Апр 2009) | 1 line Moved Registration of TCustomCalendar ------------------------------------------------------------------------ r19312 | martin | 2009-04-10 23:28:03 +0800 (Птн, 10 Апр 2009) | 1 line Moved PropertyToSkip for TCalender ------------------------------------------------------------------------ r19314 | paul | 2009-04-10 23:50:30 +0800 (Птн, 10 Апр 2009) | 1 line merge r13913 #999e8b059d ------------------------------------------------------------------------ r19315 | paul | 2009-04-10 23:53:07 +0800 (Птн, 10 Апр 2009) | 1 line cleanup WSCalendar ------------------------------------------------------------------------ r19316 | paul | 2009-04-11 00:37:44 +0800 (Сбт, 11 Апр 2009) | 1 line finish with ComCtrls ------------------------------------------------------------------------ r19318 | martin | 2009-04-11 01:37:40 +0800 (Сбт, 11 Апр 2009) | 1 line Moved dialogs ------------------------------------------------------------------------ r19319 | martin | 2009-04-11 01:47:30 +0800 (Сбт, 11 Апр 2009) | 1 line Moved dialogs ------------------------------------------------------------------------ r19320 | martin | 2009-04-11 02:47:52 +0800 (Сбт, 11 Апр 2009) | 1 line Moved ExtCtrls, ExtDlgs ------------------------------------------------------------------------ r19321 | martin | 2009-04-11 03:23:32 +0800 (Сбт, 11 Апр 2009) | 1 line Moved PropertyToSkip ------------------------------------------------------------------------ r19322 | martin | 2009-04-11 03:37:39 +0800 (Сбт, 11 Апр 2009) | 1 line Moved StdCtrls ------------------------------------------------------------------------ r19323 | martin | 2009-04-11 04:05:50 +0800 (Сбт, 11 Апр 2009) | 1 line Moved Buttons ------------------------------------------------------------------------ r19325 | paul | 2009-04-11 11:02:26 +0800 (Сбт, 11 Апр 2009) | 1 line remove DirSel ------------------------------------------------------------------------ r19326 | paul | 2009-04-11 11:11:37 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterArrow ------------------------------------------------------------------------ r19327 | paul | 2009-04-11 11:32:09 +0800 (Сбт, 11 Апр 2009) | 1 line register WS classes only for TCustomXXX classes if they are available (like TCustomScrollBar instead of TScrollBar) and only for those descendants which really differ (like TRadioButton, TToggleButton) ------------------------------------------------------------------------ r19328 | paul | 2009-04-11 11:40:00 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterCustomCheckBox ------------------------------------------------------------------------ r19329 | paul | 2009-04-11 11:57:22 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterXXX for Forms ------------------------------------------------------------------------ r19330 | paul | 2009-04-11 12:13:05 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterCustomGrid + move of RegisterPropertyToSkip ------------------------------------------------------------------------ r19331 | paul | 2009-04-11 12:24:29 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterXXX for Menus ------------------------------------------------------------------------ r19332 | paul | 2009-04-11 12:35:16 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterXXX for PairSplitter ------------------------------------------------------------------------ r19333 | paul | 2009-04-11 12:47:39 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterXXX for Spin ------------------------------------------------------------------------ r19334 | paul | 2009-04-11 12:58:55 +0800 (Сбт, 11 Апр 2009) | 1 line RegisterCustomRubberBand ------------------------------------------------------------------------ r19335 | paul | 2009-04-11 13:31:43 +0800 (Сбт, 11 Апр 2009) | 1 line remove 2 initialization sections ------------------------------------------------------------------------ r19336 | paul | 2009-04-11 13:46:26 +0800 (Сбт, 11 Апр 2009) | 1 line remove TPopupNotifier.png from LCL ------------------------------------------------------------------------ r19338 | paul | 2009-04-11 13:54:03 +0800 (Сбт, 11 Апр 2009) | 1 line cleanup ------------------------------------------------------------------------ r19341 | paul | 2009-04-11 14:59:27 +0800 (Сбт, 11 Апр 2009) | 1 line cleanup ------------------------------------------------------------------------ r19343 | martin | 2009-04-11 19:59:18 +0800 (Сбт, 11 Апр 2009) | 1 line Reduced Unit-Circles, by moving Register* into WS* units ------------------------------------------------------------------------ r19344 | martin | 2009-04-11 20:22:49 +0800 (Сбт, 11 Апр 2009) | 1 line Dummy file for gtk ------------------------------------------------------------------------ r19345 | martin | 2009-04-11 21:06:55 +0800 (Сбт, 11 Апр 2009) | 1 line Initial move of gtk1 register ------------------------------------------------------------------------ r19346 | martin | 2009-04-11 21:19:48 +0800 (Сбт, 11 Апр 2009) | 1 line Missing dependencies in gtk1 wsfactory ------------------------------------------------------------------------ r19347 | martin | 2009-04-11 22:36:42 +0800 (Сбт, 11 Апр 2009) | 1 line Declare register* in interface, to keep external linker happy ------------------------------------------------------------------------ r19348 | martin | 2009-04-11 23:34:16 +0800 (Сбт, 11 Апр 2009) | 1 line Declare register* in interface, to keep external linker happy ------------------------------------------------------------------------ r19349 | martin | 2009-04-11 23:39:20 +0800 (Сбт, 11 Апр 2009) | 1 line moved uses for factory ------------------------------------------------------------------------ r19350 | martin | 2009-04-11 23:41:57 +0800 (Сбт, 11 Апр 2009) | 1 line corrected a few accidental "Result := False" ------------------------------------------------------------------------ r19351 | paul | 2009-04-12 00:04:15 +0800 (Вск, 12 Апр 2009) | 1 line removed unused units ------------------------------------------------------------------------ r19352 | paul | 2009-04-12 00:05:26 +0800 (Вск, 12 Апр 2009) | 1 line qt: move RegisterWS calls to qtwsfactory ------------------------------------------------------------------------ r19354 | paul | 2009-04-12 01:04:04 +0800 (Вск, 12 Апр 2009) | 1 line wince: move RegisterWS calls to WinCEWSFactory ------------------------------------------------------------------------ r19356 | martin | 2009-04-12 01:39:56 +0800 (Вск, 12 Апр 2009) | 1 line moved GTK2 ------------------------------------------------------------------------ r19357 | martin | 2009-04-12 01:45:31 +0800 (Вск, 12 Апр 2009) | 1 line moved GTK2 / missing units ------------------------------------------------------------------------ r19358 | martin | 2009-04-12 01:57:43 +0800 (Вск, 12 Апр 2009) | 1 line Fixed one return value from register ------------------------------------------------------------------------ r19360 | martin | 2009-04-12 02:47:42 +0800 (Вск, 12 Апр 2009) | 1 line Gtk2 , needs 2 registrations for WinControl ------------------------------------------------------------------------ r19361 | martin | 2009-04-12 02:57:58 +0800 (Вск, 12 Апр 2009) | 1 line Gtk2 , needs 2nd registrations ------------------------------------------------------------------------ r19368 | paul | 2009-04-12 13:09:59 +0800 (Вск, 12 Апр 2009) | 1 line cleanup ------------------------------------------------------------------------ r19373 | paul | 2009-04-12 13:45:17 +0800 (Вск, 12 Апр 2009) | 1 line wince: forgotten file ------------------------------------------------------------------------ r19374 | paul | 2009-04-12 14:04:04 +0800 (Вск, 12 Апр 2009) | 1 line carbon: move RegisterWSComponent to CarbonWSFactory ------------------------------------------------------------------------ r19375 | paul | 2009-04-12 14:27:47 +0800 (Вск, 12 Апр 2009) | 1 line cleanup ------------------------------------------------------------------------ git-svn-id: trunk@19376 -
381 lines
11 KiB
ObjectPascal
381 lines
11 KiB
ObjectPascal
{ $Id$
|
|
/***************************************************************************
|
|
checklst.pas
|
|
------------
|
|
|
|
Initial Revision : Thu Jun 19 CST 2003
|
|
|
|
***************************************************************************/
|
|
|
|
*****************************************************************************
|
|
* *
|
|
* This file is part of the Lazarus Component Library (LCL) *
|
|
* *
|
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* 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. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
|
|
unit CheckLst;
|
|
|
|
{$mode objfpc} {$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LCLProc, LCLType, GraphType, Graphics, LMessages,
|
|
LResources, Controls, StdCtrls;
|
|
|
|
|
|
type
|
|
TCheckListClicked = procedure(Sender: TObject; Index: integer) of object;
|
|
|
|
{ TCustomCheckListBox }
|
|
|
|
TCustomCheckListBox = class(TCustomListBox)
|
|
private
|
|
FAllowGrayed: Boolean;
|
|
FItemDataOffset: Integer;
|
|
FOnClickCheck : TNotifyEvent;
|
|
FOnItemClick: TCheckListClicked;
|
|
function GetChecked(const AIndex: Integer): Boolean;
|
|
function GetCount: integer;
|
|
function GetItemEnabled(AIndex: Integer): Boolean;
|
|
function GetState(AIndex: Integer): TCheckBoxState;
|
|
procedure SetChecked(const AIndex: Integer; const AValue: Boolean);
|
|
procedure SendItemState(const AIndex: Integer; const AState: TCheckBoxState);
|
|
procedure SendItemEnabled(const AIndex: Integer; const AEnabled: Boolean);
|
|
procedure DoChange(var Msg: TLMessage); message LM_CHANGED;
|
|
procedure SetItemEnabled(AIndex: Integer; const AValue: Boolean);
|
|
procedure SetState(AIndex: Integer; const AValue: TCheckBoxState);
|
|
protected
|
|
class procedure WSRegisterClass; override;
|
|
procedure AssignItemDataToCache(const AIndex: Integer; const AData: Pointer); override;
|
|
procedure AssignCacheToItemData(const AIndex: Integer; const AData: Pointer); override;
|
|
function GetCachedDataSize: Integer; override;
|
|
procedure DefineProperties(Filer: TFiler); override;
|
|
procedure ReadData(Stream: TStream);
|
|
procedure WriteData(Stream: TStream);
|
|
procedure ClickCheck; dynamic;
|
|
procedure ItemClick(const AIndex: Integer); dynamic;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure FontChanged(Sender: TObject); override;
|
|
procedure ParentFontChanged; override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure MeasureItem(Index: Integer; var TheHeight: Integer); override;
|
|
procedure Toggle(AIndex: Integer);
|
|
|
|
property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
|
|
property Checked[AIndex: Integer]: Boolean read GetChecked write SetChecked;
|
|
property ItemEnabled[AIndex: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
|
|
property State[AIndex: Integer]: TCheckBoxState read GetState write SetState;
|
|
property Count: integer read GetCount;
|
|
property OnClickCheck: TNotifyEvent read FOnClickCheck write FOnClickCheck;
|
|
property OnItemClick: TCheckListClicked read FOnItemClick write FOnItemClick;
|
|
end;
|
|
|
|
|
|
{ TCheckListBox }
|
|
|
|
TCheckListBox = class(TCustomCheckListBox)
|
|
published
|
|
property Align;
|
|
property AllowGrayed;
|
|
property Anchors;
|
|
property BidiMode;
|
|
property BorderSpacing;
|
|
property BorderStyle;
|
|
property Color;
|
|
property Columns;
|
|
property Constraints;
|
|
property DragCursor;
|
|
property DragMode;
|
|
property ExtendedSelect;
|
|
property Enabled;
|
|
property Font;
|
|
property IntegralHeight;
|
|
property Items;
|
|
property ItemHeight;
|
|
property MultiSelect;
|
|
property OnChangeBounds;
|
|
property OnClick;
|
|
property OnClickCheck;
|
|
property OnContextPopup;
|
|
property OnDblClick;
|
|
property OnDrawItem;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnItemClick;
|
|
property OnKeyPress;
|
|
property OnKeyDown;
|
|
property OnKeyUp;
|
|
property OnMouseMove;
|
|
property OnMouseDown;
|
|
property OnMouseUp;
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnMouseWheel;
|
|
property OnMouseWheelDown;
|
|
property OnMouseWheelUp;
|
|
property OnResize;
|
|
property OnShowHint;
|
|
property OnStartDrag;
|
|
property OnUTF8KeyPress;
|
|
property ParentBidiMode;
|
|
property ParentFont;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property Sorted;
|
|
property Style;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property TopIndex;
|
|
property Visible;
|
|
end;
|
|
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
uses
|
|
WSCheckLst;
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents('Additional',[TCheckListBox]);
|
|
end;
|
|
|
|
type
|
|
PCachedItemData = ^TCachedItemData;
|
|
TCachedItemData = record
|
|
State: TCheckBoxState;
|
|
Enabled: Boolean;
|
|
end;
|
|
|
|
{ TCustomCheckListBox }
|
|
|
|
procedure TCustomCheckListBox.AssignCacheToItemData(const AIndex: Integer;
|
|
const AData: Pointer);
|
|
begin
|
|
inherited AssignCacheToItemData(AIndex, AData);
|
|
SendItemState(AIndex, PCachedItemData(AData + FItemDataOffset)^.State);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.AssignItemDataToCache(const AIndex: Integer;
|
|
const AData: Pointer);
|
|
begin
|
|
inherited AssignItemDataToCache(AIndex, AData);
|
|
PCachedItemData(AData + FItemDataOffset)^.State := State[AIndex];
|
|
PCachedItemData(AData + FItemDataOffset)^.Enabled := ItemEnabled[AIndex];
|
|
end;
|
|
|
|
constructor TCustomCheckListBox.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FCompStyle := csCheckListBox;
|
|
FItemDataOffset := inherited GetCachedDataSize;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.MeasureItem(Index: Integer; var TheHeight: Integer);
|
|
begin
|
|
if (Style = lbStandard) then
|
|
TheHeight := CalculateStandardItemHeight
|
|
else
|
|
inherited MeasureItem(Index, TheHeight);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.Toggle(AIndex: Integer);
|
|
const
|
|
NextStateMap: array[TCheckBoxState] of array[Boolean] of TCheckBoxState =
|
|
(
|
|
{cbUnchecked} (cbChecked, cbChecked),
|
|
{cbChecked } (cbUnChecked, cbGrayed),
|
|
{cbGrayed } (cbUnChecked, cbUnChecked)
|
|
);
|
|
begin
|
|
State[AIndex] := NextStateMap[State[AIndex]][AllowGrayed];
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.DoChange(var Msg: TLMessage);
|
|
begin
|
|
//DebugLn(['TCustomCheckListBox.DoChange ',DbgSName(Self),' ',Msg.WParam]);
|
|
ClickCheck;
|
|
ItemClick(Msg.WParam);
|
|
end;
|
|
|
|
function TCustomCheckListBox.GetCachedDataSize: Integer;
|
|
begin
|
|
FItemDataOffset := inherited GetCachedDataSize;
|
|
Result := FItemDataOffset + SizeOf(TCachedItemData);
|
|
end;
|
|
|
|
function TCustomCheckListBox.GetChecked(const AIndex: Integer): Boolean;
|
|
begin
|
|
Result := State[AIndex] <> cbUnchecked;
|
|
end;
|
|
|
|
function TCustomCheckListBox.GetCount: integer;
|
|
begin
|
|
Result := Items.Count;
|
|
end;
|
|
|
|
function TCustomCheckListBox.GetItemEnabled(AIndex: Integer): Boolean;
|
|
begin
|
|
CheckIndex(AIndex);
|
|
|
|
if HandleAllocated then
|
|
Result := TWSCustomCheckListBoxClass(WidgetSetClass).GetItemEnabled(Self, AIndex)
|
|
else
|
|
Result := PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.Enabled;
|
|
end;
|
|
|
|
function TCustomCheckListBox.GetState(AIndex: Integer): TCheckBoxState;
|
|
begin
|
|
CheckIndex(AIndex);
|
|
|
|
if HandleAllocated then
|
|
Result := TWSCustomCheckListBoxClass(WidgetSetClass).GetState(Self, AIndex)
|
|
else
|
|
Result := PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.State;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
if (Key = VK_SPACE) and (Shift=[]) then
|
|
begin
|
|
Index := ItemIndex;
|
|
Checked[Index] := not Checked[Index];
|
|
ItemClick(Index);
|
|
Key := VK_UNKNOWN;
|
|
end else
|
|
inherited KeyDown(Key,Shift);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.SetItemEnabled(AIndex: Integer;
|
|
const AValue: Boolean);
|
|
begin
|
|
CheckIndex(AIndex);
|
|
|
|
if HandleAllocated then
|
|
SendItemEnabled(AIndex, AValue)
|
|
else
|
|
PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.Enabled := AValue;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.SetState(AIndex: Integer;
|
|
const AValue: TCheckBoxState);
|
|
begin
|
|
CheckIndex(AIndex);
|
|
|
|
if HandleAllocated
|
|
then SendItemState(AIndex, AValue)
|
|
else PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.State := AValue;
|
|
end;
|
|
|
|
class procedure TCustomCheckListBox.WSRegisterClass;
|
|
begin
|
|
inherited WSRegisterClass;
|
|
RegisterCustomCheckListBox;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.SendItemState(const AIndex: Integer;
|
|
const AState: TCheckBoxState);
|
|
begin
|
|
if HandleAllocated then
|
|
TWSCustomCheckListBoxClass(WidgetSetClass).SetState(Self, AIndex, AState);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.SendItemEnabled(const AIndex: Integer;
|
|
const AEnabled: Boolean);
|
|
begin
|
|
if HandleAllocated then
|
|
TWSCustomCheckListBoxClass(WidgetSetClass).SetItemEnabled(Self, AIndex, AEnabled);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.SetChecked(const AIndex: Integer;
|
|
const AValue: Boolean);
|
|
begin
|
|
if AValue then
|
|
SetState(AIndex, cbChecked)
|
|
else
|
|
SetState(AIndex, cbUnChecked);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.ClickCheck;
|
|
begin
|
|
if Assigned(FOnClickCheck) then FOnClickCheck(Self);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.ItemClick(const AIndex: Integer);
|
|
begin
|
|
if Assigned(OnItemClick) then OnItemClick(Self, AIndex);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.FontChanged(Sender: TObject);
|
|
begin
|
|
inherited FontChanged(Sender);
|
|
if ([csLoading, csDestroying] * ComponentState = []) and (Style = lbStandard) then
|
|
ItemHeight := CalculateStandardItemHeight;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.ParentFontChanged;
|
|
begin
|
|
inherited ParentFontChanged;
|
|
if ([csLoading, csDestroying] * ComponentState = []) and (Style = lbStandard) then
|
|
ItemHeight := CalculateStandardItemHeight;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.DefineProperties(Filer: TFiler);
|
|
begin
|
|
inherited DefineProperties(Filer);
|
|
Filer.DefineBinaryProperty('Data', @ReadData, @WriteData, Items.Count > 0);
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.ReadData(Stream: TStream);
|
|
var
|
|
ChecksCount: integer;
|
|
Checks: string;
|
|
i: Integer;
|
|
begin
|
|
ChecksCount := ReadLRSInteger(Stream);
|
|
if ChecksCount > 0 then
|
|
begin
|
|
SetLength(Checks, ChecksCount);
|
|
Stream.ReadBuffer(Checks[1], ChecksCount);
|
|
for i := 0 to ChecksCount-1 do
|
|
State[i] := TCheckBoxState(ord(Checks[i + 1]));
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomCheckListBox.WriteData(Stream: TStream);
|
|
var
|
|
ChecksCount: integer;
|
|
Checks: string;
|
|
i: Integer;
|
|
begin
|
|
ChecksCount := Items.Count;
|
|
WriteLRSInteger(Stream, ChecksCount);
|
|
if ChecksCount > 0 then
|
|
begin
|
|
SetLength(Checks, ChecksCount);
|
|
for i := 0 to ChecksCount - 1 do
|
|
Checks[i+1] := chr(Ord(State[i]));
|
|
Stream.WriteBuffer(Checks[1], ChecksCount);
|
|
end;
|
|
end;
|
|
|
|
end.
|