LCL, custom handling of checkbox states (windows, this enables the use of allowgrayed without cbGrayed state, specially useful for dbcheckbox), fix cbGrayed state under gtk2

git-svn-id: trunk@20012 -
This commit is contained in:
jesus 2009-05-17 17:00:47 +00:00
parent 531e682b04
commit 84cead9009
7 changed files with 72 additions and 35 deletions

View File

@ -38,15 +38,6 @@ begin
end; end;
end; end;
procedure TCustomCheckBox.SetAllowGrayed(const AValue: Boolean);
begin
if AValue<>FAllowGrayed then begin
FAllowGrayed := AValue;
if HandleAllocated then
TWSCustomCheckBoxClass(WidgetSetClass).AllowGrayedChanged(Self);
end;
end;
{------------------------------------------------------------------------------ {------------------------------------------------------------------------------
Method: TCustomCheckBox.GetState Method: TCustomCheckBox.GetState
Params: none Params: none

View File

@ -471,6 +471,23 @@ end;
function gtktoggledCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl; function gtktoggledCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
var var
Mess : TLMessage; Mess : TLMessage;
procedure ChangeCheckbox(AGrayed,AChecked: boolean);
begin
LockOnChange(PgtkObject(Widget),1);
{$IFDEF GTK1}
if AGrayed then
gtk_object_set_data(PgtkObject(Widget), 'Grayed', Widget)
else
gtk_object_set_data(PgtkObject(Widget), 'Grayed', nil);
{$ENDIF}
{$IFDEF GTK2}
gtk_toggle_button_set_Inconsistent(PGtkToggleButton(Widget), AGrayed);
{$ENDIF}
gtk_toggle_button_set_active(PGtkToggleButton(Widget), AChecked);
LockOnChange(PgtkObject(Widget),-1);
end;
begin begin
//DebugLn('gtktoggledCB ',DbgSName(TObject(Data))); //DebugLn('gtktoggledCB ',DbgSName(TObject(Data)));
Result := CallBackDefaultReturn; Result := CallBackDefaultReturn;
@ -480,7 +497,26 @@ begin
if LockOnChange(PgtkObject(Widget),0) > 0 then Exit; if LockOnChange(PgtkObject(Widget),0) > 0 then Exit;
if GtkWidgetIsA(Widget,gtk_toggle_button_get_type) then begin if GtkWidgetIsA(Widget,gtk_toggle_button_get_type) then begin
gtk_object_set_data(PgtkObject(Widget), 'Grayed', nil);
if TObject(Data) is TCustomCheckbox then begin
{$IFDEF GTK1}
if gtk_object_get_data(PgtkObject(Widget), 'Grayed')<>nil then
ChangeCheckbox(false, true)
else
if TCustomCheckbox(Data).AllowGrayed and
gtk_toggle_button_get_active(PGtkToggleButton(Widget)) then
ChangeCheckbox(true, false);
{$ENDIF}
{$IFDEF GTK2}
if gtk_toggle_button_get_inconsistent(PGtkToggleButton(Widget)) then
ChangeCheckbox(false, true)
else
if TCustomCheckbox(Data).AllowGrayed and
gtk_toggle_button_get_active(PGtkToggleButton(Widget)) then
ChangeCheckbox(true, false);
{$ENDIF}
end;
end; end;
Mess.Msg := LM_CHANGED; Mess.Msg := LM_CHANGED;

View File

@ -800,13 +800,13 @@ var
ToggleButton: PGtkToggleButton; ToggleButton: PGtkToggleButton;
begin begin
ToggleButton:=PGtkToggleButton(ACustomCheckBox.Handle); ToggleButton:=PGtkToggleButton(ACustomCheckBox.Handle);
if ACustomCheckBox.AllowGrayed if gtk_toggle_button_get_inconsistent(ToggleButton) then
and gtk_toggle_button_get_inconsistent(ToggleButton) then Result := cbGrayed
Result:=cbGrayed else
else if gtk_toggle_button_get_active(ToggleButton) then if gtk_toggle_button_get_active(ToggleButton) then
Result := cbChecked Result := cbChecked
else else
Result := cbUnChecked; Result := cbUnchecked;
end; end;
class procedure TGtk2WSCustomCheckBox.SetShortCut( class procedure TGtk2WSCustomCheckBox.SetShortCut(
@ -830,8 +830,8 @@ begin
GtkObject := PGtkObject(ACustomCheckBox.Handle); GtkObject := PGtkObject(ACustomCheckBox.Handle);
LockOnChange(GtkObject,1); LockOnChange(GtkObject,1);
ToggleButton:=PGtkToggleButton(GtkObject); ToggleButton:=PGtkToggleButton(GtkObject);
gtk_toggle_button_set_active(ToggleButton, NewState=cbChecked);
gtk_toggle_button_set_inconsistent(ToggleButton, NewState=cbGrayed); gtk_toggle_button_set_inconsistent(ToggleButton, NewState=cbGrayed);
gtk_toggle_button_set_active(ToggleButton, NewState=cbChecked);
LockOnChange(GtkObject,-1); LockOnChange(GtkObject,-1);
end; end;

View File

@ -1351,6 +1351,33 @@ begin
// buddy controls use 'awincontrol' to designate associated wincontrol // buddy controls use 'awincontrol' to designate associated wincontrol
if lWinControl = nil then if lWinControl = nil then
lWinControl := GetWindowInfo(HWND(LParam))^.AWinControl; lWinControl := GetWindowInfo(HWND(LParam))^.AWinControl;
if lWinControl is TCustomCheckbox then begin
case HIWORD(WParam) of
BN_CLICKED:
begin
// to allow cbGrayed state at the same time as not AllowGrayed
// in checkboxes (needed by dbcheckbox for null fields) we need
// to handle checkbox state ourselves, according to msdn state
// sequence goes from checked->cleared->grayed etc.
Flags := SendMessage(lWinControl.Handle, BM_GETCHECK, 0, 0);
if (Flags=BST_CHECKED) then
Flags := BST_UNCHECKED
else
if (Flags=BST_UNCHECKED) and
TCustomCheckbox(lWinControl).AllowGrayed then
Flags := BST_INDETERMINATE
else
Flags := BST_CHECKED;
Windows.SendMessage(lWinControl.Handle, BM_SETCHECK,
Windows.WPARAM(flags), 0);
LMessage.Msg := LM_CLICKED;
end;
BN_KILLFOCUS:
LMessage.Msg := LM_EXIT;
end
end else
if lWinControl is TButtonControl then if lWinControl is TButtonControl then
case HIWORD(WParam) of case HIWORD(WParam) of
BN_CLICKED: LMessage.Msg := LM_CLICKED; BN_CLICKED: LMessage.Msg := LM_CLICKED;

View File

@ -257,7 +257,6 @@ type
class procedure SetBiDiMode(const AWinControl: TWinControl; UseRightToLeftAlign, class procedure SetBiDiMode(const AWinControl: TWinControl; UseRightToLeftAlign,
UseRightToLeftReading, UseRightToLeftScrollBar : Boolean); override; UseRightToLeftReading, UseRightToLeftScrollBar : Boolean); override;
class procedure SetState(const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState); override; class procedure SetState(const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState); override;
class procedure AllowGrayedChanged(const ACustomCheckbox: TCustomCheckbox); override;
end; end;
{ TWin32WSCheckBox } { TWin32WSCheckBox }
@ -1467,10 +1466,7 @@ begin
begin begin
pClassName := @ButtonClsName[0]; pClassName := @ButtonClsName[0];
WindowTitle := StrCaption; WindowTitle := StrCaption;
if TCustomCheckBox(AWinControl).AllowGrayed then Flags := Flags or BS_3STATE;
Flags := Flags or BS_AUTO3STATE
else
Flags := Flags or BS_AUTOCHECKBOX;
end; end;
// create window // create window
FinishCreateWindow(AWinControl, Params, false); FinishCreateWindow(AWinControl, Params, false);
@ -1538,12 +1534,6 @@ begin
Windows.SendMessage(ACustomCheckBox.Handle, BM_SETCHECK, Flags, 0); Windows.SendMessage(ACustomCheckBox.Handle, BM_SETCHECK, Flags, 0);
end; end;
class procedure TWin32WSCustomCheckBox.AllowGrayedChanged(
const ACustomCheckbox: TCustomCheckbox);
begin
RecreateWnd(ACustomCheckbox);
end;
{ TWin32WSToggleBox } { TWin32WSToggleBox }
class function TWin32WSToggleBox.CreateHandle(const AWinControl: TWinControl; class function TWin32WSToggleBox.CreateHandle(const AWinControl: TWinControl;

View File

@ -1166,7 +1166,6 @@ type
FAllowGrayed: Boolean; FAllowGrayed: Boolean;
FState: TCheckBoxState; FState: TCheckBoxState;
FShortCut: TShortcut; FShortCut: TShortcut;
procedure SetAllowGrayed(const AValue: Boolean);
procedure SetState(Value: TCheckBoxState); procedure SetState(Value: TCheckBoxState);
function GetState: TCheckBoxState; function GetState: TCheckBoxState;
procedure DoChange(var Msg); message LM_CHANGED; procedure DoChange(var Msg); message LM_CHANGED;
@ -1189,7 +1188,7 @@ type
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
public public
property AutoSize default true; property AutoSize default true;
property AllowGrayed: Boolean read FAllowGrayed write SetAllowGrayed default false; property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default false;
property State: TCheckBoxState read GetState write SetState default cbUnchecked; property State: TCheckBoxState read GetState write SetState default cbUnchecked;
property TabStop default true; property TabStop default true;
property OnChange; property OnChange;

View File

@ -222,7 +222,6 @@ type
class procedure SetShortCut(const ACustomCheckBox: TCustomCheckBox; class procedure SetShortCut(const ACustomCheckBox: TCustomCheckBox;
const OldShortCut, NewShortCut: TShortCut); virtual; const OldShortCut, NewShortCut: TShortCut); virtual;
class procedure SetState(const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState); virtual; class procedure SetState(const ACustomCheckBox: TCustomCheckBox; const NewState: TCheckBoxState); virtual;
class procedure AllowGrayedChanged(const ACustomCheckbox: TCustomCheckbox); virtual;
end; end;
TWSCustomCheckBoxClass = class of TWSCustomCheckBox; TWSCustomCheckBoxClass = class of TWSCustomCheckBox;
@ -579,11 +578,6 @@ class procedure TWSCustomCheckBox.SetState(const ACustomCheckBox: TCustomCheckBo
begin begin
end; end;
class procedure TWSCustomCheckBox.AllowGrayedChanged(
const ACustomCheckbox: TCustomCheckbox);
begin
end;
{ WidgetSetRegistration } { WidgetSetRegistration }
procedure RegisterCustomScrollBar; procedure RegisterCustomScrollBar;