{ ***************************************************************************** * CocoaWSCheckLst.pp * * --------------- * * * * * ***************************************************************************** ***************************************************************************** This file is part of the Lazarus Component Library (LCL) See the file COPYING.modifiedLGPL.txt, included in this distribution, for details about the license. ***************************************************************************** } unit CocoaWSCheckLst; {$mode objfpc}{$H+} {$modeswitch objectivec1} {$modeswitch objectivec2} interface uses // Libs MacOSAll, CocoaAll, Classes, sysutils, // LCL Controls, StdCtrls, CheckLst, LCLType, LCLMessageGlue, // Widgetset WSCheckLst, WSLCLClasses, // LCL Cocoa CocoaWSCommon, CocoaPrivate, CocoaUtils, CocoaWSStdCtrls, CocoaTables, CocoaScrollers; type { TCocoaCheckStringList } TCocoaCheckStringList = class(TCocoaStringList) protected procedure ExchangeItems(Index1, Index2: Integer); override; public ChkState : array of SInt8; procedure InsertItem(Index: Integer; const S: string; O: TObject); override; procedure Delete(Index: Integer); override; procedure Clear; override; end; { TLCLCheckboxListCallback } TLCLCheckboxListCallback = class(TLCLListBoxCallback, IListViewCallback) protected function AllocStrings(ATable: NSTableView): TCocoaStringList; override; public checklist: TCustomCheckListBox; constructor Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView); override; function GetItemCheckedAt(ARow, ACol: Integer; var CheckState: Integer): Boolean; override; procedure SetItemCheckedAt(ARow, ACol: Integer; CheckState: Integer); override; function GetCheckState(Index: Integer; var AState: Integer): Boolean; function SetCheckState(Index: Integer; AState: Integer; InvalidateCocoa: Boolean = true): Boolean; end; { TCocoaWSCustomCheckListBox } TCocoaWSCustomCheckListBox = class(TWSCustomCheckListBox) published class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle; 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; function CtrlToCheckList(ctrl: TWinControl; out tbl: TCocoaTableListView; out cb: TLCLCheckboxListCallback): Boolean; implementation function CtrlToCheckList(ctrl: TWinControl; out tbl: TCocoaTableListView; out cb: TLCLCheckboxListCallback): Boolean; begin Result := Assigned(ctrl) and (ctrl.HandleAllocated) and (ctrl.Handle <> 0); if not Result then begin tbl := nil; cb := nil; Exit; end; tbl:=TCocoaTableListView(NSSCrollView(ctrl.Handle).documentView); Result := Assigned(tbl); if Result then cb := TLCLCheckboxListCallback(tbl.lclGetCallback.GetCallbackObject) else cb := nil; end; { TCocoaCheckStringList } procedure TCocoaCheckStringList.ExchangeItems(Index1, Index2: Integer); var t : Integer; begin inherited ExchangeItems(Index1, Index2); t := ChkState[Index1]; ChkState[Index1] := ChkState[Index2]; ChkState[Index2] := t; end; procedure TCocoaCheckStringList.InsertItem(Index: Integer; const S: string; O: TObject); var cnt : integer; sz : integer; begin cnt := Count; inherited InsertItem(Index, S, O); if length(ChkState)0 then System.Move(ChkState[Index], ChkState[Index+1], sz); ChkState[Index] := 0; end; procedure TCocoaCheckStringList.Delete(Index: Integer); var sz : Integer; begin inherited Delete(Index); sz := (Count - Index) * sizeof(SInt8); if (sz>0) and (Index < Count) then System.Move(ChkState[Index+1], ChkState[Index], sz); end; procedure TCocoaCheckStringList.Clear; begin inherited Clear; SetLength(ChkState, 0); end; { TLCLCheckboxListCallback } function TLCLCheckboxListCallback.AllocStrings(ATable: NSTableView): TCocoaStringList; begin Result:=TCocoaCheckStringList.Create(ATable); end; constructor TLCLCheckboxListCallback.Create(AOwner: NSObject; ATarget: TWinControl; AHandleView: NSView); begin inherited Create(AOwner, ATarget, AHandleView); if ATarget is TCustomCheckListBox then checklist := TCustomCheckListBox(ATarget); end; function TLCLCheckboxListCallback.GetItemCheckedAt(ARow, ACol: Integer; var CheckState: Integer): Boolean; begin Result := GetCheckState(Arow, CheckState); end; procedure TLCLCheckboxListCallback.SetItemCheckedAt(ARow, ACol: Integer; CheckState: Integer); var changed : Boolean; begin changed := SetCheckState(ARow, CheckState, false); // returns true, if changed!s if changed then LCLSendChangedMsg(Target, ARow); end; function TLCLCheckboxListCallback.GetCheckState(Index: Integer; var AState: Integer): Boolean; var chkstr : TCocoaCheckStringList; begin Result := Assigned(strings) and (Index>=0) and (Index=0) and (Index AState; if Result then begin chkstr.ChkState[Index] := AState; if InvalidateCocoa and Assigned(listview) then listview.reloadDataForRow_column(Index, 0); end; end; { TCocoaWSCustomCheckListBox } {------------------------------------------------------------------------------ Method: TCocoaWSCustomCheckListBox.CreateHandle Params: AWinControl - LCL control AParams - Creation parameters Returns: Handle to the control in Cocoa interface Creates new check list box in Cocoa interface with the specified parameters ------------------------------------------------------------------------------} class function TCocoaWSCustomCheckListBox.CreateHandle( const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle; var list: TCocoaTableListView; scroll: TCocoaScrollView; begin list := AllocCocoaTableListView.lclInitWithCreateParams(AParams); if not Assigned(list) then begin Result := 0; Exit; end; list.callback := TLCLCheckboxListCallback.CreateWithView(list, AWinControl); list.lclSetFirstColumCheckboxes(true); //list.list := TCocoaStringList.Create(list); list.addTableColumn(NSTableColumn.alloc.init.autorelease); list.setHeaderView(nil); list.setDataSource(list); list.setDelegate(list); list.readOnly := true; //todo: //list.AllowMixedState := TCustomCheckListBox(AWinControl).AllowGrayed; list.isOwnerDraw := TCustomCheckListBox(AWinControl).Style in [lbOwnerDrawFixed, lbOwnerDrawVariable]; scroll := EmbedInScrollView(list); if not Assigned(scroll) then begin Result := 0; Exit; end; scroll.callback := list.callback; scroll.setHasVerticalScroller(true); scroll.setAutohidesScrollers(true); ScrollViewSetBorderStyle(scroll, TCustomCheckListBox(AWinControl).BorderStyle); UpdateFocusRing(list, TCustomCheckListBox(AWinControl).BorderStyle); Result := TLCLHandle(scroll); end; {------------------------------------------------------------------------------ Method: TCocoaWSCustomCheckListBox.GetState Params: ACustomCheckListBox - LCL custom check list box AIndex - Item index Returns: If the specified item in check list box in Cocoa interface is checked, grayed or unchecked ------------------------------------------------------------------------------} class function TCocoaWSCustomCheckListBox.GetState( const ACheckListBox: TCustomCheckListBox; const AIndex: integer): TCheckBoxState; var tbl: TCocoaTableListView; cb : TLCLCheckboxListCallback; cocoaSt: Integer; begin if not CtrlToCheckList(ACheckListBox, tbl, cb) then begin Result := cbUnchecked; Exit; end; if cb.GetCheckState(AIndex, cocoaSt) then case cocoaSt of NSOnState : Result := cbChecked; NSMixedState : Result := cbGrayed; else Result := cbUnchecked; end else Result := cbUnchecked; end; {------------------------------------------------------------------------------ Method: TCocoaWSCustomCheckListBox.SetState Params: ACustomCheckListBox - LCL custom check list box AIndex - Item index to change checked value AChecked - New checked value Changes checked value of item with the specified index of check list box in Cocoa interface ------------------------------------------------------------------------------} class procedure TCocoaWSCustomCheckListBox.SetState( const ACheckListBox: TCustomCheckListBox; const AIndex: integer; const AState: TCheckBoxState); var tbl: TCocoaTableListView; cb : TLCLCheckboxListCallback; cocoaSt: Integer; begin if not CtrlToCheckList(ACheckListBox, tbl, cb) then Exit; case AState of cbChecked: cocoaSt := NSOnState; cbGrayed: cocoaSt := NSMixedState; else cocoaSt := NSOffState; end; cb.SetCheckState(AIndex, cocoaSt, true); end; end.