- add TCheckListBox.ItemEnabled property
- implement ItemEnabled for win32, qt, gtk2

git-svn-id: trunk@15295 -
This commit is contained in:
paul 2008-06-03 02:02:42 +00:00
parent 867475552a
commit 72096b4856
9 changed files with 208 additions and 22 deletions

View File

@ -45,11 +45,14 @@ type
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 KeyDown(var Key: Word; Shift: TShiftState); override;
procedure SetItemEnabled(AIndex: Integer; const AValue: Boolean);
procedure SetState(AIndex: Integer; const AValue: TCheckBoxState);
protected
procedure AssignItemDataToCache(const AIndex: Integer; const AData: Pointer); override;
@ -66,6 +69,7 @@ type
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;
@ -147,7 +151,10 @@ end;
type
PCachedItemData = ^TCachedItemData;
TCachedItemData = TCheckBoxState;
TCachedItemData = record
State: TCheckBoxState;
Enabled: Boolean;
end;
{ TCustomCheckListBox }
@ -155,14 +162,15 @@ procedure TCustomCheckListBox.AssignCacheToItemData(const AIndex: Integer;
const AData: Pointer);
begin
inherited AssignCacheToItemData(AIndex, AData);
SendItemState(AIndex, PCachedItemData(AData + FItemDataOffset)^);
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[AIndex];
PCachedItemData(AData + FItemDataOffset)^.State := State[AIndex];
PCachedItemData(AData + FItemDataOffset)^.Enabled := ItemEnabled[AIndex];
end;
constructor TCustomCheckListBox.Create(AOwner: TComponent);
@ -207,6 +215,16 @@ 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);
@ -214,7 +232,7 @@ begin
if HandleAllocated then
Result := TWSCustomCheckListBoxClass(WidgetSetClass).GetState(Self, AIndex)
else
Result := PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^;
Result := PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.State;
end;
procedure TCustomCheckListBox.KeyDown(var Key: Word; Shift: TShiftState);
@ -231,6 +249,17 @@ begin
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
@ -238,7 +267,7 @@ begin
if HandleAllocated
then SendItemState(AIndex, AValue)
else PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^ := AValue;
else PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^.State := AValue;
end;
procedure TCustomCheckListBox.SendItemState(const AIndex: Integer;
@ -248,6 +277,13 @@ begin
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

View File

@ -52,8 +52,12 @@ type
protected
public
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): Boolean; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AEnabled: Boolean); override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
@ -70,13 +74,17 @@ procedure Gtk2WS_CheckListBoxDataFunc(tree_column: PGtkTreeViewColumn;
cell: PGtkCellRenderer; tree_model: PGtkTreeModel; iter: PGtkTreeIter; data: Pointer); cdecl;
var
b: byte;
ADisabled: Boolean;
AValue: TCheckBoxState;
begin
gtk_tree_model_get(tree_model, iter, [0, @b, -1]);
gtk_tree_model_get(tree_model, iter, [3, @ADisabled, -1]);
AValue := TCheckBoxState(b); // TCheckBoxState is 4 byte
g_object_set(cell, 'inconsistent', [gboolean(AValue = cbGrayed), nil]);
if AValue <> cbGrayed then
gtk_cell_renderer_toggle_set_active(PGtkCellRendererToggle(cell), AValue = cbChecked);
g_object_set(cell, 'activatable', [gboolean(not ADisabled), nil]);
end;
procedure Gtk2WS_CheckListBoxToggle(cellrenderertoggle : PGtkCellRendererToggle;
@ -98,10 +106,13 @@ procedure Gtk2WS_CheckListBoxRowActivate(treeview : PGtkTreeView;
arg1 : PGtkTreePath; arg2 : PGtkTreeViewColumn; WidgetInfo: PWidgetInfo); cdecl;
var
APathStr: Pgchar;
AIndex: Integer;
begin
APathStr := gtk_tree_path_to_string(arg1);
TCheckListBox(widgetInfo^.lclObject).Toggle(StrToInt(APathStr));
AIndex := StrToInt(APathStr);
g_free(APathStr);
if TCheckListBox(widgetInfo^.lclObject).ItemEnabled[AIndex] then
TCheckListBox(widgetInfo^.lclObject).Toggle(AIndex);
end;
class procedure TGtk2WSCustomCheckListBox.SetCallbacks(const AGtkWidget: PGtkWidget;
@ -127,7 +138,7 @@ var
WidgetInfo: PWidgetInfo;
begin
Result := TGtkWSBaseScrollingWinControl.CreateHandle(AWinControl,AParams);
p:= PGtkWidget(Result);
p := PGtkWidget(Result);
if Result = 0 then exit;
@ -140,8 +151,8 @@ begin
gtk_scrolled_window_set_shadow_type(PGtkScrolledWindow(p), GTK_SHADOW_IN);
gtk_widget_show(p);
liststore := gtk_list_store_new (3,
[G_TYPE_UCHAR, G_TYPE_STRING, G_TYPE_POINTER, nil]);
liststore := gtk_list_store_new (4,
[G_TYPE_UCHAR, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, nil]);
TreeViewWidget := gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(G_OBJECT(liststore));
@ -158,7 +169,7 @@ begin
@Gtk2WS_CheckListBoxDataFunc, WidgetInfo, nil);
gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(renderer), True);
gtk_tree_view_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), True);
SignalConnect(PGtkWidget(renderer), 'toggled', @Gtk2WS_CheckListBoxToggle, WidgetInfo);
SignalConnect(TreeViewWidget, 'row_activated', @Gtk2WS_CheckListBoxRowActivate, WidgetInfo);
@ -171,7 +182,7 @@ begin
column := gtk_tree_view_column_new_with_attributes(
'LISTITEMS', renderer, ['text', 1, nil]);
gtk_tree_view_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), True);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(TreeViewWidget), False);
@ -192,6 +203,26 @@ begin
SetCallbacks(p, WidgetInfo);
end;
class function TGtk2WSCustomCheckListBox.GetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): Boolean;
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
begin
Result := True;
WidgetInfo := GetWidgetInfo(PGtkWidget(ACheckListBox.Handle));
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
begin
gtk_tree_model_get(ListStore, @Iter, [3, @Result, -1]);
Result := not Result;
end;
end;
class function TGtk2WSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
@ -214,6 +245,23 @@ begin
end;
end;
class procedure TGtk2WSCustomCheckListBox.SetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AEnabled: Boolean);
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
begin
WidgetInfo := GetWidgetInfo(PGtkWidget(ACheckListBox.Handle));
TreeView := PGtkTreeView(WidgetInfo^.CoreWidget);
ListStore := gtk_tree_view_get_model(TreeView);
if gtk_tree_model_iter_nth_child(ListStore, @Iter, nil, AIndex) then
gtk_list_store_set(ListStore, @Iter, [3, not AEnabled, -1]);
end;
class procedure TGtk2WSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);

View File

@ -47,8 +47,12 @@ type
private
protected
public
class function GetState(const ACheckListBox: TCustomCheckListBox;
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): Boolean; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AEnabled: Boolean); override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
@ -71,6 +75,19 @@ const
{QtChecked } cbChecked
);
class function TQtWSCustomCheckListBox.GetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): Boolean;
var
QtListWidget: TQtListWidget;
AListWidget: QListWidgetH;
AItem: QListWidgetItemH;
begin
QtListWidget := TQtListWidget(ACheckListBox.Handle);
AListWidget := QListWidgetH(QtListWidget.Widget);
AItem := QListWidget_item(AListWidget, AIndex);
Result := (QListWidgetItem_flags(AItem) and QtItemIsEnabled) <> 0;
end;
class function TQtWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
@ -85,6 +102,26 @@ begin
Result := QtCheckStateToLCLCheckStateMap[QListWidgetItem_checkState(AItem)];
end;
class procedure TQtWSCustomCheckListBox.SetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AEnabled: Boolean);
var
QtListWidget: TQtListWidget;
AListWidget: QListWidgetH;
AItem: QListWidgetItemH;
Flags: QtItemFlags;
begin
QtListWidget := TQtListWidget(ACheckListBox.Handle);
AListWidget := QListWidgetH(QtListWidget.Widget);
AItem := QListWidget_item(AListWidget, AIndex);
Flags := QListWidgetItem_flags(AItem);
if AEnabled then
Flags := Flags or QtItemIsEnabled
else
Flags := Flags and not QtItemIsEnabled;
QListWidgetItem_setFlags(AItem, Flags);
end;
class procedure TQtWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);

View File

@ -564,10 +564,13 @@ var
// item clicked: toggle
if I < TCheckListBox(lWinControl).Items.Count then
begin
TCheckListBox(lWinControl).Toggle(I);
Message.Msg := LM_CHANGED;
Message.WParam := I;
DeliverMessage(lWinControl, Message);
if TCheckListBox(lWinControl).ItemEnabled[I] then
begin
TCheckListBox(lWinControl).Toggle(I);
Message.Msg := LM_CHANGED;
Message.WParam := I;
DeliverMessage(lWinControl, Message);
end;
end;
// can only click one item
exit;

View File

@ -433,6 +433,7 @@ begin
with FDefaultItem do
begin
State := cbUnchecked;
Enabled := True;
TheObject := nil;
end;
end;
@ -445,6 +446,14 @@ begin
Result := Data^.State;
end;
function TWin32CheckListBoxStrings.GetEnabled(Index: Integer): Boolean;
var
Data: PWin32CheckListBoxItemRecord;
begin
Data := GetItemRecord(Index, false);
Result := Data^.Enabled;
end;
function TWin32CheckListBoxStrings.GetItemRecord(const Index: Integer;
const CreateNew: boolean): PWin32CheckListBoxItemRecord;
begin
@ -460,6 +469,16 @@ begin
end;
end;
procedure TWin32CheckListBoxStrings.SetEnabled(Index: Integer;
const AValue: Boolean);
var
ItemRecord: PWin32CheckListBoxItemRecord;
begin
ItemRecord := GetItemRecord(Index, true);
ItemRecord^.Enabled := AValue;
SetItemRecord(Index, ItemRecord);
end;
procedure TWin32CheckListBoxStrings.SetItemRecord(const Index: Integer;
ItemRecord: PWin32CheckListBoxItemRecord);
begin

View File

@ -101,6 +101,7 @@ Type
TWin32CheckListBoxItemRecord = record
TheObject: TObject;
State: TCheckBoxState;
Enabled: Boolean;
end;
{ TWin32CheckListBoxStrings }
@ -108,8 +109,10 @@ Type
TWin32CheckListBoxStrings = class(TWin32ListStringList)
private
FDefaultItem: TWin32CheckListBoxItemRecord;
function GetEnabled(Index: Integer): Boolean;
function GetState(Index: Integer): TCheckBoxState;
function GetItemRecord(const Index: Integer; const CreateNew: boolean): PWin32CheckListBoxItemRecord;
procedure SetEnabled(Index: Integer; const AValue: Boolean);
procedure SetItemRecord(const Index: Integer; ItemRecord: PWin32CheckListBoxItemRecord);
procedure SetState(Index: Integer; const AValue: TCheckBoxState);
protected
@ -121,6 +124,7 @@ Type
class procedure DeleteItemRecord(const List: HWND; const Index: integer);
procedure Clear; override;
procedure Delete(Index: Integer); override;
property Enabled[Index: Integer]: Boolean read GetEnabled write SetEnabled;
property State[Index: Integer]: TCheckBoxState read GetState write SetState;
end;

View File

@ -219,7 +219,7 @@ var
{$endif}
begin
Selected := (Data^.itemState AND ODS_SELECTED)>0;
Enabled := CheckListBox.Enabled;
Enabled := CheckListBox.Enabled and CheckListBox.ItemEnabled[Data^.itemID];
// fill the background
if Enabled and Selected then

View File

@ -39,8 +39,6 @@ uses
type
{ TWin32WSCheckListBox }
{ TWin32WSCustomCheckListBox }
TWin32WSCustomCheckListBox = class(TWSCustomCheckListBox)
@ -49,8 +47,12 @@ type
public
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): Boolean; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AEnabled: Boolean); override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
@ -67,6 +69,12 @@ begin
GetWindowInfo(Handle)^.List := Result;
end;
class function TWin32WSCustomCheckListBox.GetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): Boolean;
begin
Result := TWin32CheckListBoxStrings(ACheckListBox.Items).Enabled[AIndex];
end;
class function TWin32WSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
@ -74,6 +82,21 @@ begin
Result := TWin32CheckListBoxStrings(ACheckListBox.Items).State[AIndex];
end;
class procedure TWin32WSCustomCheckListBox.SetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AEnabled: Boolean);
var
SizeRect: Windows.RECT;
Handle: HWND;
begin
TWin32CheckListBoxStrings(ACheckListBox.Items).Enabled[AIndex] := AEnabled;
// redraw control
Handle := ACheckListBox.Handle;
Windows.SendMessage(Handle, LB_GETITEMRECT, AIndex, LPARAM(@SizeRect));
Windows.InvalidateRect(Handle, @SizeRect, False);
end;
class procedure TWin32WSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);

View File

@ -54,8 +54,12 @@ type
{ TWSCustomCheckListBox }
TWSCustomCheckListBox = class(TWSCustomListBox)
class function GetState(const ACheckListBox: TCustomCheckListBox;
class function GetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): Boolean; virtual;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; virtual;
class procedure SetItemEnabled(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AEnabled: Boolean); virtual;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); virtual;
end;
@ -64,6 +68,12 @@ type
implementation
class function TWSCustomCheckListBox.GetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): Boolean;
begin
Result := True;
end;
class function TWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
@ -71,6 +81,12 @@ begin
Result := cbUnchecked;
end;
class procedure TWSCustomCheckListBox.SetItemEnabled(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AEnabled: Boolean);
begin
end;
class procedure TWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);