LCL-CustomDrawn-Cocoa: Now the highlighting of windowed controls is perfect in UIBrowser, non-windowed ones still wrong. Also fixes the implementation of ClientToScreen

git-svn-id: trunk@37173 -
This commit is contained in:
sekelsenmat 2012-05-06 07:01:46 +00:00
parent ffa0f2e2dd
commit 2111299e6b
4 changed files with 58 additions and 19 deletions

View File

@ -60,6 +60,8 @@ constructor TButtonControl.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
ControlStyle := ControlStyle-csMultiClicks-[csAcceptsControls,csCaptureMouse];
AccessibleRole := larButton;
AccessibleDescription := 'Button';
end;
{ TButtonActionLink }

View File

@ -96,6 +96,7 @@ type
// Accessibility
class function LazRoleToCocoaRole(ALazRole: TLazAccessibilityRole): NSString; message 'LazRoleToCocoaRole:';
function accessibilityAttributeValue(attribute: NSString): id; override;
function accessibilityFocusedUIElement: id; override;
end;
{ TCocoaAccessibleObject }
@ -993,6 +994,22 @@ begin
end;
end;
function TCocoaCustomControl.accessibilityFocusedUIElement: id;
var
lForm: TCustomForm;
// lFormAcc: TLazAccessibleObject;
lActiveControl: TWinControl;
begin
Result := inherited accessibilityFocusedUIElement();
lForm := WindowHandle.LCLForm;
// lFormAcc := lForm.GetAccessibleObject();
lActiveControl := lForm.ActiveControl;
if lActiveControl = nil then lActiveControl := lForm;
Result := id(lActiveControl.GetAccessibleObject().Handle);
end;
{ TCocoaAccessibleObject }
function TCocoaAccessibleObject.accessibilityAttributeNames: NSArray;
@ -1009,19 +1026,21 @@ begin
if lCocoaRole.isEqualToString(NSAccessibilityButtonRole) then
begin
lResult.addObject(NSAccessibilityDescriptionAttribute);
lResult.addObject(NSAccessibilityEnabledAttribute);
lResult.addObject(NSAccessibilityFocusedAttribute);
lResult.addObject(NSAccessibilityParentAttribute);
lResult.addObject(NSAccessibilityPositionAttribute);
lResult.addObject(NSAccessibilityRoleAttribute);
lResult.addObject(NSAccessibilityRoleDescriptionAttribute);
lResult.addObject(NSAccessibilitySizeAttribute);
lResult.addObject(NSAccessibilityTitleAttribute);
lResult.addObject(NSAccessibilityTopLevelUIElementAttribute);
lResult.addObject(NSAccessibilityWindowAttribute);
lResult.addObject(NSAccessibilityTitleAttribute);
end
else
begin
lResult.addObject(NSAccessibilityDescriptionAttribute);
lResult.addObject(NSAccessibilityEnabledAttribute);
lResult.addObject(NSAccessibilityFocusedAttribute);
lResult.addObject(NSAccessibilityParentAttribute);
lResult.addObject(NSAccessibilityPositionAttribute);
@ -1030,7 +1049,6 @@ begin
lResult.addObject(NSAccessibilityTitleAttribute);
lResult.addObject(NSAccessibilityTopLevelUIElementAttribute);
lResult.addObject(NSAccessibilityWindowAttribute);
lResult.addObject(NSAccessibilityTitleAttribute);
end;
// This one we use to put LCL object and class names to help debugging =)
@ -1073,11 +1091,11 @@ begin
end
else if attribute.isEqualToString(NSAccessibilityRoleDescriptionAttribute) then
begin
Result := NSStringUtf8(LCLControl.Caption);
end
else if attribute.isEqualToString(NSAccessibilityValueAttribute) then
begin
//Result := NSStringUtf8(LCLControl.Caption);
end
{else if attribute = NSAccessibilityMinValueAttribute: NSString; cvar; external;
NSAccessibilityMaxValueAttribute: NSString; cvar; external;}
@ -1091,7 +1109,8 @@ begin
Result := NSNumber.numberWithBool(TWinControl(LCLControl).Focused)
else Result := NSNumber.numberWithBool(False);
end
else if attribute.isEqualToString(NSAccessibilityParentAttribute) then
else if attribute.isEqualToString(NSAccessibilityParentAttribute) or
attribute.isEqualToString(NSAccessibilityTopLevelUIElementAttribute) then
begin
lParent := LCLControl.Parent;
if lParent <> nil then
@ -1137,19 +1156,18 @@ begin
else if attribute.isEqualToString(NSAccessibilityWindowAttribute) then
begin
lForm := Forms.GetParentForm(LCLControl);
Result := TCocoaAccessibleObject(lForm.GetAccessibleObject().Handle);
end
else if attribute.isEqualToString(NSAccessibilityTopLevelUIElementAttribute) then
begin
//Result := TCocoaAccessibleObject(lForm.GetAccessibleObject().Handle);
Result := TCocoaWindow(lForm.Handle).CocoaForm;//ClientArea;
end
else if attribute.isEqualToString(NSAccessibilitySelectedChildrenAttribute) then
begin
end
// Position is in screen coordinates!
else if attribute.isEqualToString(NSAccessibilityPositionAttribute) then
begin
lPoint := LCLAcc.Position;
//lPoint := LCLAcc.Position;
lPoint := LCLControl.ClientToScreen(Types.Point(0, 0));
lNSPoint.x := lPoint.X;
lNSPoint.y := lPoint.Y;
Result := NSValue.valueWithPoint(lNSPoint);

View File

@ -23,29 +23,36 @@
function TCDWidgetSet.ClientToScreen(Handle: HWND; var P: TPoint) : Boolean;
var
ControlHandle: TCDBaseControl;
lControl: TWinControl;
winhandle: TCocoaWindow absolute Handle;
lOriginalControl, lControl: TWinControl;
lPoint: NSPoint;
lCocoaForm: TCocoaForm; // NSWindow
lClientFrame: NSRect;
begin
Result := False;
if Handle = 0 then Exit;
// Go throught the non-native controls
ControlHandle := TCDBaseControl(Handle);
while not (ControlHandle is TCDForm) do
lOriginalControl := ControlHandle.GetWinControl();
while not (ControlHandle is TCocoaWindow) do
begin
lControl := ControlHandle.GetWinControl();
if lControl = nil then Exit;
P.X := P.X + lControl.Left;
P.Y := P.Y + lControl.Top;
lControl := lControl.Parent;
if lControl = nil then Exit;
ControlHandle := TCDBaseControl(lControl.Handle);
P.X := P.X - lControl.Left;
P.Y := P.Y - lControl.Top;
end;
// Now actually do the convertion
lPoint.x := P.X;
lPoint.Y := P.Y;
lPoint := winhandle.CocoaForm.convertBaseToScreen(lPoint);
lClientFrame := TCocoaWindow(ControlHandle).ClientArea.frame;
lPoint.x := lClientFrame.origin.X + P.X;
lPoint.Y := lClientFrame.origin.Y + lClientFrame.size.height - P.Y - lOriginalControl.Height;
lCocoaForm := TCocoaWindow(ControlHandle).CocoaForm;
if lCocoaForm = nil then Exit;
lPoint := lCocoaForm.convertBaseToScreen(lPoint);
P.x := Round(lPoint.X);
P.Y := Round(lPoint.Y);
Result := True;

View File

@ -163,6 +163,15 @@ class function TCDWSLazAccessibleObject.CreateHandle(
begin
Result := 0;
if AObject = nil then Exit;
// If this is a top-level window, then use the window Handle
if AObject.OwnerControl is TCustomForm then
begin
Result := HWND(TCocoaWindow(TCustomForm(AObject.OwnerControl).Handle).CocoaForm);
Exit;
end;
// Otherwise create a new handle
Result := HWND(TCocoaAccessibleObject.alloc.init);
TCocoaAccessibleObject(Result).LCLAcc := AObject;
TCocoaAccessibleObject(Result).LCLControl := AObject.OwnerControl;
@ -173,6 +182,9 @@ class procedure TCDWSLazAccessibleObject.DestroyHandle(
var
lAccessibleHandle: TCocoaAccessibleObject;
begin
if AObject.OwnerControl is TCustomForm then
Exit;
lAccessibleHandle := TCocoaAccessibleObject(AObject.Handle);
lAccessibleHandle.release;
end;