Cocoa: fix the width of the drop-down menu is not updated after the size of TCustomComboBox (TCocoaReadOnlyComboBox) is dynamically updated

This commit is contained in:
rich2014 2024-10-28 22:56:35 +08:00
parent 59f5c61e2e
commit 3b1a924a6d

View File

@ -216,8 +216,6 @@ type
const r: TRect; isSelected: Boolean); const r: TRect; isSelected: Boolean);
end; end;
{ TCocoaComboBox }
{ TCocoaComboBoxItemCell } { TCocoaComboBoxItemCell }
// represents an item in the combobox dropdown // represents an item in the combobox dropdown
@ -244,6 +242,8 @@ type
//function tableView_heightOfRow(tableView: NSTableView; row: NSInteger): CGFloat; message 'tableView:heightOfRow:'; //function tableView_heightOfRow(tableView: NSTableView; row: NSInteger): CGFloat; message 'tableView:heightOfRow:';
end; end;
{ TCocoaComboBox }
TCocoaComboBox = objcclass(NSComboBox, NSComboBoxDataSourceProtocol, NSComboBoxDelegateProtocol) TCocoaComboBox = objcclass(NSComboBox, NSComboBoxDataSourceProtocol, NSComboBoxDelegateProtocol)
private private
userSel: boolean; userSel: boolean;
@ -288,13 +288,17 @@ type
{ TCocoaReadOnlyView } { TCocoaReadOnlyView }
TCocoaReadOnlyView = objcclass (NSView) TCocoaReadOnlyView = objcclass (NSView)
private
itemIndex: Integer; itemIndex: Integer;
combobox: TCocoaReadOnlyComboBox; combobox: TCocoaReadOnlyComboBox;
isMouseOver: Boolean; isMouseOver: Boolean;
trackingArea: NSTrackingArea;
public
procedure drawRect(dirtyRect: NSRect); override; procedure drawRect(dirtyRect: NSRect); override;
procedure mouseUp(event: NSEvent); override; procedure mouseUp(event: NSEvent); override;
procedure mouseEntered(theEvent: NSEvent); override; procedure mouseEntered(theEvent: NSEvent); override;
procedure mouseExited(theEvent: NSEvent); override; procedure mouseExited(theEvent: NSEvent); override;
procedure lclUpdateTrackingAreas; message 'lclUpdateTrackingAreas';
end; end;
{ TCocoaReadOnlyComboBoxList } { TCocoaReadOnlyComboBoxList }
@ -306,6 +310,7 @@ type
FOwner: TCocoaReadOnlyComboBox; FOwner: TCocoaReadOnlyComboBox;
procedure InsertItem(Index: Integer; const S: string; O: TObject); override; procedure InsertItem(Index: Integer; const S: string; O: TObject); override;
procedure Put(Index: Integer; const S: string); override; procedure Put(Index: Integer; const S: string); override;
procedure UpdateItemSize;
public public
// Pass only 1 owner and nil for the other ones // Pass only 1 owner and nil for the other ones
constructor Create(AOwner: TCocoaReadOnlyComboBox); constructor Create(AOwner: TCocoaReadOnlyComboBox);
@ -331,6 +336,7 @@ type
isComboBoxEx: Boolean; isComboBoxEx: Boolean;
function initWithFrame(frameRect: NSRect): id; override; function initWithFrame(frameRect: NSRect): id; override;
procedure setFrameSize(newSize: NSSize); override;
procedure dealloc; override; procedure dealloc; override;
function lclGetItemHeight( row: Integer ): Integer; message 'lclGetItemHeight:'; function lclGetItemHeight( row: Integer ): Integer; message 'lclGetItemHeight:';
@ -488,7 +494,6 @@ var
astr : NSString; astr : NSString;
mn : NSMenuItem; mn : NSMenuItem;
menuItem : TCocoaReadOnlyView; menuItem : TCocoaReadOnlyView;
track: NSTrackingArea;
begin begin
inherited InsertItem(Index, S, O); inherited InsertItem(Index, S, O);
@ -528,15 +533,9 @@ begin
begin begin
menuItem := TCocoaReadOnlyView.alloc.initWithFrame( menuItem := TCocoaReadOnlyView.alloc.initWithFrame(
NSMakeRect(0,0, FOwner.frame.size.width, FOwner.lclGetItemHeight(index)) ); NSMakeRect(0,0, FOwner.frame.size.width, FOwner.lclGetItemHeight(index)) );
menuItem.lclUpdateTrackingAreas;
menuItem.itemIndex := Index; menuItem.itemIndex := Index;
menuItem.combobox := FOwner; menuItem.combobox := FOwner;
track:=NSTrackingArea(NSTrackingArea.alloc).initWithRect_options_owner_userInfo(
menuItem.bounds
, NSTrackingMouseEnteredAndExited or NSTrackingActiveAlways
, menuItem, nil);
menuItem.addTrackingArea(track);
track.release;
mn.setView(menuItem); mn.setView(menuItem);
menuItem.release; menuItem.release;
end; end;
@ -557,6 +556,21 @@ begin
end; end;
end; end;
procedure TCocoaReadOnlyComboBoxList.UpdateItemSize;
var
menuItem: NSMenuItem;
itemView: TCocoaReadOnlyView;
size: NSSize;
begin
size.width:= FOwner.frame.size.width;
for menuItem in FOwner.menu.itemArray do begin
itemView:= TCocoaReadOnlyView( menuItem.view );
size.height:= itemView.frame.size.height;
itemView.setFrameSize( size );
itemView.lclUpdateTrackingAreas;
end;
end;
constructor TCocoaReadOnlyComboBoxList.Create(AOwner: TCocoaReadOnlyComboBox); constructor TCocoaReadOnlyComboBoxList.Create(AOwner: TCocoaReadOnlyComboBox);
begin begin
inherited Create; inherited Create;
@ -712,6 +726,24 @@ begin
lclInvalidate; lclInvalidate;
end; end;
procedure TCocoaReadOnlyView.lclUpdateTrackingAreas;
const
options: NSTrackingAreaOptions = NSTrackingMouseEnteredAndExited
or NSTrackingActiveAlways;
begin
if Assigned(self.trackingArea) then begin
removeTrackingArea(self.trackingArea);
self.trackingArea.release;
end;
self.trackingArea:= NSTrackingArea.alloc.initWithRect_options_owner_userInfo(
self.bounds,
options,
self,
nil );
self.addTrackingArea( self.trackingArea );
end;
{ TCocoaComboBoxItemCell } { TCocoaComboBoxItemCell }
procedure TCocoaComboBoxItemCell.drawWithFrame_inView(cellFrame: NSRect; controlView_: NSView); procedure TCocoaComboBoxItemCell.drawWithFrame_inView(cellFrame: NSRect; controlView_: NSView);
@ -1603,6 +1635,12 @@ begin
_defaultItemHeight:= CocoaConfigComboBox.readOnly.item.defaultHeight; _defaultItemHeight:= CocoaConfigComboBox.readOnly.item.defaultHeight;
end; end;
procedure TCocoaReadOnlyComboBox.setFrameSize(newSize: NSSize);
begin
inherited setFrameSize(newSize);
TCocoaReadOnlyComboBoxList(self.list).UpdateItemSize;
end;
procedure TCocoaReadOnlyComboBox.dealloc; procedure TCocoaReadOnlyComboBox.dealloc;
begin begin
FreeAndNil( list ); FreeAndNil( list );