TCheckListBox.State property and support for grayed states:

- win32 and gtk2 working
- wince - only setting state. drawing of state is not implemented as before
- gtk - only setting state, drawing of grayed state to be implemented
- carbon - mapped to UnChecked, Checked (grayed is also treated as checked)

git-svn-id: trunk@13356 -
This commit is contained in:
paul 2007-12-17 10:21:56 +00:00
parent 86b9d6a98d
commit 2bb622e3e8
15 changed files with 358 additions and 254 deletions

View File

@ -39,15 +39,18 @@ type
TCustomCheckListBox = class(TCustomListBox)
private
FAllowGrayed: Boolean;
FItemDataOffset: Integer;
FOnClickCheck : TNotifyEvent;
FOnItemClick: TCheckListClicked;
function GetChecked(const AIndex: Integer): Boolean;
function GetCount: integer;
function GetState(AIndex: Integer): TCheckBoxState;
procedure SetChecked(const AIndex: Integer; const AValue: Boolean);
procedure SendItemChecked(const AIndex: Integer; const AChecked: Boolean);
procedure SendItemState(const AIndex: Integer; const AState: TCheckBoxState);
procedure DoChange(var Msg: TLMessage); message LM_CHANGED;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure SetState(AIndex: Integer; const AValue: TCheckBoxState);
protected
procedure AssignItemDataToCache(const AIndex: Integer; const AData: Pointer); override;
procedure AssignCacheToItemData(const AIndex: Integer; const AData: Pointer); override;
@ -59,7 +62,11 @@ type
procedure ItemClick(const AIndex: Integer);
public
constructor Create(AOwner: TComponent); override;
property Checked[const AIndex: Integer]: Boolean read GetChecked write SetChecked;
procedure Toggle(AIndex: Integer);
property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
property Checked[AIndex: Integer]: Boolean read GetChecked write SetChecked;
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;
@ -71,6 +78,7 @@ type
TCheckListBox = class(TCustomCheckListBox)
published
property Align;
property AllowGrayed;
property Anchors;
property BorderSpacing;
property BorderStyle;
@ -124,7 +132,7 @@ end;
type
PCachedItemData = ^TCachedItemData;
TCachedItemData = Boolean;
TCachedItemData = TCheckBoxState;
{ TCustomCheckListBox }
@ -132,15 +140,14 @@ procedure TCustomCheckListBox.AssignCacheToItemData(const AIndex: Integer;
const AData: Pointer);
begin
inherited AssignCacheToItemData(AIndex, AData);
if PCachedItemData(AData + FItemDataOffset)^
then SendItemChecked(AIndex, True);
SendItemState(AIndex, PCachedItemData(AData + FItemDataOffset)^);
end;
procedure TCustomCheckListBox.AssignItemDataToCache(const AIndex: Integer;
const AData: Pointer);
begin
inherited AssignItemDataToCache(AIndex, AData);
PCachedItemData(AData + FItemDataOffset)^ := Checked[AIndex];
PCachedItemData(AData + FItemDataOffset)^ := State[AIndex];
end;
constructor TCustomCheckListBox.Create(AOwner: TComponent);
@ -150,6 +157,18 @@ begin
FItemDataOffset := inherited GetCachedDataSize;
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]);
@ -165,12 +184,7 @@ end;
function TCustomCheckListBox.GetChecked(const AIndex: Integer): Boolean;
begin
CheckIndex(AIndex);
if HandleAllocated then
Result := TWSCustomCheckListBoxClass(WidgetSetClass).GetChecked(Self, AIndex)
else
Result := PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^;
Result := State[AIndex] <> cbUnchecked;
end;
function TCustomCheckListBox.GetCount: integer;
@ -178,34 +192,51 @@ begin
Result := Items.Count;
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)^;
end;
procedure TCustomCheckListBox.KeyDown(var Key: Word; Shift: TShiftState);
var
Index: Integer;
begin
if (Key = VK_SPACE) and (Shift=[]) then begin
if (Key = VK_SPACE) and (Shift=[]) then
begin
Index := ItemIndex;
Checked[Index]:=not Checked[Index];
Checked[Index] := not Checked[Index];
ItemClick(Index);
Key:=VK_UNKNOWN;
Key := VK_UNKNOWN;
end else
inherited KeyDown(Key,Shift);
end;
procedure TCustomCheckListBox.SendItemChecked(const AIndex: Integer;
const AChecked: Boolean);
procedure TCustomCheckListBox.SetState(AIndex: Integer;
const AValue: TCheckBoxState);
begin
CheckIndex(AIndex);
if HandleAllocated
then SendItemState(AIndex, AValue)
else PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^ := AValue;
end;
procedure TCustomCheckListBox.SendItemState(const AIndex: Integer;
const AState: TCheckBoxState);
begin
if HandleAllocated then
TWSCustomCheckListBoxClass(WidgetSetClass).SetChecked(Self,AIndex,AChecked);
TWSCustomCheckListBoxClass(WidgetSetClass).SetState(Self, AIndex, AState);
end;
procedure TCustomCheckListBox.SetChecked(const AIndex: Integer;
const AValue: Boolean);
begin
CheckIndex(AIndex);
if HandleAllocated
then SendItemChecked(AIndex, AValue)
else PCachedItemData(GetCachedData(AIndex) + FItemDataOffset)^ := AValue;
SetState(AIndex, cbChecked);
end;
procedure TCustomCheckListBox.ClickCheck;
@ -221,7 +252,7 @@ end;
procedure TCustomCheckListBox.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('Data', @ReadData, @WriteData,Items.Count>0);
Filer.DefineBinaryProperty('Data', @ReadData, @WriteData, Items.Count > 0);
end;
procedure TCustomCheckListBox.ReadData(Stream: TStream);
@ -231,13 +262,15 @@ var
i: Integer;
v: Integer;
begin
ChecksCount:=ReadLRSInteger(Stream);
if ChecksCount>0 then begin
SetLength(Checks,ChecksCount);
ChecksCount := ReadLRSInteger(Stream);
if ChecksCount > 0 then
begin
SetLength(Checks, ChecksCount);
Stream.ReadBuffer(Checks[1], ChecksCount);
for i:=0 to ChecksCount-1 do begin
v:=ord(Checks[i+1]);
Checked[i]:=((v and 1)>0);
for i:=0 to ChecksCount-1 do
begin
v := ord(Checks[i+1]);
Checked[i] := ((v and 1) > 0);
//debugln('TCustomCheckListBox.ReadData Checked[',dbgs(i),']=',dbgs(Checked[i]),' v=',dbgs(v));
end;
end;
@ -251,14 +284,16 @@ var
v: Integer;
begin
ChecksCount:=Items.Count;
WriteLRSInteger(Stream,ChecksCount);
if ChecksCount>0 then begin
SetLength(Checks,ChecksCount);
for i:=0 to ChecksCount-1 do begin
v:=0;
if Checked[i] then inc(v,1);
WriteLRSInteger(Stream, ChecksCount);
if ChecksCount>0 then
begin
SetLength(Checks, ChecksCount);
for i:=0 to ChecksCount-1 do
begin
v := 0;
if Checked[i] then inc(v, 1);
//debugln('TCustomCheckListBox.WriteData Checked[',dbgs(i),']=',dbgs(Checked[i]));
Checks[i+1]:=chr(v);
Checks[i+1] := chr(v);
end;
Stream.WriteBuffer(Checks[1], ChecksCount);
end;

View File

@ -47,10 +47,10 @@ type
public
class function CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): TLCLIntfHandle; override;
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
@ -74,23 +74,28 @@ begin
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomCheckListBox.GetChecked
Method: TCarbonWSCustomCheckListBox.GetState
Params: ACustomCheckListBox - LCL custom check list box
AIndex - Item index
Returns: If the specified item in check list box in Carbon interface is
checked
checked, grayed or unchecked
------------------------------------------------------------------------------}
class function TCarbonWSCustomCheckListBox.GetChecked(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): boolean;
class function TCarbonWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
begin
Result := false;
if not CheckHandle(ACheckListBox, Self, 'GetChecked') then Exit;
if not CheckHandle(ACheckListBox, Self, 'GetState') then Exit;
Result := TCarbonCheckListBox(ACheckListBox.Handle).GetItemChecked(AIndex);
// TODO: grayed state
if TCarbonCheckListBox(ACheckListBox.Handle).GetItemChecked(AIndex) then
Result := cbChecked
else
Result := cbUnchecked;
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomCheckListBox.SetChecked
Method: TCarbonWSCustomCheckListBox.SetState
Params: ACustomCheckListBox - LCL custom check list box
AIndex - Item index to change checked value
AChecked - New checked value
@ -98,13 +103,14 @@ end;
Changes checked value of item with the specified index of check list box in
Carbon interface
------------------------------------------------------------------------------}
class procedure TCarbonWSCustomCheckListBox.SetChecked(
class procedure TCarbonWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AChecked: boolean);
const AState: TCheckBoxState);
begin
if not CheckHandle(ACheckListBox, Self, 'SetChecked') then Exit;
if not CheckHandle(ACheckListBox, Self, 'SetState') then Exit;
TCarbonCheckListBox(ACheckListBox.Handle).SetItemChecked(AIndex, AChecked);
// TODO: grayed state
TCarbonCheckListBox(ACheckListBox.Handle).SetItemChecked(AIndex, AState <> cbUnchecked);
end;
initialization

View File

@ -27,7 +27,7 @@ unit GtkWSCheckLst;
interface
uses
CheckLst, WSCheckLst, WSLCLClasses,
CheckLst, StdCtrls, WSCheckLst, WSLCLClasses,
{$IFDEF gtk2}
glib2, gdk2pixbuf, gdk2, gtk2, Pango,
{$ELSE}
@ -43,50 +43,66 @@ type
private
protected
public
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
implementation
class function TGtkWSCustomCheckListBox.GetChecked(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): boolean;
class function TGtkWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
var
Widget : PGtkWidget; // pointer to gtk-widget (local use when neccessary)
ChildWidget : PGtkWidget; // generic pointer to a child gtk-widget
Widget : PGtkWidget; // pointer to gtk-widget (local use when neccessary)
ChildWidget: PGtkWidget; // generic pointer to a child gtk-widget
// (local use when neccessary)
ListItem : PGtkListItem;
ListItem : PGtkListItem;
begin
Result := false;
Result := cbUnChecked;
{ Get the child in question of that index }
Widget := GetWidgetInfo(Pointer(ACheckListBox.Handle),True)^.CoreWidget;
ListItem := g_list_nth_data(PGtkList(Widget)^.children, AIndex);
if ListItem <> nil then
if ListItem <> nil then
begin
ChildWidget := PPointer(PGTKBox(PGtkBin(ListItem)^.child)^.Children^.Data)^;
if (ChildWidget <> nil)
and gtk_toggle_button_get_active(PGTKToggleButton(ChildWidget))
then Result := true;
if (ChildWidget <> nil) then
begin
if (gtk_object_get_data(PgtkObject(ChildWidget), 'Grayed') <> nil) then
Result:=cbGrayed
else
if gtk_toggle_button_get_active(PGTKToggleButton(ChildWidget)) then
Result := cbChecked
else
Result := cbUnChecked;
end;
end;
end;
class procedure TGtkWSCustomCheckListBox.SetChecked(
class procedure TGtkWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AChecked: boolean);
const AState: TCheckBoxState);
var
Widget, ChildWidget: PGtkWidget;
ListItem: PGtkListItem;
begin
Widget := GetWidgetInfo(Pointer(ACheckListBox.Handle), True)^.CoreWidget;
ListItem := g_list_nth_data(PGtkList(Widget)^.children, AIndex);
if ListItem <> nil then
if ListItem <> nil then
begin
ChildWidget := PPointer(PGTKBox(PGtkBin(ListItem)^.child)^.Children^.Data)^;
if (ChildWidget <> nil)
then gtk_toggle_button_set_active(PGTKToggleButton(ChildWidget), AChecked);
if (ChildWidget <> nil) then
begin
LockOnChange(PGtkObject(ChildWidget), 1);
if AState = cbGrayed then
gtk_object_set_data(PGtkObject(ChildWidget), 'Grayed', ChildWidget)
else
gtk_object_set_data(PGtkObject(ChildWidget), 'Grayed', nil);
gtk_toggle_button_set_active(PGtkToggleButton(ChildWidget), AState = cbChecked);
LockOnChange(PGtkObject(ChildWidget), -1);
end;
end;
end;

View File

@ -35,7 +35,7 @@ Gtk2, GLib2, GtkDef,
// To get as little as posible circles,
// uncomment only when needed for registration
////////////////////////////////////////////////////
CheckLst, Controls, LCLType, Classes, LMessages,
CheckLst, StdCtrls, Controls, LCLType, SysUtils, Classes, LMessages,
////////////////////////////////////////////////////
WSCheckLst, WSLCLClasses,
Gtk2WSStdCtrls;
@ -44,51 +44,50 @@ type
{ TGtk2WSCheckListBox }
{ TGtk2WSCustomCheckListBox }
TGtk2WSCustomCheckListBox = class(TWSCustomCheckListBox)
private
class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
protected
public
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
implementation
uses GtkWSControls, GtkProc;
uses
GtkWSControls, GtkProc;
{ TGtk2WSCheckListBox }
procedure Gtk2WS_CheckListBoxDataFunc(tree_column: PGtkTreeViewColumn;
cell: PGtkCellRenderer; tree_model: PGtkTreeModel; iter: PGtkTreeIter; data: Pointer); cdecl;
var
b: byte;
AValue: TCheckBoxState;
begin
gtk_tree_model_get(tree_model, iter, [0, @b, -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);
end;
procedure Gtk2WS_CheckListBoxToggle(cellrenderertoggle : PGtkCellRendererToggle;
arg1 : PGChar; WidgetInfo: PWidgetInfo); cdecl;
var
aWidget : PGTKWidget;
aTreeModel : PGtkTreeModel;
aTreeIter : TGtkTreeIter;
value : pgValue;
Mess: TLMessage;
begin
{$IFDEF EventTrace}
EventTrace('Gtk2WS_CheckListBoxToggle', WidgetInfo^.LCLObject);
{$ENDIF}
aWidget := WidgetInfo^.CoreWidget;
aTreeModel := gtk_tree_view_get_model (GTK_TREE_VIEW(aWidget));
if (gtk_tree_model_get_iter_from_string (aTreeModel, @aTreeIter, arg1)) then begin
// aTreeIter.stamp := GTK_LIST_STORE (aTreeModel)^.stamp; //strange hack
value := g_new0(SizeOf(TgValue), 1);
gtk_tree_model_get_value(aTreeModel, @aTreeIter, 0, value);
g_value_set_boolean(value, not g_value_get_boolean(value));
gtk_list_store_set_value (GTK_LIST_STORE (aTreeModel), @aTreeIter, 0, value);
g_value_unset(value);
g_free(value);
end;
TCheckListBox(widgetInfo^.lclObject).Toggle(StrToInt(arg1));
Mess.Msg := LM_CHANGED;
Val(arg1, Mess.WParam);
Mess.Result := 0;
@ -98,22 +97,11 @@ end;
procedure Gtk2WS_CheckListBoxRowActivate(treeview : PGtkTreeView;
arg1 : PGtkTreePath; arg2 : PGtkTreeViewColumn; WidgetInfo: PWidgetInfo); cdecl;
var
aTreeModel : PGtkTreeModel;
aTreeIter : TGtkTreeIter;
value : PGValue;
APathStr: Pgchar;
begin
aTreeModel := gtk_tree_view_get_model (treeview);
if (gtk_tree_model_get_iter (aTreeModel, @aTreeIter, arg1)) then begin
// aTreeIter.stamp := GTK_LIST_STORE (aTreeModel)^.stamp; //strange hack
value := g_new0(SizeOf(TgValue), 1);
gtk_tree_model_get_value(aTreeModel, @aTreeIter, 0, value);
g_value_set_boolean(value, not g_value_get_boolean(value));
gtk_list_store_set_value (GTK_LIST_STORE (aTreeModel), @aTreeIter, 0, value);
g_value_unset(value);
g_free(value);
end;
APathStr := gtk_tree_path_to_string(arg1);
TCheckListBox(widgetInfo^.lclObject).Toggle(StrToInt(APathStr));
g_free(APathStr);
end;
class procedure TGtk2WSCustomCheckListBox.SetCallbacks(const AGtkWidget: PGtkWidget;
@ -127,40 +115,6 @@ begin
//SignalConnect(PGtkWidget(Selection), 'changed', @Gtk2WS_ListBoxChange, AWidgetInfo);
end;
class function TGtk2WSCustomCheckListBox.GetChecked(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer): boolean;
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
begin
Result:=False;
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_tree_model_get(ListStore, @Iter, [0, @Result, -1]);
end;
class procedure TGtk2WSCustomCheckListBox.SetChecked(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AChecked: 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, [0, AChecked, -1]);
end;
class function TGtk2WSCustomCheckListBox.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
var
@ -183,21 +137,24 @@ begin
GTK_WIDGET_UNSET_FLAGS(PGtkScrolledWindow(p)^.vscrollbar, GTK_CAN_FOCUS);
gtk_scrolled_window_set_policy(PGtkScrolledWindow(p),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(PGtkScrolledWindow(p),GTK_SHADOW_IN);
gtk_scrolled_window_set_shadow_type(PGtkScrolledWindow(p), GTK_SHADOW_IN);
gtk_widget_show(p);
liststore := gtk_list_store_new (3,
[G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER, nil]);
TreeViewWidget:= gtk_tree_view_new_with_model (GTK_TREE_MODEL(liststore));
g_object_unref (G_OBJECT (liststore));
[G_TYPE_UCHAR, G_TYPE_STRING, G_TYPE_POINTER, nil]);
TreeViewWidget := gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(G_OBJECT(liststore));
// Check Column
renderer := gtk_cell_renderer_toggle_new();
column := gtk_tree_view_column_new_with_attributes(
'CHECKBTNS', renderer, ['active', 0, nil]);
column := gtk_tree_view_column_new;
gtk_tree_view_column_set_title(column, 'CHECKBTNS');
gtk_tree_view_column_pack_start(column, renderer, True);
gtk_tree_view_column_set_cell_data_func(column, renderer,
@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_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
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);
@ -207,12 +164,12 @@ begin
// Text Column
renderer := gtk_cell_renderer_text_new();
column := gtk_tree_view_column_new_with_attributes (
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_append_column(GTK_TREE_VIEW(TreeViewWidget), column);
gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (TreeViewWidget), False);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(TreeViewWidget), False);
gtk_container_add(GTK_CONTAINER(p), TreeViewWidget);
gtk_widget_show(TreeViewWidget);
@ -229,6 +186,47 @@ begin
SetCallbacks(p, WidgetInfo);
end;
class function TGtk2WSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
var
Iter : TGtkTreeIter;
TreeView: PGtkTreeView;
WidgetInfo: PWidgetInfo;
ListStore: PGtkTreeModel;
b: byte;
begin
Result := cbUnchecked;
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, [0, @b, -1]);
Result := TCheckBoxState(b);
end;
end;
class procedure TGtk2WSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
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
begin
gtk_list_store_set(ListStore, @Iter, [0, Byte(AState), -1]);
end;
end;
initialization
////////////////////////////////////////////////////

View File

@ -39,7 +39,7 @@ uses
Classes, SysUtils, Types, Math,
// LCL
LCLType, LCLProc, LCLIntf, LMessages, Buttons, Forms, Controls, ComCtrls,
ExtCtrls, StdCtrls, Menus, Dialogs;
ExtCtrls, StdCtrls, CheckLst, Menus, Dialogs;
type
// forward declarations

View File

@ -45,21 +45,39 @@ type
{ TQtWSCheckListBox }
{ TQtWSCustomCheckListBox }
TQtWSCustomCheckListBox = class(TWSCustomCheckListBox)
private
protected
public
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
implementation
class function TQtWSCustomCheckListBox.GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean;
const
LCLCheckStateToQtCheckStateMap: array[TCheckBoxState] of QtCheckState =
(
{cbUnchecked} QtUnchecked,
{cbChecked } QtChecked,
{cbGrayed } QtPartiallyChecked
);
QtCheckStateToLCLCheckStateMap: array[QtCheckState] of TCheckBoxState =
(
{QtUnchecked } cbUnchecked,
{QtPartiallyChecked} cbGrayed,
{QtChecked } cbChecked
);
class function TQtWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
var
QtListWidget: TQtListWidget;
AListWidget: QListWidgetH;
@ -68,11 +86,12 @@ begin
QtListWidget := TQtListWidget(ACheckListBox.Handle);
AListWidget := QListWidgetH(QtListWidget.Widget);
AItem := QListWidget_item(AListWidget, AIndex);
Result := QListWidgetItem_checkState(AItem) = QtChecked;
Result := QtCheckStateToLCLCheckStateMap[QListWidgetItem_checkState(AItem)];
end;
class procedure TQtWSCustomCheckListBox.SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean);
class procedure TQtWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
var
QtListWidget: TQtListWidget;
AListWidget: QListWidgetH;
@ -81,10 +100,7 @@ begin
QtListWidget := TQtListWidget(ACheckListBox.Handle);
AListWidget := QListWidgetH(QtListWidget.Widget);
AItem := QListWidget_item(AListWidget, AIndex);
if AChecked then
QListWidgetItem_setCheckState(AItem, QtChecked)
else QListWidgetItem_setCheckState(AItem, QtUnchecked);
QListWidgetItem_setCheckState(AItem, LCLCheckStateToQtCheckStateMap[AState]);
end;
initialization

View File

@ -562,8 +562,9 @@ var
if Windows.PtInRect(ItemRect, MousePos) then
begin
// item clicked: toggle
if I < TCheckListBox(lWinControl).Items.Count then begin
TCheckListBox(lWinControl).Checked[I] := not TCheckListBox(lWinControl).Checked[I];
if I < TCheckListBox(lWinControl).Items.Count then
begin
TCheckListBox(lWinControl).Toggle(I);
Message.Msg := LM_CHANGED;
Message.WParam := I;
DeliverMessage(lWinControl, Message);

View File

@ -426,27 +426,17 @@ begin
inherited Create(List, TheOwner);
with FDefaultItem do
begin
Checked := false;
State := cbUnchecked;
TheObject := nil;
end;
end;
function TWin32CheckListBoxStrings.GetChecked(const Index: Integer): Boolean;
function TWin32CheckListBoxStrings.GetState(Index: Integer): TCheckBoxState;
var
Data: PWin32CheckListBoxItemRecord;
begin
Data := GetItemRecord(Index, false);
Result := Data^.Checked
end;
procedure TWin32CheckListBoxStrings.SetChecked(const Index: Integer;
const AValue: Boolean);
var
ItemRecord: PWin32CheckListBoxItemRecord;
begin
ItemRecord := GetItemRecord(Index, true);
ItemRecord^.Checked := AValue;
SetItemRecord(Index, ItemRecord);
Result := Data^.State;
end;
function TWin32CheckListBoxStrings.GetItemRecord(const Index: Integer;
@ -470,6 +460,16 @@ begin
Windows.SendMessage(FWin32List, LB_SETITEMDATA, Index, LPARAM(ItemRecord));
end;
procedure TWin32CheckListBoxStrings.SetState(Index: Integer;
const AValue: TCheckBoxState);
var
ItemRecord: PWin32CheckListBoxItemRecord;
begin
ItemRecord := GetItemRecord(Index, true);
ItemRecord^.State := AValue;
SetItemRecord(Index, ItemRecord);
end;
procedure TWin32CheckListBoxStrings.Clear;
begin
DeleteItemRecords(FWin32List);

View File

@ -98,16 +98,18 @@ Type
PWin32CheckListBoxItemRecord = ^TWin32CheckListBoxItemRecord;
TWin32CheckListBoxItemRecord = record
TheObject: TObject;
Checked: Boolean;
State: TCheckBoxState;
end;
{ TWin32CheckListBoxStrings }
TWin32CheckListBoxStrings = class(TWin32ListStringList)
private
FDefaultItem: TWin32CheckListBoxItemRecord;
function GetChecked(const Index: Integer): Boolean;
procedure SetChecked(const Index: Integer; const AValue: Boolean);
function GetState(Index: Integer): TCheckBoxState;
function GetItemRecord(const Index: Integer; const CreateNew: boolean): PWin32CheckListBoxItemRecord;
procedure SetItemRecord(const Index: Integer; ItemRecord: PWin32CheckListBoxItemRecord);
procedure SetState(Index: Integer; const AValue: TCheckBoxState);
protected
function GetObject(Index: Integer): TObject; override;
procedure PutObject(Index: Integer; AObject: TObject); override;
@ -117,7 +119,7 @@ Type
class procedure DeleteItemRecord(const List: HWND; const Index: integer);
procedure Clear; override;
procedure Delete(Index: Integer); override;
property Checked[const Index: Integer]: Boolean read GetChecked write SetChecked;
property State[Index: Integer]: TCheckBoxState read GetState write SetState;
end;
TWin32CListStringList = Class(TStrings)

View File

@ -204,6 +204,7 @@ var
Brush: HBRUSH;
Rect: Windows.Rect;
Flags: Cardinal;
Details: TThemedElementDetails;
OldColor: COLORREF;
OldBackColor: COLORREF;
{$ifdef WindowsUnicodeSupport}
@ -224,14 +225,28 @@ var
DeleteObject(Brush);
// draw checkbox
Flags := DFCS_BUTTONCHECK;
if CheckListBox.Checked[Data^.ItemID] then
Flags := Flags or DFCS_CHECKED;
Rect.Left := Data^.rcItem.Left + 2;
Rect.Top := Data^.rcItem.Top + 2;
Rect.Bottom := Data^.rcItem.Bottom - 2;
Rect := Data^.rcItem;
InflateRect(Rect, -1, -1);
Rect.Right := Rect.Left + Rect.Bottom - Rect.Top;
Windows.DrawFrameControl(Data^._HDC, Rect, DFC_BUTTON, Flags);
if ThemeServices.ThemesEnabled then
begin
case CheckListBox.State[Data^.ItemID] of
cbUnchecked: Details := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal);
cbChecked: Details := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal);
cbGrayed: Details := ThemeServices.GetElementDetails(tbCheckBoxMixedNormal);
end;
ThemeServices.DrawElement(Data^._HDC, Details, Rect);
end
else
begin
Flags := DFCS_BUTTONCHECK;
case CheckListBox.State[Data^.ItemID] of
cbChecked: Flags := Flags or DFCS_CHECKED;
cbGrayed: Flags := Flags or DFCS_INACTIVE;
end;
Windows.DrawFrameControl(Data^._HDC, Rect, DFC_BUTTON, Flags);
end;
// draw text
Rect := Windows.Rect(Data^.rcItem);

View File

@ -41,26 +41,23 @@ type
{ TWin32WSCheckListBox }
{ TWin32WSCustomCheckListBox }
TWin32WSCustomCheckListBox = class(TWSCustomCheckListBox)
private
protected
public
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
implementation
class function TWin32WSCustomCheckListBox.GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean;
begin
Result := TWin32CheckListBoxStrings(ACheckListBox.Items).Checked[AIndex];
end;
class function TWin32WSCustomCheckListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;
var
Handle: HWND;
@ -70,18 +67,26 @@ begin
GetWindowInfo(Handle)^.List := Result;
end;
class procedure TWin32WSCustomCheckListBox.SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean);
class function TWin32WSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
begin
Result := TWin32CheckListBoxStrings(ACheckListBox.Items).State[AIndex];
end;
class procedure TWin32WSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
var
SizeRect: Windows.RECT;
Handle: HWND;
begin
TWin32CheckListBoxStrings(ACheckListBox.Items).Checked[AIndex] := AChecked;
TWin32CheckListBoxStrings(ACheckListBox.Items).State[AIndex] := AState;
// redraw control
Handle := ACheckListBox.Handle;
Windows.SendMessage(Handle, LB_GETITEMRECT, AIndex, LPARAM(@SizeRect));
Windows.InvalidateRect(Handle, @SizeRect, false);
Windows.InvalidateRect(Handle, @SizeRect, False);
end;
initialization

View File

@ -387,28 +387,19 @@ end;
constructor TWinCECheckListBoxStrings.Create(List : HWND; TheOwner: TWinControl);
begin
inherited Create(List, TheOwner);
with FDefaultItem do begin
Checked := false;
with FDefaultItem do
begin
State := cbUnchecked;
TheObject := nil;
end;
end;
function TWinCECheckListBoxStrings.GetChecked(const Index: Integer): Boolean;
function TWinCECheckListBoxStrings.GetState(AIndex: Integer): TCheckBoxState;
var
Data: PWinCECheckListBoxItemRecord;
begin
Data := GetItemRecord(Index, false);
Result := Data^.Checked
end;
procedure TWinCECheckListBoxStrings.SetChecked(const Index: Integer;
const AValue: Boolean);
var
ItemRecord: PWinCECheckListBoxItemRecord;
begin
ItemRecord := GetItemRecord(Index, true);
ItemRecord^.Checked := AValue;
SetItemRecord(Index, ItemRecord);
Result := Data^.State
end;
function TWinCECheckListBoxStrings.GetItemRecord(const Index: Integer;
@ -430,6 +421,16 @@ begin
Windows.SendMessage(FWinCEList, LB_SETITEMDATA, Index, LPARAM(ItemRecord));
end;
procedure TWinCECheckListBoxStrings.SetState(AIndex: Integer;
const AValue: TCheckBoxState);
var
ItemRecord: PWinCECheckListBoxItemRecord;
begin
ItemRecord := GetItemRecord(Index, true);
ItemRecord^.State := AValue;
SetItemRecord(Index, ItemRecord);
end;
procedure TWinCECheckListBoxStrings.Clear;
begin
DeleteItemRecords(FWinCEList);

View File

@ -89,16 +89,18 @@ Type
PWinCECheckListBoxItemRecord = ^TWinCECheckListBoxItemRecord;
TWinCECheckListBoxItemRecord = record
TheObject: TObject;
Checked: Boolean;
State: TCheckBoxState;
end;
{ TWinCECheckListBoxStrings }
TWinCECheckListBoxStrings = class(TWinCEListStringList)
private
FDefaultItem: TWinCECheckListBoxItemRecord;
function GetChecked(const Index: Integer): Boolean;
procedure SetChecked(const Index: Integer; const AValue: Boolean);
function GetState(AIndex: Integer): TCheckBoxState;
function GetItemRecord(const Index: Integer; const CreateNew: boolean): PWinCECheckListBoxItemRecord;
procedure SetItemRecord(const Index: Integer; ItemRecord: PWinCECheckListBoxItemRecord);
procedure SetState(AIndex: Integer; const AValue: TCheckBoxState);
protected
function GetObject(Index: Integer): TObject; override;
procedure PutObject(Index: Integer; AObject: TObject); override;
@ -108,7 +110,7 @@ Type
class procedure DeleteItemRecord(const List: HWND; const Index: integer);
procedure Clear; override;
procedure Delete(Index: Integer); override;
property Checked[const Index: Integer]: Boolean read GetChecked write SetChecked;
property State[AIndex: Integer]: TCheckBoxState read GetState write SetState;
end;
TWinCECListStringList = Class(TStrings)

View File

@ -40,26 +40,21 @@ type
{ TWinCEWSCheckListBox }
{ TWinCEWSCustomCheckListBox }
TWinCEWSCustomCheckListBox = class(TWSCustomCheckListBox)
private
protected
public
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; override;
class function GetStrings(const ACustomListBox: TCustomListBox): TStrings; override;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); override;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; override;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); override;
end;
implementation
class function TWinCEWSCustomCheckListBox.GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean;
begin
Result := TWinCECheckListBoxStrings(ACheckListBox.Items).Checked[AIndex];
end;
class function TWinCEWSCustomCheckListBox.GetStrings(const ACustomListBox: TCustomListBox): TStrings;
var
Handle: HWND;
@ -69,13 +64,21 @@ begin
GetWindowInfo(Handle)^.List := Result;
end;
class procedure TWinCEWSCustomCheckListBox.SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean);
class function TWinCEWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
begin
Result := TWinCECheckListBoxStrings(ACheckListBox.Items).State[AIndex];
end;
class procedure TWinCEWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
var
SizeRect: Windows.RECT;
Handle: HWND;
begin
TWinCECheckListBoxStrings(ACheckListBox.Items).Checked[AIndex] := AChecked;
TWinCECheckListBoxStrings(ACheckListBox.Items).State[AIndex] := AChecked;
// redraw control
Handle := ACheckListBox.Handle;

View File

@ -44,32 +44,36 @@ uses
// To get as little as posible circles,
// uncomment only when needed for registration
////////////////////////////////////////////////////
CheckLst,
StdCtrls, CheckLst,
////////////////////////////////////////////////////
WSLCLClasses, WSStdCtrls;
type
{ TWSCheckListBox }
{ TWSCustomCheckListBox }
TWSCustomCheckListBox = class(TWSCustomListBox)
class function GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean; virtual;
class procedure SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean); virtual;
class function GetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): TCheckBoxState; virtual;
class procedure SetState(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AState: TCheckBoxState); virtual;
end;
TWSCustomCheckListBoxClass = class of TWSCustomCheckListBox;
implementation
class function TWSCustomCheckListBox.GetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer): boolean;
class function TWSCustomCheckListBox.GetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer
): TCheckBoxState;
begin
Result := false;
Result := cbUnchecked;
end;
class procedure TWSCustomCheckListBox.SetChecked(const ACheckListBox: TCustomCheckListBox;
const AIndex: integer; const AChecked: boolean);
class procedure TWSCustomCheckListBox.SetState(
const ACheckListBox: TCustomCheckListBox; const AIndex: integer;
const AState: TCheckBoxState);
begin
end;
@ -81,4 +85,4 @@ initialization
////////////////////////////////////////////////////
// RegisterWSComponent(TCustomCheckListBox, TWSCustomCheckListBox);
////////////////////////////////////////////////////
end.
end.