Cocoa: support Canvas Font/Brush in OnDrawItem/OnCustomDraw/OnCustomDrawItem/OnCustomDrawSubItem for ListView/ListBox/CheckListBox, issue #39500

in NSTableView, cell drawing is out of order:
1. it is not necessary to draw rows first and then columns
2. row order is not fixed
3. column order is not fixed
therefore, in these callback functions, do not assume the settings in Canvas
This commit is contained in:
rich2014 2024-08-19 00:19:13 +08:00
parent 5abac68141
commit 85c17ebf3e
3 changed files with 97 additions and 8 deletions

View File

@ -7,7 +7,7 @@ interface
uses uses
Classes, SysUtils, Classes, SysUtils,
LclType, Controls, ComCtrls, LCLType, Graphics, Controls, ComCtrls,
CocoaAll, CocoaPrivate, CocoaCallback, CocoaWSCommon, CocoaGDIObjects; CocoaAll, CocoaPrivate, CocoaCallback, CocoaWSCommon, CocoaGDIObjects;
type type
@ -95,6 +95,7 @@ type
TCocoaTableViewProcessor = class TCocoaTableViewProcessor = class
function isInitializing( tv: NSTableView ): Boolean; virtual; abstract; function isInitializing( tv: NSTableView ): Boolean; virtual; abstract;
function getLCLControlCanvas( tv:NSTableView ): TCanvas; virtual; abstract;
procedure onReloadData( tv: NSTableView ); virtual; abstract; procedure onReloadData( tv: NSTableView ); virtual; abstract;
procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); virtual; abstract; procedure onSelectOneItem( tv: NSTableView; selection: NSIndexSet ); virtual; abstract;
procedure onSelectionChanged( tv: NSTableView ); virtual; abstract; procedure onSelectionChanged( tv: NSTableView ); virtual; abstract;

View File

@ -25,11 +25,12 @@ interface
uses uses
Classes, SysUtils, Classes, SysUtils,
MacOSAll, CocoaAll, LazLogger, LCLType, LCLMessageGlue, LMessages, Controls, Graphics,
ComCtrls, StdCtrls, ImgList, Forms,
MacOSAll, CocoaAll,
CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaListControl, CocoaPrivate, Cocoa_Extra, CocoaCallback, CocoaListControl,
CocoaConst, CocoaConfig, CocoaWSCommon, CocoaUtils, CocoaGDIObjects, CocoaConst, CocoaConfig, CocoaWSCommon, CocoaUtils, CocoaGDIObjects,
CocoaListView, CocoaTextEdits, CocoaListView, CocoaTextEdits;
LCLType, LCLMessageGlue, LMessages, Controls, ComCtrls, StdCtrls, ImgList, Forms;
type type
@ -92,6 +93,7 @@ type
procedure lclSetProcessor( processor: TCocoaTableViewProcessor ); message 'lclSetProcessor:'; procedure lclSetProcessor( processor: TCocoaTableViewProcessor ); message 'lclSetProcessor:';
procedure lclSetCheckBoxes( checkBoxes: Boolean); message 'lclSetCheckBoxes:'; procedure lclSetCheckBoxes( checkBoxes: Boolean); message 'lclSetCheckBoxes:';
function lclHasCheckBoxes: Boolean; message 'lclHasCheckBoxes'; function lclHasCheckBoxes: Boolean; message 'lclHasCheckBoxes';
function lclGetCanvas: TCanvas; message 'lclGetCanvas';
function tableView_viewForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): NSView; function tableView_viewForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: NSInteger): NSView;
function tableView_rowViewForRow(tableView: NSTableView; row: NSInteger): NSTableRowView; function tableView_rowViewForRow(tableView: NSTableView; row: NSInteger): NSTableRowView;
@ -237,6 +239,7 @@ type
TCocoaTableListViewProcessor = class( TCocoaTableListControlProcessor ) TCocoaTableListViewProcessor = class( TCocoaTableListControlProcessor )
public public
function isInitializing( tv: NSTableView ): Boolean; override; function isInitializing( tv: NSTableView ): Boolean; override;
function getLCLControlCanvas( tv: NSTableView ): TCanvas; override;
procedure onSelectionChanged( tv: NSTableView ); override; procedure onSelectionChanged( tv: NSTableView ); override;
end; end;
@ -328,6 +331,52 @@ begin
view.setHidden( True ); view.setHidden( True );
end; end;
procedure updateNSTextFieldWithTFont( cocoaField: NSTextField; lclFont: TFont );
var
saveFontColor: TColor;
cocoaFont: NSFont;
cocoaColor: NSColor;
begin
saveFontColor:= lclFont.Color;
lclFont.Color:= clDefault;
if NOT lclFont.isDefault then begin
cocoaFont:= TCocoaFont(lclFont.Reference.Handle).Font;
cocoaField.setFont( cocoaFont );
end;
lclFont.Color:= saveFontColor;
if lclFont.Color <> clDefault then begin
cocoaColor:= ColorToNSColor(ColorToRGB(lclFont.Color));
cocoaField.setTextColor( cocoaColor );
end;
end;
procedure drawNSViewBackground( view: NSView; lclBrush: TBrush );
var
ctx: TCocoaContext;
cocoaBrush: TCocoaBrush;
width: Integer;
height: Integer;
begin
if lclBrush.Color = clWindow then
Exit;
width:= Round( view.bounds.size.width );
height:= Round( view.bounds.size.height );
ctx := TCocoaContext.Create( NSGraphicsContext.currentContext );
ctx.InitDraw( width, height );
try
cocoaBrush:= TCocoaBrush( lclBrush.Reference.Handle );
ctx.Rectangle( 0, 0, width, height, True, cocoaBrush );
finally
ctx.Free;
end;
end;
procedure TCocoaTableRowView.drawRect(dirtyRect: NSRect); procedure TCocoaTableRowView.drawRect(dirtyRect: NSRect);
var var
done: Boolean; done: Boolean;
@ -341,6 +390,7 @@ begin
// it's a case where the default drawing must be skipped. // it's a case where the default drawing must be skipped.
hideAllSubviews( self ); hideAllSubviews( self );
end else begin end else begin
drawNSViewBackground( self, tableView.lclGetCanvas.Brush );
inherited drawRect( dirtyRect ); inherited drawRect( dirtyRect );
end; end;
end; end;
@ -408,6 +458,11 @@ begin
inherited addSubview(aView); inherited addSubview(aView);
end; end;
function TCocoaTableListView.lclGetCanvas: TCanvas;
begin
Result:= _processor.getLCLControlCanvas( self );
end;
procedure TCocoaTableListView.dealloc; procedure TCocoaTableListView.dealloc;
begin begin
FreeAndNil( _processor ); FreeAndNil( _processor );
@ -523,9 +578,17 @@ procedure TCocoaTableListView.drawRect(dirtyRect: NSRect);
var var
done: Boolean; done: Boolean;
begin begin
if CheckMainThread and Assigned(self.callback) then if NOT Assigned(self.callback) then
Exit;
if CheckMainThread then
self.callback.Draw(NSGraphicsContext.currentContext, bounds, dirtyRect); self.callback.Draw(NSGraphicsContext.currentContext, bounds, dirtyRect);
if NOT self.callback.isCustomDrawSupported then begin
inherited;
Exit;
end;
done:= self.lclCallCustomDraw( -1, -1, self.bounds.size, dirtyRect ); done:= self.lclCallCustomDraw( -1, -1, self.bounds.size, dirtyRect );
if done then begin if done then begin
@ -533,7 +596,8 @@ begin
// we can only hide the SubviewViews to get the same effect. // we can only hide the SubviewViews to get the same effect.
hideAllSubviews( self ); hideAllSubviews( self );
end else begin end else begin
inherited drawRect( dirtyRect ); drawNSViewBackground( self, self.lclGetCanvas.Brush );
inherited;
end; end;
end; end;
@ -1058,11 +1122,21 @@ var
row: Integer; row: Integer;
col: Integer; col: Integer;
done: Boolean; done: Boolean;
cocoaTLV: TCocoaTableListView;
begin begin
cocoaTLV:= TCocoaTableListView( _tableView );
if NOT Assigned(cocoaTLV.callback) then
Exit;
if NOT cocoaTLV.callback.isCustomDrawSupported then begin
inherited;
Exit;
end;
row:= _tableView.rowForView( self ); row:= _tableView.rowForView( self );
col:= _tableView.columnForView( self ); col:= _tableView.columnForView( self );
done:= TCocoaTableListView(_tableView).lclCallCustomDraw( done:= cocoaTLV.lclCallCustomDraw( row, col, self.bounds.size, dirtyRect );
row, col, self.bounds.size, dirtyRect );
if done then begin if done then begin
// the Cocoa default drawing cannot be skipped in NSTableView, // the Cocoa default drawing cannot be skipped in NSTableView,
@ -1071,6 +1145,7 @@ begin
// in Perferences-Component Palette. // in Perferences-Component Palette.
hideAllSubviews( self ); hideAllSubviews( self );
end else begin end else begin
updateNSTextFieldWithTFont( self.textField, cocoaTLV.lclGetCanvas.Font );
inherited drawRect(dirtyRect); inherited drawRect(dirtyRect);
end; end;
end; end;
@ -1862,6 +1937,12 @@ begin
Result:= TCocoaListView( self.getCallback(tv).Owner ).initializing; Result:= TCocoaListView( self.getCallback(tv).Owner ).initializing;
end; end;
function TCocoaTableListViewProcessor.getLCLControlCanvas(tv: NSTableView
): TCanvas;
begin
Result:= TCustomListView(tv.lclGetTarget).Canvas;
end;
procedure TCocoaTableListViewProcessor.onSelectionChanged(tv: NSTableView); procedure TCocoaTableListViewProcessor.onSelectionChanged(tv: NSTableView);
var var
NewSel: Integer; NewSel: Integer;

View File

@ -134,6 +134,7 @@ type
TCocoaTableListBoxProcessor = class( TCocoaTableListControlProcessor ) TCocoaTableListBoxProcessor = class( TCocoaTableListControlProcessor )
function isInitializing( tv: NSTableView ): Boolean; override; function isInitializing( tv: NSTableView ): Boolean; override;
function getLCLControlCanvas(tv: NSTableView): TCanvas; override;
procedure onSelectionChanged(tv: NSTableView); override; procedure onSelectionChanged(tv: NSTableView); override;
end; end;
@ -2466,6 +2467,12 @@ begin
Result:= False; Result:= False;
end; end;
function TCocoaTableListBoxProcessor.getLCLControlCanvas(tv: NSTableView
): TCanvas;
begin
Result:= TCustomListBox(tv.lclGetTarget).Canvas;
end;
procedure TCocoaTableListBoxProcessor.onSelectionChanged(tv: NSTableView); procedure TCocoaTableListBoxProcessor.onSelectionChanged(tv: NSTableView);
var var
lclListBox: TCustomListBox; lclListBox: TCustomListBox;