Carbon intf:

- implemented ComboBox DropDownList style
- working: T(Float)SpinEdit
- Buttons and Bars moved from CarbonPrivate to separate units

git-svn-id: trunk@11284 -
This commit is contained in:
tombo 2007-06-05 13:28:23 +00:00
parent 6c321c0b48
commit c09bbe5a88
24 changed files with 2140 additions and 1038 deletions

2
.gitattributes vendored
View File

@ -2475,6 +2475,8 @@ lcl/inipropstorage.pas svneol=native#text/pascal
lcl/interfacebase.pp svneol=native#text/pascal
lcl/interfaces/LAYOUT.txt svneol=native#text/plain
lcl/interfaces/carbon/README.txt svneol=native#text/plain
lcl/interfaces/carbon/carbonbars.pp svneol=native#text/pascal
lcl/interfaces/carbon/carbonbuttons.pp svneol=native#text/pascal
lcl/interfaces/carbon/carboncanvas.pp svneol=native#text/pascal
lcl/interfaces/carbon/carbondbgconsts.pp svneol=native#text/pascal
lcl/interfaces/carbon/carbondebug.inc svneol=native#text/plain

View File

@ -0,0 +1,397 @@
{ $Id$
-------------------------------------
CarbonBars.pp - Carbon bars classes
-------------------------------------
*****************************************************************************
* *
* This file is part of the Lazarus Component Library (LCL) *
* *
* See the file COPYING.modifiedLGPL, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
}
unit CarbonBars;
{$mode objfpc}{$H+}
interface
// debugging defines
{$I carbondebug.inc}
uses
// rtl+ftl
Types, Classes, SysUtils, Math, Contnrs,
// carbon bindings
FPCMacOSAll,
// widgetset
WSControls, WSLCLClasses, WSProc,
// LCL Carbon
CarbonDef, CarbonPrivate,
// LCL
LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, Menus;
type
{ TCarbonCustomBar }
TCarbonCustomBar = class(TCarbonControl)
private
public
function GetPosition: Integer; virtual;
procedure SetPosition(APosition: Integer); virtual;
procedure SetColor(const AColor: TColor); override;
procedure SetFont(const AFont: TFont); override;
end;
{ TCarbonProgressBar }
TCarbonProgressBar = class(TCarbonCustomBar)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ApplyChanges; virtual;
end;
{ TCarbonMovableBar }
TCarbonMovableBar = class(TCarbonCustomBar)
protected
class function GetValidEvents: TCarbonControlEvents; override;
procedure IndicatorMoved; override;
procedure ValueChanged; override;
end;
{ TCarbonTrackBar }
TCarbonTrackBar = class(TCarbonMovableBar)
private
FTicks: Word;
function GetTicks: Word;
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ApplyChanges; virtual;
end;
{ TCarbonScrollBar }
TCarbonScrollBar = class(TCarbonMovableBar)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure ValueChanged; override;
procedure DoAction(AControlPart: ControlPartCode); override;
procedure SetParams; virtual;
end;
implementation
uses InterfaceBase, CarbonInt, CarbonProc, CarbonDbgConsts, CarbonUtils,
CarbonWSStdCtrls, CarbonStrings, CarbonCanvas, CarbonGDIObjects;
{ TCarbonCustomBar }
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.GetPosition
Returns: The positon of Carbon bar
------------------------------------------------------------------------------}
function TCarbonCustomBar.GetPosition: Integer;
begin
Result := GetValue;
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetPosition
Params: APosition - New position
Sets the position of Carbon bar
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetPosition(APosition: Integer);
begin
SetValue(APosition);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetColor
Params: AColor - New color
Sets the color of control (for edit like controls)
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetColor(const AColor: TColor);
begin
// not supported
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetFont
Params: AFont - New font
Sets the font of control
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetFont(const AFont: TFont);
begin
// not supported
end;
{ TCarbonProgressBar }
{------------------------------------------------------------------------------
Method: TCarbonProgressBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon progress bar
------------------------------------------------------------------------------}
procedure TCarbonProgressBar.CreateWidget(const AParams: TCreateParams);
var
ProgressBar: TCustomProgressBar;
Control: ControlRef;
begin
ProgressBar := LCLObject as TCustomProgressBar;
// create determinate progress bar
if OSError(
CreateProgressBarControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
ProgressBar.Position, ProgressBar.Min, ProgressBar.Max, False, Control),
Self, SCreateWidget, 'CreateProgressBarControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonProgressBar.ApplyChanges
Sets the parameters (Min, Max, Position) of Carbon progress bar
------------------------------------------------------------------------------}
procedure TCarbonProgressBar.ApplyChanges;
var
ProgressBar: TCustomProgressBar;
begin
ProgressBar := LCLObject as TCustomProgressBar;
SetValue(ProgressBar.Position);
SetMinimum(ProgressBar.Min);
SetMaximum(ProgressBar.Max);
end;
{ TCarbonMovableBar }
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonMovableBar.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceValueChanged, cceIndicatorMoved];
end;
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.IndicatorMoved
Indicator moved event handler
------------------------------------------------------------------------------}
procedure TCarbonMovableBar.IndicatorMoved;
begin
ValueChanged;
end;
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonMovableBar.ValueChanged;
begin
LCLSendChangedMsg(LCLObject);
end;
{ TCarbonTrackBar }
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.GetTicks
Returns: Number of ticks
Returns the number of ticks for the track bar
------------------------------------------------------------------------------}
function TCarbonTrackBar.GetTicks: Word;
var
TrackBar: TCustomTrackBar;
begin
Result := 0;
TrackBar := LCLObject as TCustomTrackBar;
if TrackBar = nil then Exit;
if TrackBar.TickStyle = tsNone then Exit;
if TrackBar.Frequency > 0 then
Result := Math.Ceil(Abs(TrackBar.Max - TrackBar.Min) / TrackBar.Frequency) + 1
else
Result := 2;
end;
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon track bar
------------------------------------------------------------------------------}
procedure TCarbonTrackBar.CreateWidget(const AParams: TCreateParams);
var
TrackBar: TCustomTrackBar;
Control: ControlRef;
begin
TrackBar := LCLObject as TCustomTrackBar;
FTicks := GetTicks;
if OSError(
CreateSliderControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
TrackBar.Position, TrackBar.Min, TrackBar.Max,
kControlSliderPointsDownOrRight, FTicks, True, nil, Control),
Self, SCreateWidget, 'CreateSliderControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.ApplyChanges
Sets the parameters (Min, Max, Position, Ticks) of Carbon track bar
------------------------------------------------------------------------------}
procedure TCarbonTrackBar.ApplyChanges;
var
TrackBar: TCustomTrackBar;
begin
if FTicks <> GetTicks then
RecreateWnd(LCLObject) // recreate track bar if ticks have changed
else
begin
TrackBar := LCLObject as TCustomTrackBar;
SetValue(TrackBar.Position);
SetMinimum(TrackBar.Min);
SetMaximum(TrackBar.Max);
end;
end;
{ TCarbonScrollBar }
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon scroll bar
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.CreateWidget(const AParams: TCreateParams);
var
ScrollBar: TCustomScrollBar;
Control: ControlRef;
begin
ScrollBar := LCLObject as TCustomScrollBar;
if OSError(
CreateScrollBarControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
ScrollBar.Position, ScrollBar.Min, ScrollBar.Max, ScrollBar.PageSize, True,
nil, Control),
Self, SCreateWidget, 'CreateScrollBarControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonScrollBar.GetValidEvents: TCarbonControlEvents;
begin
Result := inherited GetValidEvents + [cceDoAction];
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.ValueChanged;
var
ScrollMsg: TLMScroll;
begin
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
ScrollMsg.Msg := LM_HSCROLL;
ScrollMsg.ScrollCode := SB_THUMBTRACK;
ScrollMsg.Pos := GetControl32BitValue(ControlRef(Widget));
ScrollMsg.ScrollBar := HWND(Widget);
DeliverMessage(LCLObject, ScrollMsg);
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.DoAction
Params: AControlPart - Control part to perform the action
Action event handler
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.DoAction(AControlPart: ControlPartCode);
var
ScrollMsg: TLMScroll;
ScrollCode: SmallInt;
begin
ScrollCode := -1; // valid scrollcode is >= 0
case AControlPart of
kControlUpButtonPart : ScrollCode := SB_LINEUP;
kControlDownButtonPart: ScrollCode := SB_LINEDOWN;
kControlPageUpPart : ScrollCode := SB_PAGEUP;
kControlPageDownPart : ScrollCode := SB_PAGEDOWN;
end;
//DebugLn('TCarbonScrollBar.DoAction ' + IntToStr(Integer(AControlPart)) + ' ' +
// IntToStr(ScrollCode));
if ScrollCode >= 0 then
begin
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
ScrollMsg.Msg := LM_HSCROLL;
ScrollMsg.ScrollCode := ScrollCode;
ScrollMsg.Pos := GetControl32BitValue(ControlRef(Widget));
ScrollMsg.ScrollBar := HWND(Widget);
DeliverMessage(LCLObject, ScrollMsg);
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.SetParams
Sets the parameters (Min, Max, Position, PageSize) of Carbon scroll bar
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.SetParams;
var
ScrollBar: TCustomScrollBar;
begin
ScrollBar := LCLObject as TCustomScrollBar;
SetMinimum(ScrollBar.Min);
SetMaximum(ScrollBar.Max);
SetValue(ScrollBar.Position);
SetViewSize(ScrollBar.PageSize);
end;
end.

View File

@ -0,0 +1,475 @@
{ $Id$
-------------------------------------------
CarbonButtons.pp - Carbon buttons classes
-------------------------------------------
*****************************************************************************
* *
* This file is part of the Lazarus Component Library (LCL) *
* *
* See the file COPYING.modifiedLGPL, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
}
unit CarbonButtons;
{$mode objfpc}{$H+}
interface
// debugging defines
{$I carbondebug.inc}
uses
// rtl+ftl
Types, Classes, SysUtils, Math, Contnrs,
// carbon bindings
FPCMacOSAll,
// widgetset
WSControls, WSLCLClasses, WSProc,
// LCL Carbon
CarbonDef, CarbonPrivate,
// LCL
LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, Menus;
type
{ TCarbonCustomCheckBox }
TCarbonCustomCheckBox = class(TCarbonControl)
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure Hit(AControlPart: ControlPartCode); override;
procedure ValueChanged; override;
function RetrieveState: TCheckBoxState; virtual;
procedure SetState(AState: TCheckBoxState); virtual;
end;
{ TCarbonCheckBox }
TCarbonCheckBox = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonToggleBox }
TCarbonToggleBox = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonRadioButton }
TCarbonRadioButton = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ValueChanged; override;
end;
{ TCarbonCustomButton }
TCarbonCustomButton = class(TCarbonControl)
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure Hit(AControlPart: ControlPartCode); override;
public
procedure SetDefault(ADefault: Boolean); virtual;
end;
{ TCarbonButton }
TCarbonButton = class(TCarbonCustomButton)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonBitBtn }
TCarbonBitBtn = class(TCarbonCustomButton)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure SetGlyph(const AGlyph: TBitmap); virtual;
procedure SetLayout(ALayout: TButtonLayout); virtual;
procedure SetDefault(ADefault: Boolean); override;
end;
implementation
uses InterfaceBase, CarbonInt, CarbonProc, CarbonDbgConsts, CarbonUtils,
CarbonWSStdCtrls, CarbonStrings, CarbonCanvas, CarbonGDIObjects;
{ TCarbonCustomCheckBox }
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonCustomCheckBox.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceValueChanged, cceHit];
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.Hit
Params: AControlPart - Hitted control part
Hit event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.Hit(AControlPart: ControlPartCode);
begin
// do nothing, because value changed will be fired immediately
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.ValueChanged;
begin
LCLSendChangedMsg(LCLObject);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.RetrieveState
Returns: State of Carbon custom check box
------------------------------------------------------------------------------}
function TCarbonCustomCheckBox.RetrieveState: TCheckBoxState;
begin
case GetControl32BitValue(ControlRef(Widget)) of
kControlCheckBoxCheckedValue : Result := cbChecked;
kControlCheckBoxUncheckedValue : Result := cbUnchecked;
kControlCheckBoxMixedValue : Result := cbGrayed;
else
Result := cbUnchecked;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.SetState
Params: AState - New state
Sets the new state of Carbon custom check box
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.SetState(AState: TCheckBoxState);
var
Value: UInt32;
begin
case AState of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
SetControl32BitValue(ControlRef(Widget), Value);
end;
{ TCarbonCheckBox }
{------------------------------------------------------------------------------
Method: TCarbonCheckBox.CreateWidget
Params: AParams - Creation parameters
Creates Carbon check box
------------------------------------------------------------------------------}
procedure TCarbonCheckBox.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TCustomCheckBox).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateCheckBoxControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Value, True, Control),
Self, SCreateWidget, 'CreateCheckBoxControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{ TCarbonToggleBox }
{------------------------------------------------------------------------------
Method: TCarbonToggleBox.CreateWidget
Params: AParams - Creation parameters
Creates Carbon toggle box
------------------------------------------------------------------------------}
procedure TCarbonToggleBox.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TToggleBox).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateBevelButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, kControlBevelButtonNormalBevel,
kControlBehaviorToggles, nil, 0, 0, 0, Control),
Self, SCreateWidget, SCreateBevelButton) then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
SetControl32BitValue(Control, Value);
end;
{ TCarbonRadioButton }
{------------------------------------------------------------------------------
Method: TCarbonRadioButton.CreateWidget
Params: AParams - Creation parameters
Creates Carbon radio button
------------------------------------------------------------------------------}
procedure TCarbonRadioButton.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TRadioButton).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateRadioButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Value, True, Control),
Self, SCreateWidget, 'CreateRadioButtonControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{------------------------------------------------------------------------------
Method: TCarbonRadioButton.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonRadioButton.ValueChanged;
var
RadioButton: TRadioButton;
Sibling: TControl;
I: Integer;
begin
if GetControl32BitValue(ControlRef(Widget)) = kControlCheckBoxCheckedValue then
begin
//DebugLn('TCarbonRadioButton.ValueChanged Uncheck Sibling');
// uncheck sibling radio buttons
RadioButton := (LCLObject as TRadioButton);
if RadioButton.Parent <> nil then
begin
for I := 0 to RadioButton.Parent.ControlCount - 1 do
begin
Sibling := RadioButton.Parent.Controls[I];
if (Sibling is TRadioButton) and (Sibling <> RadioButton) then
(Sibling as TRadioButton).Checked := False;
end;
end;
end;
inherited;
end;
{ TCarbonCustomButton }
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonCustomButton.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceHit];
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.Hit
Params: AControlPart - Hitted control part
Hit event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomButton.Hit(AControlPart: ControlPartCode);
begin
LCLSendClickedMsg(LCLObject);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.SetDefault
Params: ADefault - Is default
Sets the default indication
------------------------------------------------------------------------------}
procedure TCarbonCustomButton.SetDefault(ADefault: Boolean);
begin
OSError(
SetControlData(ControlRef(Widget), kControlEntireControl,
kControlPushButtonDefaultTag, SizeOf(Boolean), @ADefault),
Self, 'SetDefault', SSetData);
end;
{ TCarbonButton }
{------------------------------------------------------------------------------
Method: TCarbonButton.CreateWidget
Params: AParams - Creation parameters
Creates Carbon button
------------------------------------------------------------------------------}
procedure TCarbonButton.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
begin
// create the button at bounds
if OSError(
CreatePushButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Control),
Self, SCreateWidget, 'CreatePushButtonControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{ TCarbonBitBtn }
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.CreateWidget
Params: AParams - Creation parameters
Creates Carbon bitmap button
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
ButtonKind: ThemeButtonKind;
begin
if OSError(
CreateBevelButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, kControlBevelButtonLargeBevel, kControlBehaviorPushbutton,
nil, 0, 0, 0, Control),
Self, SCreateWidget, SCreateBevelButton) then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
// set round border
ButtonKind := kThemeRoundedBevelButton;
OSError(SetControlData(ControlRef(Widget), kControlEntireControl,
kControlBevelButtonKindTag, SizeOf(ThemeButtonKind), @ButtonKind),
Self, SCreateWidget, SSetData, 'kControlBevelButtonKindTag');
end;
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.SetGlyph
Params: AGlyph - New glyph bitmap
Sets the glyph bitmap
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.SetGlyph(const AGlyph: TBitmap);
var
ContentInfo: ControlButtonContentInfo;
FreeImage: Boolean;
BitBtn: TCustomBitBtn;
R: TRect;
begin
ContentInfo.contentType := kControlContentCGImageRef;
FreeImage := False;
ContentInfo.imageRef := nil;
if AGlyph <> nil then
begin
if TObject(AGlyph.Handle) is TCarbonBitmap then
begin
BitBtn := LCLObject as TCustomBitBtn;
if BitBtn.NumGlyphs <= 1 then
ContentInfo.imageRef := TCarbonBitmap(AGlyph.Handle).CGImage
else
begin
// TODO: consider button style (down, disabled)
R := Classes.Rect(0, 0, AGlyph.Width div BitBtn.NumGlyphs, AGlyph.Height);
ContentInfo.imageRef := TCarbonBitmap(AGlyph.Handle).GetSubImage(R);
FreeImage := True;
end;
end;
end;
try
OSError(SetBevelButtonContentInfo(ControlRef(Widget), @ContentInfo),
Self, 'SetGlyph', 'SetBevelButtonContentInfo');
finally
if FreeImage then CGImageRelease(ContentInfo.imageRef);
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.SetLayout
Params: ALayout - Bitmap and caption layout
Sets the bitmap and caption layout
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.SetLayout(ALayout: TButtonLayout);
var
Placement: ControlButtonTextPlacement;
begin
case ALayout of
blGlyphLeft : Placement := kControlBevelButtonPlaceToRightOfGraphic;
blGlyphRight : Placement := kControlBevelButtonPlaceToLeftOfGraphic;
blGlyphTop : Placement := kControlBevelButtonPlaceBelowGraphic;
blGlyphBottom: Placement := kControlBevelButtonPlaceAboveGraphic;
end;
OSError(SetBevelButtonTextPlacement(ControlRef(Widget), Placement),
Self, 'SetLayout', 'SetBevelButtonTextPlacement');
Invalidate;
end;
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.SetDefault
Params: ADefault - Is default
Sets the default indication
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.SetDefault(ADefault: Boolean);
begin
// not supported
end;
end.

View File

@ -99,6 +99,7 @@ type
procedure SetAntialiasing(AValue: Boolean);
public
procedure DrawFocusRect(const ARect: TRect);
procedure DrawFrameControl(var ARect: TRect; AType, AState: Cardinal);
procedure DrawSplitter(const ARect: TRect);
@ -349,8 +350,8 @@ end;
------------------------------------------------------------------------------}
constructor TCarbonDeviceContext.Create;
begin
FBkBrush := TCarbonBrush.Create;
FTextBrush := TCarbonBrush.Create;
FBkBrush := TCarbonBrush.Create(False);
FTextBrush := TCarbonBrush.Create(False);
FCurrentPen := BlackPen;
FCurrentPen.Select;
@ -564,6 +565,8 @@ const
SName = 'BeginTextRender';
begin
Result := False;
if ACount = 0 then Exit;
// save context
CGContextSaveGState(CGContext);
@ -623,6 +626,20 @@ begin
CGContextSetShouldAntialias(CGContext, CBool(AValue));
end;
{------------------------------------------------------------------------------
Method: TCarbonDeviceContext.DrawFocusRect
Params: ARect - Bounding rectangle
Returns: If the function succeeds
Draws a focus rectangle
------------------------------------------------------------------------------}
procedure TCarbonDeviceContext.DrawFocusRect(const ARect: TRect);
begin
OSError(
HIThemeDrawFocusRect(RectToCGRect(ARect), True, CGContext, kHIThemeOrientationNormal),
Self, 'DrawFocusRect', 'HIThemeDrawFocusRect');
end;
{------------------------------------------------------------------------------
Method: TCarbonDeviceContext.DrawFrameControl
Params: ARect - Bounding rectangle, returned adujsted to frame client area
@ -1317,7 +1334,7 @@ end;
constructor TCarbonBitmapContext.Create;
begin
inherited Create;
FBitmap := nil;
FBitmap := DefaultBitmap;
end;
{------------------------------------------------------------------------------

View File

@ -31,6 +31,7 @@ const
SInvalidate = 'Invalidate';
SEnable = 'Enable';
SSetFocus = 'SetFocus';
SSetBounds = 'SetBounds';
SSetColor = 'SetColor';
SGetText = 'GetText';
SSetText = 'SetText';
@ -79,7 +80,7 @@ const
SSetModality = 'SetWindowModality';
SGetData = 'GetControlData';
SSetData = 'GetControlData';
SSetData = 'SetControlData';
SGetEvent = 'GetEventParameter';
SSetEvent = 'SetEventParameter';

View File

@ -33,8 +33,9 @@
{off $DEFINE VerboseCanvas}
{off $DEFINE VerboseMenu} // Carbon menu
{$DEFINE VerboseScroll} // Carbon scrollable
{off $DEFINE VerboseBounds} // debug bounding and client rects of LCL vs. intf
{off $DEFINE VerboseWidget} // Carbon widget
{$DEFINE VerboseWidget} // Carbon widget
{off $DEFINE VerboseAppEvent} // Carbon application event handlers
{$DEFINE VerboseControlEvent} // Carbon control event handlers
{$DEFINE VerboseWindowEvent} // Carbon window event handlers

View File

@ -70,6 +70,7 @@ type
procedure SetProperty(AIndex: String; const AValue: Pointer);
protected
procedure RegisterEvents; virtual; abstract;
function CreateCustomHIView(const ARect: HIRect): HIViewRef;
procedure CreateWidget(const AParams: TCreateParams); virtual; abstract;
procedure DestroyWidget; virtual; abstract;
function GetContent: ControlRef; virtual; abstract;
@ -91,6 +92,7 @@ type
function IsVisible: Boolean; virtual; abstract;
function Enable(AEnable: Boolean): Boolean; virtual; abstract;
procedure GetScrollInfo(SBStyle: Integer; var ScrollInfo: TScrollInfo); virtual;
function GetBounds(var ARect: TRect): Boolean; virtual; abstract;
function GetScreenBounds(var ARect: TRect): Boolean; virtual; abstract;
function SetBounds(const ARect: TRect): Boolean; virtual; abstract;
@ -98,6 +100,7 @@ type
procedure SetFocus; virtual; abstract;
procedure SetColor(const AColor: TColor); virtual; abstract;
function SetScrollInfo(SBStyle: Integer; const ScrollInfo: TScrollInfo): Integer; virtual;
procedure SetFont(const AFont: TFont); virtual; abstract;
procedure ShowHide(AVisible: Boolean); virtual; abstract;
@ -369,6 +372,28 @@ begin
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonWidget.CreateCustomHIView
Params: ARect - Bounds rect
Returns: New custom HIView
------------------------------------------------------------------------------}
function TCarbonWidget.CreateCustomHIView(const ARect: HIRect): HIViewRef;
const
SName = 'CreateCustomHIView';
begin
Result := nil;
if OSError(
HIObjectCreate(CustomControlClassID, nil, Result),
Self, SName, 'HIObjectCreate') then Exit;
OSError(
HIViewChangeFeatures(Result, kHIViewFeatureAllowsSubviews or
kHIViewFeatureGetsFocusOnClick, 0),
Self, SName, 'HIViewChangeFeatures');
OSError(HIViewSetFrame(Result, ARect), Self, SName, SViewFrame);
end;
{------------------------------------------------------------------------------
Method: TCarbonWidget.BoundsChanged
@ -376,26 +401,30 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonWidget.BoundsChanged;
var
{$IFDEF VerboseBounds}
WidgetClient,
{$ENDIF}
WidgetBounds, OldBounds: TRect;
Resized: Boolean;
Resized, ClientResized: Boolean;
begin
//DebugLn('TCarbonWidget.BoundsChanged ' + LCLObject.Name);
{$IFDEF VerboseBounds}
DebugLn('TCarbonWidget.BoundsChanged ' + LCLObject.Name);
{$ENDIF}
GetBounds(WidgetBounds);
OldBounds := LCLObject.BoundsRect;
{$IFDEF VerboseBounds}
GetClientRect(WidgetClient);
DebugLn('TCarbonWidget.BoundsChanged Interface new bounds: ' + DbgS(WidgetBounds));
DebugLn('TCarbonWidget.BoundsChanged LCL old bounds: ' + DbgS(OldBounds));
DebugLn('TCarbonWidget.BoundsChanged Interface new client: ' + DbgS(WidgetClient));
DebugLn('TCarbonWidget.BoundsChanged LCL old client: ' + DbgS(LCLObject.ClientRect));
{$ENDIF}
Resized := False;
if LCLObject.ClientRectNeedsInterfaceUpdate then
begin
//DebugLn('TCarbonWidget.BoundsChanged Update client rects cache');
// update client rects cache
LCLObject.InvalidateClientRectCache(True);
LCLObject.DoAdjustClientRectChange;
Resized := True;
end;
ClientResized := False;
// then send a LM_SIZE message
if (OldBounds.Right - OldBounds.Left <> WidgetBounds.Right - WidgetBounds.Left) or
(OldBounds.Bottom - OldBounds.Top <> WidgetBounds.Bottom - WidgetBounds.Top) then
@ -405,6 +434,16 @@ begin
Resized := True;
end;
if Resized or LCLObject.ClientRectNeedsInterfaceUpdate then
begin
{$IFDEF VerboseBounds}
DebugLn('TCarbonWidget.BoundsChanged Update client rects cache');
{$ENDIF}
LCLObject.InvalidateClientRectCache(True);
LCLObject.DoAdjustClientRectChange;
ClientResized := True;
end;
// then send a LM_MOVE message
if (OldBounds.Left <> WidgetBounds.Left) or
@ -414,14 +453,19 @@ begin
WidgetBounds.Top, Move_SourceIsInterface);
end;
// invalidate control canvas
if Resized then Invalidate;
// invalidate client area
if ClientResized then Invalidate;
// invalidate parent client area, previously covered by control
if Resized and (LCLObject.Parent <> nil) and LCLObject.Parent.HandleAllocated then
begin
TCarbonWidget(LCLObject.Parent.Handle).Invalidate(@OldBounds);
end;
{$IFDEF VerboseBounds}
DebugLn('TCarbonWidget.BoundsChanged LCL new bounds: ' + DbgS(LCLObject.BoundsRect));
DebugLn('TCarbonWidget.BoundsChanged LCL new client: ' + DbgS(LCLObject.ClientRect));
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -442,14 +486,20 @@ begin
CreateWidget(AParams);
LCLObject.InvalidateClientRectCache(True);
{$IFDEF VerboseWidget}
DebugLn('TCarbonWidget.Create ', ClassName, ' ', LCLObject.Name, ': ',
LCLObject.ClassName);
{$ENDIF}
RegisterEvents;
LCLObject.InvalidateClientRectCache(True);
BoundsChanged;
{$IFDEF VerboseBounds}
DebugLn('TCarbonWidget.Create LCL bounds: ' + DbgS(LCLObject.BoundsRect));
DebugLn('TCarbonWidget.Create LCL client: ' + DbgS(LCLObject.ClientRect));
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -481,6 +531,35 @@ begin
Result.Y := 0;
end;
{------------------------------------------------------------------------------
Method: TCarbonWidget.GetScrollInfo
Params: SBStyle - Scrollbar type (SB_VERT, SB_HORZ)
ScrollInfo - Record fo scrolling info
Returns: If the function suceeds
Gets the scrolling info of the specified scroll bar
------------------------------------------------------------------------------}
procedure TCarbonWidget.GetScrollInfo(SBStyle: Integer;
var ScrollInfo: TScrollInfo);
begin
DebugLn(ClassName + '.GetScrollInfo unsupported or not implemented!');
end;
{------------------------------------------------------------------------------
Method: TCarbonWidget.SetScrollInfo
Params: SBStyle - Scrollbar type (SB_VERT, SB_HORZ)
ScrollInfo - Scrolling info
Returns: The old scroll bar position
Sets the scrolling info of the specified scroll bar
------------------------------------------------------------------------------}
function TCarbonWidget.SetScrollInfo(SBStyle: Integer;
const ScrollInfo: TScrollInfo): Integer;
begin
Result := 0;
DebugLn(ClassName + '.SetScrollInfo unsupported or not implemented!');
end;
initialization
LAZARUS_FOURCC := MakeFourCC('Laz ');

View File

@ -32,6 +32,7 @@ uses
FPCMacOSAll,
// LCL
LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, StdCtrls,
Spin,
// widgetset
WSControls, WSLCLClasses, WSProc,
// LCL Carbon
@ -47,7 +48,7 @@ type
protected
procedure LimitTextLength;
procedure AdaptCharCase;
class function GetEditPart: ControlPartCode; virtual;
function GetEditPart: ControlPartCode; virtual;
procedure RegisterEvents; override;
public
procedure TextDidChange; dynamic;
@ -69,13 +70,22 @@ type
TCarbonComboBox = class(TCarbonControlWithEdit)
private
FItemIndex: Integer;
FReadOnly: Boolean;
FPopupMenu: MenuRef;
protected
procedure RegisterEvents; override;
procedure CreateWidget(const AParams: TCreateParams); override;
class function GetEditPart: ControlPartCode; override;
procedure DestroyWidget; override;
function GetEditPart: ControlPartCode; override;
function GetPopupButtonMenu: MenuRef;
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure ListItemSelected(AIndex: Integer); virtual;
procedure ValueChanged; override;
public
function GetText(var S: String): Boolean; override;
procedure SetReadOnly(AReadOnly: Boolean); override;
function GetItemIndex: Integer;
function SetItemIndex(AIndex: Integer): Boolean;
@ -91,6 +101,36 @@ type
public
procedure SetPasswordChar(AChar: Char); virtual; abstract;
end;
{ TCarbonSpinEdit }
TCarbonSpinEdit = class(TCarbonCustomEdit)
private
FUpDown: ControlRef;
FValue: Single;
FMin: Single;
FMax: Single;
FIncrement: Single;
FDecimalPlaces: Integer;
function UpDownThemeWidth: Integer;
function FocusRectThemeOutset: Integer;
function GetEditBounds(const ARect: HIRect): HIRect;
function GetUpDownBounds(const ARect: HIRect): HIRect;
protected
procedure CreateWidget(const AParams: TCreateParams); override;
procedure DestroyWidget; override;
function GetFrame(Index: Integer): ControlRef; override;
function GetFrameBounds(var ARect: TRect): Boolean; override;
public
class function GetFrameCount: Integer; override;
class function GetValidEvents: TCarbonControlEvents; override;
procedure DoAction(AControlPart: ControlPartCode); override;
function SetBounds(const ARect: TRect): Boolean; override;
procedure SetPasswordChar(AChar: Char); override;
public
procedure UpdateControl;
property Value: Single read FValue;
end;
{ TCarbonEdit }
@ -113,7 +153,7 @@ type
FScrollBars: TScrollStyle;
procedure SetScrollBars(const AValue: TScrollStyle);
protected
function GetFrame: ControlRef; override;
function GetFrame(Index: Integer): ControlRef; override;
function GetForceEmbedInScrollView: Boolean; override;
procedure CreateWidget(const AParams: TCreateParams); override;
procedure DestroyWidget; override;
@ -190,7 +230,7 @@ end;
Method: TCarbonControlWithEdit.GetEditPart
Returns: Control part code of edit control
------------------------------------------------------------------------------}
class function TCarbonControlWithEdit.GetEditPart: ControlPartCode;
function TCarbonControlWithEdit.GetEditPart: ControlPartCode;
begin
Result := kControlEntireControl;
end;
@ -206,10 +246,13 @@ var
begin
inherited RegisterEvents;
TmpSpec := MakeEventSpec(kEventClassTextField, kEventTextDidChange);
InstallControlEventHandler(Widget,
RegisterEventHandler(@CarbonTextField_DidChange),
1, @TmpSpec, Pointer(Self), nil);
if GetEditPart >= 0 then
begin
TmpSpec := MakeEventSpec(kEventClassTextField, kEventTextDidChange);
InstallControlEventHandler(Widget,
RegisterEventHandler(@CarbonTextField_DidChange),
1, @TmpSpec, Pointer(Self), nil);
end;
end;
{------------------------------------------------------------------------------
@ -244,6 +287,8 @@ var
SelData: ControlEditTextSelectionRec;
begin
Result := False;
ASelStart := 0;
if GetEditPart < 0 then Exit;
if OSError(
GetControlData(ControlRef(Widget), GetEditPart, kControlEditTextSelectionTag,
@ -266,6 +311,8 @@ var
SelData: ControlEditTextSelectionRec;
begin
Result := False;
ASelLength := 0;
if GetEditPart < 0 then Exit;
if OSError(
GetControlData(ControlRef(Widget), GetEditPart, kControlEditTextSelectionTag,
@ -290,6 +337,7 @@ const
SName = 'SetSelStart';
begin
Result := False;
if GetEditPart < 0 then Exit;
if OSError(
GetControlData(ControlRef(Widget), GetEditPart, kControlEditTextSelectionTag,
@ -327,6 +375,7 @@ const
SName = 'SetSelLength';
begin
Result := False;
if GetEditPart < 0 then Exit;
if OSError(
GetControlData(ControlRef(Widget), GetEditPart, kControlEditTextSelectionTag,
@ -361,6 +410,8 @@ var
CFString: CFStringRef;
begin
Result := False;
S := '';
if GetEditPart < 0 then Exit;
if OSError(
GetControlData(ControlRef(Widget), GetEditPart, kControlEditTextCFStringTag,
@ -386,6 +437,7 @@ var
CFString: CFStringRef;
begin
Result := False;
if GetEditPart < 0 then Exit;
CreateCFString(S, CFString);
try
@ -408,6 +460,8 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonControlWithEdit.SetReadOnly(AReadOnly: Boolean);
begin
if GetEditPart < 0 then Exit;
OSError(SetControlData(ControlRef(Widget), GetEditPart,
kControlEditTextLockedTag, SizeOf(Boolean), @AReadOnly),
Self, 'SetReadOnly', SSetData);
@ -466,33 +520,87 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonComboBox.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
CFString: CFStringRef;
begin
CreateCFString(AParams.Caption, CFString);
try
if OSError(HIComboBoxCreate(ParamsToHIRect(AParams), CFString, nil, nil,
kHIComboBoxAutoSizeListAttribute, Control),
Self, SCreateWidget, 'HIComboBoxCreate')then RaiseCreateWidgetError(LCLObject);
FReadOnly := (LCLObject as TCustomComboBox).ReadOnly;
if FReadOnly then
begin
if OSError(
CreatePopupButtonControl(GetTopParentWindow,
ParamsToCarbonRect(AParams), nil, -12345, False, 0, popupTitleLeftJust,
FPCMacOSAll.Normal, Widget),
Self, SCreateWidget, 'CreatePopupButtonControl')then RaiseCreateWidgetError(LCLObject);
OSError(CreateNewMenu(0, kMenuAttrAutoDisable, FPopupMenu),
Self, SCreateWidget, 'CreateNewMenu');
OSError(
SetControlData(ControlRef(Widget), kControlEntireControl,
kControlPopupButtonOwnedMenuRefTag, SizeOf(MenuRef), @FPopupMenu),
Self, SCreateWidget, SSetData);
Widget := Control;
// count of popup button items is initially zero
SetMaximum(0);
end
else
begin
CreateCFString(AParams.Caption, CFString);
try
if OSError(HIComboBoxCreate(ParamsToHIRect(AParams), CFString, nil, nil,
kHIComboBoxAutoSizeListAttribute, Widget),
Self, SCreateWidget, 'HIComboBoxCreate')then RaiseCreateWidgetError(LCLObject);
inherited;
finally
FreeCFString(CFString);
finally
FreeCFString(CFString);
end;
end;
FItemIndex := -1;
FMaxLength := 0;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.DestroyWidget
Destroys Carbon combo box
------------------------------------------------------------------------------}
procedure TCarbonComboBox.DestroyWidget;
begin
if FReadOnly then DisposeMenu(FPopupMenu);
inherited DestroyWidget;
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.GetEditPart
Returns: Control part code of edit control
------------------------------------------------------------------------------}
class function TCarbonComboBox.GetEditPart: ControlPartCode;
function TCarbonComboBox.GetEditPart: ControlPartCode;
begin
Result := kHIComboBoxEditTextPart;
if FReadOnly then Result := -1
else Result := kHIComboBoxEditTextPart;
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.GetPopupButtonMenu
Returns: Popup Button menu
------------------------------------------------------------------------------}
function TCarbonComboBox.GetPopupButtonMenu: MenuRef;
begin
Result := FPopupMenu;
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonComboBox.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceValueChanged];
end;
{------------------------------------------------------------------------------
@ -503,8 +611,57 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonComboBox.ListItemSelected(AIndex: Integer);
begin
FItemIndex := AIndex;
LCLSendSelectionChangedMsg(LCLObject);
if FItemIndex <> AIndex then
begin
FItemIndex := AIndex;
LCLSendSelectionChangedMsg(LCLObject);
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonComboBox.ValueChanged;
begin
if FReadOnly then ListItemSelected(GetValue - 1);
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.GetText
Params: S - Text
Returns: If the function succeeds
Gets the text of combo box
------------------------------------------------------------------------------}
function TCarbonComboBox.GetText(var S: String): Boolean;
var
ComboBox: TCustomComboBox;
begin
if FReadOnly then
begin
ComboBox := LCLObject as TCustomComboBox;
if (FItemIndex >= 0) and (FItemIndex < ComboBox.Items.Count) then
S := ComboBox.Items[FItemIndex]
else
S := '';
Result := True;
end
else
Result := inherited GetText(S);
end;
{------------------------------------------------------------------------------
Method: TCarbonComboBox.SetReadOnly
Params: AReadOnly - Read only behavior
Sets the read only behavior of combo box
------------------------------------------------------------------------------}
procedure TCarbonComboBox.SetReadOnly(AReadOnly: Boolean);
begin
if AReadOnly <> FReadOnly then RecreateWnd(LCLObject);
end;
{------------------------------------------------------------------------------
@ -525,18 +682,23 @@ end;
function TCarbonComboBox.SetItemIndex(AIndex: Integer): Boolean;
begin
Result := False;
DebugLn('TCarbonComboBox.SetItemIndex New: ' + DbgS(AIndex) + ' Prev: ' + DbgS(FItemIndex));
if AIndex <> FItemIndex then
begin
if AIndex = -1 then
begin
FItemIndex := -1;
Result := SetText('');
end
if FReadOnly then SetValue(AIndex + 1)
else
begin
FItemIndex := AIndex;
Result := SetText((LCLObject as TCustomComboBox).Items[AIndex]);
end;
if AIndex = -1 then
begin
FItemIndex := -1;
Result := SetText('');
end
else
begin
FItemIndex := AIndex;
Result := SetText((LCLObject as TCustomComboBox).Items[AIndex]);
end;
end;
end
else Result := True;
end;
@ -554,8 +716,19 @@ var
begin
CreateCFString(S, CFString);
try
OSError(HIComboBoxInsertTextItemAtIndex(HIViewRef(Widget), AIndex, CFString),
Self, 'Insert', 'HIComboBoxInsertTextItemAtIndex');
if FReadOnly then
begin
OSError(InsertMenuItemTextWithCFString(GetPopupButtonMenu, CFString, AIndex,
kMenuItemAttrIgnoreMeta, 0),
Self, 'Inset', 'InsertMenuItemTextWithCFString');
SetMaximum((LCLObject as TCustomComboBox).Items.Count);
end
else
begin
OSError(HIComboBoxInsertTextItemAtIndex(HIViewRef(Widget), AIndex, CFString),
Self, 'Insert', 'HIComboBoxInsertTextItemAtIndex');
end;
finally
FreeCFString(CFString);
end;
@ -569,8 +742,16 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonComboBox.Remove(AIndex: Integer);
begin
OSError(HIComboBoxRemoveItemAtIndex(HIViewRef(Widget), AIndex),
Self, 'Remove', 'HIComboBoxRemoveItemAtIndex');
if FReadOnly then
begin
DeleteMenuItem(GetPopupButtonMenu, AIndex + 1);
SetMaximum((LCLObject as TCustomComboBox).Items.Count);
end
else
begin
OSError(HIComboBoxRemoveItemAtIndex(HIViewRef(Widget), AIndex),
Self, 'Remove', 'HIComboBoxRemoveItemAtIndex');
end;
end;
{------------------------------------------------------------------------------
@ -583,6 +764,13 @@ end;
function TCarbonComboBox.DropDown(ADropDown: Boolean): Boolean;
begin
Result := False;
if FReadOnly then
begin
//P := LCLObject.ClientToScreen(Classes.Point(0, 0));
//PopUpMenuSelect(FPopupMenu, P.Y, P.X, FItemIndex + 1);
DebugLn('TCarbonComboBox.DropDown for DropDownList TODO');
Exit;
end;
if OSError(HIComboBoxSetListVisible(ControlRef(Widget), ADropDown), Self,
'DropDown', 'HIComboBoxSetListVisible') then Exit;
@ -590,6 +778,239 @@ begin
Result := True;
end;
{ TCarbonSpinEdit }
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.UpDownThemeWidth
Returns: UpDown theme width
------------------------------------------------------------------------------}
function TCarbonSpinEdit.UpDownThemeWidth: Integer;
begin
OSError(GetThemeMetric(kThemeMetricLittleArrowsWidth, Result),
Self, 'UpDownThemeWidth', SGetThemeMetric);
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.FocusRectThemeOutset
Returns: Focus rectangle theme outset
------------------------------------------------------------------------------}
function TCarbonSpinEdit.FocusRectThemeOutset: Integer;
begin
OSError(GetThemeMetric(kThemeMetricFocusRectOutset, Result),
Self, 'UpDownThemeWidth', SGetThemeMetric);
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetEditBounds
Params: ARect - Bounding rect
Returns: Bounding rect for edit
------------------------------------------------------------------------------}
function TCarbonSpinEdit.GetEditBounds(const ARect: HIRect): HIRect;
begin
Result.origin.x := ARect.origin.x;
Result.origin.y := ARect.origin.y;
Result.size.width := ARect.size.width - (UpDownThemeWidth + 2 * FocusRectThemeOutset);
Result.size.height := ARect.size.height;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetUpDownBounds
Params: ARect - Bounding rect
Returns: Bounding rect for updown
------------------------------------------------------------------------------}
function TCarbonSpinEdit.GetUpDownBounds(const ARect: HIRect): HIRect;
begin
Result.origin.x := ARect.origin.x + ARect.size.width - (UpDownThemeWidth);
Result.origin.y := ARect.origin.y;
Result.size.width := ARect.size.width;
Result.size.height := ARect.size.height;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.CreateWidget
Params: AParams - Creation parameters
Creates Carbon spin edit
------------------------------------------------------------------------------}
procedure TCarbonSpinEdit.CreateWidget(const AParams: TCreateParams);
var
CFString: CFStringRef;
begin
CreateCFString(AParams.Caption, CFString);
try
if OSError(
CreateEditUniCodeTextControl(GetTopParentWindow,
HIRectToCarbonRect(GetEditBounds(ParamsToHIRect(AParams))),
CFString, False, nil, Widget),
Self, SCreateWidget, 'CreateEditUniCodeTextControl') then RaiseCreateWidgetError(LCLObject);
finally
FreeCFString(CFString);
end;
if OSError(
CreateLittleArrowsControl(GetTopParentWindow,
HIRectToCarbonRect(GetUpDownBounds(ParamsToHIRect(AParams))),
1, 0, 2, 1, FUpDown),
Self, SCreateWidget, 'CreateLittleArrowsControl') then RaiseCreateWidgetError(LCLObject);
AddControlPart(FUpDown);
inherited;
UpdateControl;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.DestroyWidget
Destroys Carbon spin edit
------------------------------------------------------------------------------}
procedure TCarbonSpinEdit.DestroyWidget;
begin
DisposeControl(FUpDown);
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetFrame
Params: Frame index
Returns: Frame area control
------------------------------------------------------------------------------}
function TCarbonSpinEdit.GetFrame(Index: Integer): ControlRef;
begin
case Index of
0: Result := ControlRef(Widget);
1: Result := FUpDown;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetFrameBounds
Params: ARect - Rectangle
Returns: If function succeeds
Returns the control bounding rectangle relative to the client origin of its
parent
------------------------------------------------------------------------------}
function TCarbonSpinEdit.GetFrameBounds(var ARect: TRect): Boolean;
begin
Result := False;
if inherited GetFrameBounds(ARect) then
begin
// add updown width
ARect.Right := ARect.Right + (UpDownThemeWidth + 2 * FocusRectThemeOutset);
Result := True;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetFrameCount
Returns: Count of control frames
------------------------------------------------------------------------------}
class function TCarbonSpinEdit.GetFrameCount: Integer;
begin
Result := 2;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonSpinEdit.GetValidEvents: TCarbonControlEvents;
begin
Result := inherited GetValidEvents + [cceDoAction];
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.DoAction
Params: AControlPart - Control part to perform the action
Action event handler
------------------------------------------------------------------------------}
procedure TCarbonSpinEdit.DoAction(AControlPart: ControlPartCode);
var
PrevValue: Single;
begin
PrevValue := FValue;
case AControlPart of
kControlUpButtonPart: FValue := FValue + FIncrement;
kControlDownButtonPart: FValue := FValue - FIncrement;
end;
if FValue < FMin then FValue := FMin;
if FValue > FMax then FValue := FMax;
if FValue <> PrevValue then
(LCLObject as TCustomFloatSpinEdit).Text :=
FloatToStrF(FValue, ffFixed, 20, FDecimalPlaces);
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.SetBounds
Params: ARect - Record for control coordinates
Returns: If function succeeds
Sets the control bounding rectangle relative to the client origin of its
parent
------------------------------------------------------------------------------}
function TCarbonSpinEdit.SetBounds(const ARect: TRect): Boolean;
begin
Result := False;
if OSError(
HIViewSetFrame(Widget, GetEditBounds(RectToCGRect(ARect))),
Self, SSetBounds, SViewFrame) then Exit;
if OSError(HIViewSetFrame(FUpDown, GetUpDownBounds(RectToCGRect(ARect))),
Self, SSetBounds, SViewFrame) then Exit;
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.SetPasswordChar
Params: AChar - New password char
Sets the new password char of Carbon edit
------------------------------------------------------------------------------}
procedure TCarbonSpinEdit.SetPasswordChar(AChar: Char);
begin
// not supported
end;
{------------------------------------------------------------------------------
Method: TCarbonSpinEdit.UpdateControl
Updates the value, min, max and increment of Carbon spin edit
------------------------------------------------------------------------------}
procedure TCarbonSpinEdit.UpdateControl;
var
SpinEdit: TCustomFloatSpinEdit;
begin
SpinEdit := (LCLObject as TCustomFloatSpinEdit);
FValue := SpinEdit.Value;
FMin := SpinEdit.MinValue;
FMax := SpinEdit.MaxValue;
FIncrement := SpinEdit.Increment;
FDecimalPlaces := SpinEdit.DecimalPlaces;
// disable/enable arrows
if (FValue = FMin) and (FIncrement > 0) then
SetControl32BitMinimum(FUpDown, 1)
else
SetControl32BitMinimum(FUpDown, 0);
if (FValue = FMax) and (FIncrement > 0) then
SetControl32BitMaximum(FUpDown, 1)
else
SetControl32BitMaximum(FUpDown, 2);
// update edit text
SpinEdit.Text := FloatToStrF(FValue, ffFixed, 20, FDecimalPlaces);
end;
{ TCarbonEdit }
{------------------------------------------------------------------------------
@ -615,7 +1036,7 @@ begin
Self, SCreateWidget, 'CreateEditUniCodeTextControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
finally
FreeCFString(CFString);
@ -719,9 +1140,10 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonMemo.GetFrame
Params: Frame index
Returns: Frame area control
------------------------------------------------------------------------------}
function TCarbonMemo.GetFrame: ControlRef;
function TCarbonMemo.GetFrame(Index: Integer): ControlRef;
begin
Result := FScrollView;
end;
@ -929,5 +1351,6 @@ begin
Invalidate;
end;
end.

View File

@ -42,12 +42,14 @@ type
TCarbonGDIObject = class
private
FSelCount: Integer;
FGlobal: Boolean;
public
constructor Create;
constructor Create(AGlobal: Boolean);
procedure Select;
procedure Unselect;
property Global: Boolean read FGlobal;
property SelCount: Integer read FSelCount;
end;
@ -57,7 +59,7 @@ type
private
FStyle: ATSUStyle;
public
constructor Create; // default system font
constructor Create(AGlobal: Boolean); // default system font
constructor Create(ALogFont: TLogFont; AFaceName: String);
destructor Destroy; override;
public
@ -71,7 +73,7 @@ type
FR, FG, FB: Byte;
FA: Boolean; // alpha: True - solid, False - clear
public
constructor Create(const AColor: TColor; ASolid: Boolean);
constructor Create(const AColor: TColor; ASolid, AGlobal: Boolean);
procedure SetColor(const AColor: TColor; ASolid: Boolean);
procedure GetRGBA(AROP2: Integer; out AR, AG, AB, AA: Single);
end;
@ -82,7 +84,7 @@ type
private
FCGPattern: CGPatternRef; // TODO
public
constructor Create; // create default brush
constructor Create(AGlobal: Boolean); // create default brush
constructor Create(ALogBrush: TLogBrush);
procedure Apply(ADC: TCarbonContext; UseROP2: Boolean = True);
end;
@ -102,7 +104,7 @@ type
FWidth: Integer;
FStyle: LongWord;
public
constructor Create; // create default pen
constructor Create(AGlobal: Boolean); // create default pen
constructor Create(ALogPen: TLogPen);
procedure Apply(ADC: TCarbonContext; UseROP2: Boolean = True);
end;
@ -350,12 +352,14 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonGDIObject.Create
Params: AGlobal - Global
Creates custom GDI object
------------------------------------------------------------------------------}
constructor TCarbonGDIObject.Create;
constructor TCarbonGDIObject.Create(AGlobal: Boolean);
begin
FSelCount := 0;
FGlobal := AGlobal;
end;
{------------------------------------------------------------------------------
@ -365,6 +369,7 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonGDIObject.Select;
begin
if FGlobal then Exit;
Inc(FSelCount);
end;
@ -375,6 +380,7 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonGDIObject.Unselect;
begin
if FGlobal then Exit;
if FSelCount > 0 then
Dec(FSelCount)
else
@ -388,12 +394,13 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonFont.Create
Params: AGlobal
Creates default Carbon font
------------------------------------------------------------------------------}
constructor TCarbonFont.Create;
constructor TCarbonFont.Create(AGlobal: Boolean);
begin
inherited;
inherited Create(AGlobal);
FStyle := DefaultTextStyle;
end;
@ -416,7 +423,7 @@ var
const
SSetAttrs = 'ATSUSetAttributes';
begin
inherited Create;
inherited Create(False);
OSError(ATSUCreateStyle(FStyle), Self, SCreate, SCreateStyle);
@ -508,13 +515,16 @@ end;
{ TCarbonColorObject }
{------------------------------------------------------------------------------
Method: TCarbonColorObject.Destroy
Method: TCarbonColorObject.Create
Params: AColor - Color
ASolid - Opacity
AGlobal - Global
Creates Carbon color object
------------------------------------------------------------------------------}
constructor TCarbonColorObject.Create(const AColor: TColor; ASolid: Boolean);
constructor TCarbonColorObject.Create(const AColor: TColor; ASolid, AGlobal: Boolean);
begin
inherited Create;
inherited Create(AGlobal);
SetColor(AColor, ASolid);
end;
@ -591,12 +601,13 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonBrush.Create
Params: AGlobal
Creates default Carbon brush
------------------------------------------------------------------------------}
constructor TCarbonBrush.Create;
constructor TCarbonBrush.Create(AGlobal: Boolean);
begin
inherited Create(clWhite, True);
inherited Create(clWhite, True, AGlobal);
end;
{------------------------------------------------------------------------------
@ -611,11 +622,11 @@ begin
BS_SOLID,
BS_HATCHED..BS_MONOPATTERN:
begin
inherited Create(ColorToRGB(ALogBrush.lbColor), True);
inherited Create(ColorToRGB(ALogBrush.lbColor), True, False);
// TODO: patterns
end;
else
inherited Create(ColorToRGB(ALogBrush.lbColor), False);
inherited Create(ColorToRGB(ALogBrush.lbColor), False, False);
end;
end;
@ -650,12 +661,13 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonPen.Create
Params: AGlobal
Creates default Carbon pen
------------------------------------------------------------------------------}
constructor TCarbonPen.Create;
constructor TCarbonPen.Create(AGlobal: Boolean);
begin
inherited Create(clBlack, True);
inherited Create(clBlack, True, AGlobal);
FStyle := PS_SOLID;
FWidth := 1;
end;
@ -672,12 +684,12 @@ begin
PS_SOLID..PS_DASHDOTDOT,
PS_INSIDEFRAME:
begin
inherited Create(ColorToRGB(ALogPen.lopnColor), True);
inherited Create(ColorToRGB(ALogPen.lopnColor), True, False);
FWidth := Max(1, ALogPen.lopnWidth.x);
end;
else
begin
inherited Create(ColorToRGB(ALogPen.lopnColor), False);
inherited Create(ColorToRGB(ALogPen.lopnColor), False, False);
FWidth := 1;
end;
end;
@ -784,7 +796,7 @@ end;
constructor TCarbonBitmap.Create(AWidth, AHeight, ABitsPerPixel: Integer;
AData: Pointer);
begin
inherited Create;
inherited Create(False);
FCGImage := nil;
@ -867,6 +879,8 @@ end;
------------------------------------------------------------------------------}
constructor TCarbonCursor.Create;
begin
inherited Create(False);
FCursorType := cctUnknown;
FThemeCursor := 0;
FAnimationStep := 0;
@ -1215,14 +1229,14 @@ initialization
InitCursor;
StockSystemFont := TCarbonFont.Create;
StockSystemFont := TCarbonFont.Create(True);
LogBrush.lbStyle := BS_NULL;
LogBrush.lbColor := 0;
StockNullBrush := TCarbonBrush.Create(LogBrush);
WhiteBrush := TCarbonBrush.Create;
BlackPen := TCarbonPen.Create;
WhiteBrush := TCarbonBrush.Create(True);
BlackPen := TCarbonPen.Create(True);
DefaultContext := TCarbonBitmapContext.Create;
DefaultBitmap := TCarbonBitmap.Create(1, 1, 32, nil);

View File

@ -139,13 +139,14 @@ uses
// CarbonWSMaskEdit,
CarbonWSMenus,
// CarbonWSPairSplitter,
// CarbonWSSpin,
CarbonWSSpin,
CarbonWSStdCtrls,
// CarbonWSToolwin,
CarbonThemes,
////////////////////////////////////////////////////
CarbonDef, CarbonPrivate, CarbonCanvas, CarbonGDIObjects, CarbonMenus,
CarbonEdits, CarbonTabs, CarbonStrings, CarbonProc, CarbonDbgConsts, CarbonUtils,
CarbonDef, CarbonPrivate, CarbonMenus, CarbonButtons, CarbonBars, CarbonEdits,
CarbonTabs,
CarbonThemes, CarbonCanvas, CarbonGDIObjects, CarbonStrings,
CarbonProc, CarbonDbgConsts, CarbonUtils,
Buttons, StdCtrls, PairSplitter, ComCtrls, CListBox, Calendar, Arrow,
Spin, CommCtrl, ExtCtrls, FileCtrl, LResources;

View File

@ -53,13 +53,18 @@ type
procedure RegisterEvents; override;
procedure CreateWidget(const AParams: TCreateParams); override;
procedure DestroyWidget; override;
procedure AddControlPart(const AControl: ControlRef);
function GetContent: ControlRef; override;
function GetFrame: ControlRef; virtual;
function GetControlContentRect(var ARect: TRect): Boolean;
function GetFrame(Index: Integer): ControlRef; virtual;
function GetFrameBounds(var ARect: TRect): Boolean; virtual;
function GetForceEmbedInScrollView: Boolean; virtual;
function UpdateContentBounds: Boolean;
function EmbedInScrollView(const AParams: TCreateParams): HIViewRef;
function EmbedInScrollView(AScrollBars: TScrollStyle): HIViewRef;
procedure ChangeScrollBars(AScrollView: HIViewRef; var AScrollBars: TScrollStyle; ANewValue: TScrollStyle);
public
class function GetFrameCount: Integer; virtual;
class function GetValidEvents: TCarbonControlEvents; virtual;
procedure Hit(AControlPart: ControlPartCode); dynamic;
procedure Draw; virtual;
@ -104,7 +109,7 @@ type
- frame area control of control
- determines bounds of control
- processes only bounds changed event }
property Frame: ControlRef read GetFrame;
property Frames[Index: Integer]: ControlRef read GetFrame;
end;
{ TCarbonWindow }
@ -127,6 +132,8 @@ type
function GetBounds(var ARect: TRect): Boolean; override;
function GetScreenBounds(var ARect: TRect): Boolean; override;
procedure GetScrollInfo(SBStyle: Integer; var ScrollInfo: TScrollInfo); override;
function SetScrollInfo(SBStyle: Integer; const ScrollInfo: TScrollInfo): Integer; override;
function SetBounds(const ARect: TRect): Boolean; override;
procedure SetChildZPosition(AChild: TCarbonWidget; const AOldPos, ANewPos: Integer; const AChildren: TFPList); override;
@ -170,15 +177,15 @@ type
procedure RegisterEvents; override;
procedure CreateWidget(const AParams: TCreateParams); override;
procedure DestroyWidget; override;
function GetFrame: ControlRef; override;
function GetFrame(Index: Integer): ControlRef; override;
public
procedure GetInfo(out AImageSize, AViewSize, ALineSize, AOrigin: TPoint); dynamic;
procedure ScrollTo(const ANewOrigin: TPoint); dynamic;
public
procedure SetColor(const AColor: TColor); override;
procedure SetFont(const AFont: TFont); override;
function SetScrollInfo(SBStyle: Integer; const ScrollInfo: TScrollInfo): Integer;
procedure GetScrollInfo(SBStyle: Integer; var ScrollInfo: TScrollInfo);
procedure GetScrollInfo(SBStyle: Integer; var ScrollInfo: TScrollInfo); override;
function SetScrollInfo(SBStyle: Integer; const ScrollInfo: TScrollInfo): Integer; override;
end;
{ TCarbonScrollingWinControl }
@ -198,6 +205,9 @@ type
procedure CreateWidget(const AParams: TCreateParams); override;
procedure DestroyWidget; override;
function GetContent: ControlRef; override;
public
function GetClientRect(var ARect: TRect): Boolean; override;
function SetBounds(const ARect: TRect): Boolean; override;
end;
{ TCarbonStatusBar }
@ -230,68 +240,6 @@ type
function GetItemIndex: Integer;
procedure SetItemIndex(AIndex: Integer);
end;
{ TCarbonCustomCheckBox }
TCarbonCustomCheckBox = class(TCarbonControl)
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure Hit(AControlPart: ControlPartCode); override;
procedure ValueChanged; override;
function RetrieveState: TCheckBoxState; virtual;
procedure SetState(AState: TCheckBoxState); virtual;
end;
{ TCarbonCheckBox }
TCarbonCheckBox = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonToggleBox }
TCarbonToggleBox = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonRadioButton }
TCarbonRadioButton = class(TCarbonCustomCheckBox)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ValueChanged; override;
end;
{ TCarbonCustomButton }
TCarbonCustomButton = class(TCarbonControl)
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure Hit(AControlPart: ControlPartCode); override;
public
procedure SetDefault(ADefault: Boolean); virtual;
end;
{ TCarbonButton }
TCarbonButton = class(TCarbonCustomButton)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
end;
{ TCarbonBitBtn }
TCarbonBitBtn = class(TCarbonCustomButton)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure SetGlyph(const AGlyph: TBitmap); virtual;
procedure SetLayout(ALayout: TButtonLayout); virtual;
end;
{ TCarbonStaticText }
@ -302,60 +250,6 @@ type
procedure SetAlignment(AAlignment: TAlignment); virtual;
end;
{ TCarbonCustomBar }
TCarbonCustomBar = class(TCarbonControl)
private
public
function GetPosition: Integer; virtual;
procedure SetPosition(APosition: Integer); virtual;
procedure SetColor(const AColor: TColor); override;
procedure SetFont(const AFont: TFont); override;
end;
{ TCarbonProgressBar }
TCarbonProgressBar = class(TCarbonCustomBar)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ApplyChanges; virtual;
end;
{ TCarbonMovableBar }
TCarbonMovableBar = class(TCarbonCustomBar)
protected
class function GetValidEvents: TCarbonControlEvents; override;
procedure IndicatorMoved; override;
procedure ValueChanged; override;
end;
{ TCarbonTrackBar }
TCarbonTrackBar = class(TCarbonMovableBar)
private
FTicks: Word;
function GetTicks: Word;
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
procedure ApplyChanges; virtual;
end;
{ TCarbonScrollBar }
TCarbonScrollBar = class(TCarbonMovableBar)
protected
procedure CreateWidget(const AParams: TCreateParams); override;
public
class function GetValidEvents: TCarbonControlEvents; override;
procedure ValueChanged; override;
procedure DoAction(AControlPart: ControlPartCode); override;
procedure SetParams; virtual;
end;
procedure RaiseCreateWidgetError(AControl: TWinControl);
function GetCarbonWidget(AWidget: Pointer): TCarbonWidget;
@ -503,7 +397,7 @@ begin
DebugLn('CustomControlHandler HitTest');
{$ENDIF}
Part := kControlButtonPart;
Part := kControlEditTextPart; // workaround
Result := SetEventParameter(AEvent, kEventParamControlPart,
typeControlPartCode, SizeOf(Part), @Part);
@ -606,17 +500,9 @@ end;
Creates Carbon custom control
------------------------------------------------------------------------------}
procedure TCarbonCustomControl.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
begin
if OSError(
HIObjectCreate(CustomControlClassID, nil, Control),
Self, SCreateWidget, 'HIObjectCreate') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
with AParams do
SetBounds(Bounds(X, Y, Width, Height));
Widget := CreateCustomHIView(ParamsToHIRect(AParams));
if Widget = nil then RaiseCreateWidgetError(LCLObject);
FScrollView := EmbedInScrollView(AParams);
FScrollSize := Classes.Point(0, 0);
@ -640,9 +526,10 @@ end;
{------------------------------------------------------------------------------
Method: TCarbonCustomControl.GetFrame
Params: Frame index
Returns: Frame area control
------------------------------------------------------------------------------}
function TCarbonCustomControl.GetFrame: ControlRef;
function TCarbonCustomControl.GetFrame(Index: Integer): ControlRef;
begin
Result := FScrollView;
end;
@ -662,7 +549,7 @@ begin
AOrigin := FScrollOrigin;
AImageSize := FScrollSize;
AViewSize := FScrollPageSize;
ALineSize := Classes.Point(1, 1);
ALineSize := Classes.Point(20, 20);
{$IFDEF VerboseScroll}
DebugLn('TCarbonCustomControl.GetInfo ' + LCLObject.Name + ' Origin: ' +
@ -791,7 +678,7 @@ begin
kEventAttributeUserEvent, Event),
Self, SName, 'CreateEvent') then Exit;
try
OSError(SendEventToEventTarget(Event, GetControlEventTarget(Widget)),
OSError(SendEventToEventTarget(Event, GetControlEventTarget(FScrollView)),
Self, SName, 'SendEventToEventTarget');
finally
ReleaseEvent(Event);
@ -902,15 +789,13 @@ begin
Exit;
end;
if OSError(
HIObjectCreate(CustomControlClassID, nil, FUserPane),
Self, SCreateWidget, 'HIObjectCreate') then RaiseCreateWidgetError(LCLObject);
FUserPane := CreateCustomHIView(RectToCGRect(R));
if FUserPane = nil then RaiseCreateWidgetError(LCLObject);
OSError(HIViewSetFrame(FUserPane, RectToCGRect(R)), Self, SCreateWidget, SViewFrame);
OSError(HIViewSetVisible(FUserPane, True), Self, SCreateWidget, SViewVisible);
if OSError(HIViewAddSubview(Control, FUserPane), Self, SCreateWidget,
SViewAddView) then Exit;
SViewAddView) then RaiseCreateWidgetError(LCLObject);
inherited;
@ -938,6 +823,33 @@ begin
Result := FUserPane;
end;
{------------------------------------------------------------------------------
Method: TCarbonGroupBox.GetClientRect
Params: ARect - Record for client area coordinates
Returns: If the function succeeds
Returns the control client rectangle relative to the control origin
------------------------------------------------------------------------------}
function TCarbonGroupBox.GetClientRect(var ARect: TRect): Boolean;
begin
Result := GetControlContentRect(ARect);
end;
{------------------------------------------------------------------------------
Method: TCarbonGroupBox.SetBounds
Params: ARect - Record for control coordinates
Returns: If function succeeds
Sets the control bounding rectangle relative to the client origin of its
parent
------------------------------------------------------------------------------}
function TCarbonGroupBox.SetBounds(const ARect: TRect): Boolean;
begin
Result := False;
if not inherited SetBounds(ARect) then Exit;
Result := UpdateContentBounds;
end;
{ TCarbonStatusBar }
{------------------------------------------------------------------------------
@ -1150,359 +1062,6 @@ begin
// TODO
end;
{ TCarbonCustomCheckBox }
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonCustomCheckBox.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceValueChanged, cceHit];
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.Hit
Params: AControlPart - Hitted control part
Hit event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.Hit(AControlPart: ControlPartCode);
begin
// do nothing, because value changed will be fired immediately
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.ValueChanged;
begin
LCLSendChangedMsg(LCLObject);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.RetrieveState
Returns: State of Carbon custom check box
------------------------------------------------------------------------------}
function TCarbonCustomCheckBox.RetrieveState: TCheckBoxState;
begin
case GetControl32BitValue(ControlRef(Widget)) of
kControlCheckBoxCheckedValue : Result := cbChecked;
kControlCheckBoxUncheckedValue : Result := cbUnchecked;
kControlCheckBoxMixedValue : Result := cbGrayed;
else
Result := cbUnchecked;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomCheckBox.SetState
Params: AState - New state
Sets the new state of Carbon custom check box
------------------------------------------------------------------------------}
procedure TCarbonCustomCheckBox.SetState(AState: TCheckBoxState);
var
Value: UInt32;
begin
case AState of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
SetControl32BitValue(ControlRef(Widget), Value);
end;
{ TCarbonCheckBox }
{------------------------------------------------------------------------------
Method: TCarbonCheckBox.CreateWidget
Params: AParams - Creation parameters
Creates Carbon check box
------------------------------------------------------------------------------}
procedure TCarbonCheckBox.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TCustomCheckBox).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateCheckBoxControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Value, True, Control),
Self, SCreateWidget, 'CreateCheckBoxControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{ TCarbonToggleBox }
{------------------------------------------------------------------------------
Method: TCarbonToggleBox.CreateWidget
Params: AParams - Creation parameters
Creates Carbon toggle box
------------------------------------------------------------------------------}
procedure TCarbonToggleBox.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TToggleBox).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateBevelButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, kControlBevelButtonNormalBevel,
kControlBehaviorToggles, nil, 0, 0, 0, Control),
Self, SCreateWidget, SCreateBevelButton) then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
SetControl32BitValue(Control, Value);
end;
{ TCarbonRadioButton }
{------------------------------------------------------------------------------
Method: TCarbonRadioButton.CreateWidget
Params: AParams - Creation parameters
Creates Carbon radio button
------------------------------------------------------------------------------}
procedure TCarbonRadioButton.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
Value: UInt32;
begin
case (LCLObject as TRadioButton).State of
cbChecked : Value := kControlCheckBoxCheckedValue;
cbUnChecked: Value := kControlCheckBoxUncheckedValue;
cbGrayed : Value := kControlCheckBoxMixedValue;
end;
if OSError(
CreateRadioButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Value, True, Control),
Self, SCreateWidget, 'CreateRadioButtonControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{------------------------------------------------------------------------------
Method: TCarbonRadioButton.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonRadioButton.ValueChanged;
var
RadioButton: TRadioButton;
Sibling: TControl;
I: Integer;
begin
if GetControl32BitValue(ControlRef(Widget)) = kControlCheckBoxCheckedValue then
begin
//DebugLn('TCarbonRadioButton.ValueChanged Uncheck Sibling');
// uncheck sibling radio buttons
RadioButton := (LCLObject as TRadioButton);
if RadioButton.Parent <> nil then
begin
for I := 0 to RadioButton.Parent.ControlCount - 1 do
begin
Sibling := RadioButton.Parent.Controls[I];
if (Sibling is TRadioButton) and (Sibling <> RadioButton) then
(Sibling as TRadioButton).Checked := False;
end;
end;
end;
inherited;
end;
{ TCarbonCustomButton }
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonCustomButton.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceHit];
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.Hit
Params: AControlPart - Hitted control part
Hit event handler
------------------------------------------------------------------------------}
procedure TCarbonCustomButton.Hit(AControlPart: ControlPartCode);
begin
LCLSendClickedMsg(LCLObject);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomButton.SetDefault
Params: ADefault - Is default
Sets the default indication
------------------------------------------------------------------------------}
procedure TCarbonCustomButton.SetDefault(ADefault: Boolean);
begin
OSError(
SetControlData(ControlRef(Widget), kControlEntireControl,
kControlPushButtonDefaultTag, SizeOf(Boolean), @ADefault),
Self, 'SetDefault', SSetData);
end;
{ TCarbonButton }
{------------------------------------------------------------------------------
Method: TCarbonButton.CreateWidget
Params: AParams - Creation parameters
Creates Carbon button
------------------------------------------------------------------------------}
procedure TCarbonButton.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
begin
// create the button at bounds
if OSError(
CreatePushButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, Control),
Self, SCreateWidget, 'CreatePushButtonControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
end;
{ TCarbonBitBtn }
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.CreateWidget
Params: AParams - Creation parameters
Creates Carbon bitmap button
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.CreateWidget(const AParams: TCreateParams);
var
Control: ControlRef;
ButtonKind: ThemeButtonKind;
begin
if OSError(
CreateBevelButtonControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
nil, kControlBevelButtonLargeBevel, kControlBehaviorPushbutton,
nil, 0, 0, 0, Control),
Self, SCreateWidget, SCreateBevelButton) then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
SetText(AParams.Caption);
// set round border
ButtonKind := kThemeRoundedBevelButton;
OSError(SetControlData(ControlRef(Widget), kControlEntireControl,
kControlBevelButtonKindTag, SizeOf(ThemeButtonKind), @ButtonKind),
Self, SCreateWidget, SSetData, 'kControlBevelButtonKindTag');
end;
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.SetGlyph
Params: AGlyph - New glyph bitmap
Sets the glyph bitmap
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.SetGlyph(const AGlyph: TBitmap);
var
ContentInfo: ControlButtonContentInfo;
FreeImage: Boolean;
BitBtn: TCustomBitBtn;
R: TRect;
begin
ContentInfo.contentType := kControlContentCGImageRef;
FreeImage := False;
ContentInfo.imageRef := nil;
if AGlyph <> nil then
begin
if TObject(AGlyph.Handle) is TCarbonBitmap then
begin
BitBtn := LCLObject as TCustomBitBtn;
if BitBtn.NumGlyphs <= 1 then
ContentInfo.imageRef := TCarbonBitmap(AGlyph.Handle).CGImage
else
begin
// TODO: consider button style (down, disabled)
R := Classes.Rect(0, 0, AGlyph.Width div BitBtn.NumGlyphs, AGlyph.Height);
ContentInfo.imageRef := TCarbonBitmap(AGlyph.Handle).GetSubImage(R);
FreeImage := True;
end;
end;
end;
try
OSError(SetBevelButtonContentInfo(ControlRef(Widget), @ContentInfo),
Self, 'SetGlyph', 'SetBevelButtonContentInfo');
finally
if FreeImage then CGImageRelease(ContentInfo.imageRef);
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonBitBtn.SetLayout
Params: ALayout - Bitmap and caption layout
Sets the bitmap and caption layout
------------------------------------------------------------------------------}
procedure TCarbonBitBtn.SetLayout(ALayout: TButtonLayout);
var
Placement: ControlButtonTextPlacement;
begin
case ALayout of
blGlyphLeft : Placement := kControlBevelButtonPlaceToRightOfGraphic;
blGlyphRight : Placement := kControlBevelButtonPlaceToLeftOfGraphic;
blGlyphTop : Placement := kControlBevelButtonPlaceBelowGraphic;
blGlyphBottom: Placement := kControlBevelButtonPlaceAboveGraphic;
end;
OSError(SetBevelButtonTextPlacement(ControlRef(Widget), Placement),
Self, 'SetLayout', 'SetBevelButtonTextPlacement');
Invalidate;
end;
{ TCarbonStaticText }
{------------------------------------------------------------------------------
@ -1576,300 +1135,6 @@ begin
end;
{ TCarbonCustomBar }
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.GetPosition
Returns: The positon of Carbon bar
------------------------------------------------------------------------------}
function TCarbonCustomBar.GetPosition: Integer;
begin
Result := GetValue;
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetPosition
Params: APosition - New position
Sets the position of Carbon bar
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetPosition(APosition: Integer);
begin
SetValue(APosition);
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetColor
Params: AColor - New color
Sets the color of control (for edit like controls)
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetColor(const AColor: TColor);
begin
// not supported
end;
{------------------------------------------------------------------------------
Method: TCarbonCustomBar.SetFont
Params: AFont - New font
Sets the font of control
------------------------------------------------------------------------------}
procedure TCarbonCustomBar.SetFont(const AFont: TFont);
begin
// not supported
end;
{ TCarbonProgressBar }
{------------------------------------------------------------------------------
Method: TCarbonProgressBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon progress bar
------------------------------------------------------------------------------}
procedure TCarbonProgressBar.CreateWidget(const AParams: TCreateParams);
var
ProgressBar: TCustomProgressBar;
Control: ControlRef;
begin
ProgressBar := LCLObject as TCustomProgressBar;
// create determinate progress bar
if OSError(
CreateProgressBarControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
ProgressBar.Position, ProgressBar.Min, ProgressBar.Max, False, Control),
Self, SCreateWidget, 'CreateProgressBarControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonProgressBar.ApplyChanges
Sets the parameters (Min, Max, Position) of Carbon progress bar
------------------------------------------------------------------------------}
procedure TCarbonProgressBar.ApplyChanges;
var
ProgressBar: TCustomProgressBar;
begin
ProgressBar := LCLObject as TCustomProgressBar;
SetValue(ProgressBar.Position);
SetMinimum(ProgressBar.Min);
SetMaximum(ProgressBar.Max);
end;
{ TCarbonMovableBar }
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonMovableBar.GetValidEvents: TCarbonControlEvents;
begin
Result := [cceValueChanged, cceIndicatorMoved];
end;
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.IndicatorMoved
Indicator moved event handler
------------------------------------------------------------------------------}
procedure TCarbonMovableBar.IndicatorMoved;
begin
ValueChanged;
end;
{------------------------------------------------------------------------------
Method: TCarbonMovableBar.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonMovableBar.ValueChanged;
begin
LCLSendChangedMsg(LCLObject);
end;
{ TCarbonTrackBar }
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.GetTicks
Returns: Number of ticks
Returns the number of ticks for the track bar
------------------------------------------------------------------------------}
function TCarbonTrackBar.GetTicks: Word;
var
TrackBar: TCustomTrackBar;
begin
Result := 0;
TrackBar := LCLObject as TCustomTrackBar;
if TrackBar = nil then Exit;
if TrackBar.TickStyle = tsNone then Exit;
if TrackBar.Frequency > 0 then
Result := Math.Ceil(Abs(TrackBar.Max - TrackBar.Min) / TrackBar.Frequency) + 1
else
Result := 2;
end;
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon track bar
------------------------------------------------------------------------------}
procedure TCarbonTrackBar.CreateWidget(const AParams: TCreateParams);
var
TrackBar: TCustomTrackBar;
Control: ControlRef;
begin
TrackBar := LCLObject as TCustomTrackBar;
FTicks := GetTicks;
if OSError(
CreateSliderControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
TrackBar.Position, TrackBar.Min, TrackBar.Max,
kControlSliderPointsDownOrRight, FTicks, True, nil, Control),
Self, SCreateWidget, 'CreateSliderControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonTrackBar.ApplyChanges
Sets the parameters (Min, Max, Position, Ticks) of Carbon track bar
------------------------------------------------------------------------------}
procedure TCarbonTrackBar.ApplyChanges;
var
TrackBar: TCustomTrackBar;
begin
if FTicks <> GetTicks then
RecreateWnd(LCLObject) // recreate track bar if ticks have changed
else
begin
TrackBar := LCLObject as TCustomTrackBar;
SetValue(TrackBar.Position);
SetMinimum(TrackBar.Min);
SetMaximum(TrackBar.Max);
end;
end;
{ TCarbonScrollBar }
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.CreateWidget
Params: AParams - Creation parameters
Creates Carbon scroll bar
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.CreateWidget(const AParams: TCreateParams);
var
ScrollBar: TCustomScrollBar;
Control: ControlRef;
begin
ScrollBar := LCLObject as TCustomScrollBar;
if OSError(
CreateScrollBarControl(GetTopParentWindow, ParamsToCarbonRect(AParams),
ScrollBar.Position, ScrollBar.Min, ScrollBar.Max, ScrollBar.PageSize, True,
nil, Control),
Self, SCreateWidget, 'CreateScrollBarControl') then RaiseCreateWidgetError(LCLObject);
Widget := Control;
inherited;
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.GetValidEvents
Returns: Set of events with installed handlers
------------------------------------------------------------------------------}
class function TCarbonScrollBar.GetValidEvents: TCarbonControlEvents;
begin
Result := inherited GetValidEvents + [cceDoAction];
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.ValueChanged
Value changed event handler
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.ValueChanged;
var
ScrollMsg: TLMScroll;
begin
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
ScrollMsg.Msg := LM_HSCROLL;
ScrollMsg.ScrollCode := SB_THUMBTRACK;
ScrollMsg.Pos := GetControl32BitValue(ControlRef(Widget));
ScrollMsg.ScrollBar := HWND(Widget);
DeliverMessage(LCLObject, ScrollMsg);
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.DoAction
Params: AControlPart - Control part to perform the action
Action event handler
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.DoAction(AControlPart: ControlPartCode);
var
ScrollMsg: TLMScroll;
ScrollCode: SmallInt;
begin
ScrollCode := -1; // valid scrollcode is >= 0
case AControlPart of
kControlUpButtonPart : ScrollCode := SB_LINEUP;
kControlDownButtonPart: ScrollCode := SB_LINEDOWN;
kControlPageUpPart : ScrollCode := SB_PAGEUP;
kControlPageDownPart : ScrollCode := SB_PAGEDOWN;
end;
//DebugLn('TCarbonScrollBar.DoAction ' + IntToStr(Integer(AControlPart)) + ' ' +
// IntToStr(ScrollCode));
if ScrollCode >= 0 then
begin
FillChar(ScrollMsg, SizeOf(TLMScroll), 0);
ScrollMsg.Msg := LM_HSCROLL;
ScrollMsg.ScrollCode := ScrollCode;
ScrollMsg.Pos := GetControl32BitValue(ControlRef(Widget));
ScrollMsg.ScrollBar := HWND(Widget);
DeliverMessage(LCLObject, ScrollMsg);
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonScrollBar.SetParams
Sets the parameters (Min, Max, Position, PageSize) of Carbon scroll bar
------------------------------------------------------------------------------}
procedure TCarbonScrollBar.SetParams;
var
ScrollBar: TCustomScrollBar;
begin
ScrollBar := LCLObject as TCustomScrollBar;
SetMinimum(ScrollBar.Min);
SetMaximum(ScrollBar.Max);
SetValue(ScrollBar.Position);
SetViewSize(ScrollBar.PageSize);
end;
var
EventSpec: Array [0..3] of EventTypeSpec;
CustomControlHandlerUPP: EventHandlerUPP;

View File

@ -302,14 +302,30 @@ function CarbonCommon_SetFocusPart(ANextHandler: EventHandlerCallRef;
AEvent: EventRef;
AWidget: TCarbonWidget): OSStatus; {$IFDEF darwin}mwpascal;{$ENDIF}
var
FocusPart: ControlPartCode;
FocusPart, PrevPart: ControlPartCode;
const
SName = 'CarbonCommon_SetFocusPart';
begin
Result := CallNextEventHandler(ANextHandler, AEvent);
//if not (AWidget.LCLObject is TCustomControl) then
Result := CallNextEventHandler(ANextHandler, AEvent);
if OSError(
GetEventParameter(AEvent, kEventParamControlPart, typeControlPartCode, nil,
SizeOf(ControlPartCode), nil, @FocusPart), 'CarbonCommon_SetFocusPart',
SizeOf(ControlPartCode), nil, @FocusPart), SName,
SGetEvent, SControlPart) then Exit;
{if not (AWidget.LCLObject is TCustomControl) then
begin
if OSError(HIViewGetFocusPart(AWidget.Widget, PrevPart),
SName, 'HIViewGetFocusPart') then Exit;
if (PrevPart = kControlFocusNoPart) and (FocusPart <> kControlFocusNoPart) then
FocusPart := kControlEditTextPart
else
FocusPart := kControlFocusNoPart;
Result := noErr;
end; }
{$IFDEF VerboseCommonEvent}
DebugLn('CarbonCommon_SetFocusPart: ', DbgSName(AWidget.LCLObject), ' ' +

View File

@ -158,10 +158,16 @@ end;
Adds control to parent widget
------------------------------------------------------------------------------}
procedure TCarbonControl.AddToWidget(AParent: TCarbonWidget);
var
I: Integer;
begin
// add frame to parent content area
OSError(HIViewAddSubview(AParent.Content, Frame), Self, 'AddToWidget',
SViewAddView);
for I := 0 to GetFrameCount - 1 do
begin
OSError(HIViewSetVisible(Frames[I], LCLObject.Visible), Self, 'AddToWidget', SViewVisible);
OSError(HIViewAddSubview(AParent.Content, Frames[I]), Self, 'AddToWidget',
SViewAddView);
end;
//DebugLn('TCarbonControl.AddToWidget ' + LCLObject.Name + ' ' + DbgS(LCLObject.Parent.ClientRect));
end;
@ -189,27 +195,9 @@ begin
1, @TmpSpec, Pointer(Self), nil);
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlBoundsChanged);
InstallControlEventHandler(Frame,
InstallControlEventHandler(Frames[0],
RegisterEventHandler(@CarbonCommon_BoundsChanged),
1, @TmpSpec, Pointer(Self), nil);
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlContextualMenuClick);
InstallControlEventHandler(Widget,
RegisterEventHandler(@CarbonCommon_ContextualMenuClick),
1, @TmpSpec, Pointer(Self), nil);
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlTrack);
InstallControlEventHandler(Widget,
RegisterEventHandler(@CarbonCommon_Track),
1, @TmpSpec, Pointer(Self), nil);
if Content <> ControlRef(Widget) then
begin
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlTrack);
InstallControlEventHandler(Content,
RegisterEventHandler(@CarbonCommon_Track),
1, @TmpSpec, Pointer(Self), nil);
end;
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlSetFocusPart);
InstallControlEventHandler(Content,
@ -223,7 +211,7 @@ begin
// cursor set
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlSetCursor);
InstallControlEventHandler(Widget,
InstallControlEventHandler(Content,
RegisterEventHandler(@CarbonCommon_SetCursor),
1, @TmpSpec, Pointer(Self), nil);
@ -265,16 +253,8 @@ end;
------------------------------------------------------------------------------}
procedure TCarbonControl.CreateWidget(const AParams: TCreateParams);
begin
OSError(
SetControlProperty(Widget, LAZARUS_FOURCC, WIDGETINFO_FOURCC, SizeOf(Self), @Self),
Self, SCreateWidget, SSetControlProp, 'Widget');
if Content <> ControlRef(Widget) then
OSError(
SetControlProperty(Content, LAZARUS_FOURCC, WIDGETINFO_FOURCC, SizeOf(Self), @Self),
SCreateWidget, SSetControlProp, 'Content');
OSError(HIViewSetVisible(Frame, LCLObject.Visible), Self, SCreateWidget, SViewVisible);
AddControlPart(Widget);
if Content <> ControlRef(Widget) then AddControlPart(Content);
end;
{------------------------------------------------------------------------------
@ -288,6 +268,31 @@ begin
Widget := nil;
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.AddControlPart
Params: AControl - Control
Adds control part of composite control
------------------------------------------------------------------------------}
procedure TCarbonControl.AddControlPart(const AControl: ControlRef);
var
TmpSpec: EventTypeSpec;
begin
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlTrack);
InstallControlEventHandler(AControl,
RegisterEventHandler(@CarbonCommon_Track),
1, @TmpSpec, Pointer(Self), nil);
TmpSpec := MakeEventSpec(kEventClassControl, kEventControlContextualMenuClick);
InstallControlEventHandler(AControl,
RegisterEventHandler(@CarbonCommon_ContextualMenuClick),
1, @TmpSpec, Pointer(Self), nil);
OSError(
SetControlProperty(AControl, LAZARUS_FOURCC, WIDGETINFO_FOURCC, SizeOf(Self), @Self),
Self, 'AddControlPart', SSetControlProp);
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetContent
Returns: Content area control
@ -297,15 +302,54 @@ begin
Result := ControlRef(Widget);
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetControlContentRect
Params: ARect - Content area rectangle
Returns: If the function succeeds
------------------------------------------------------------------------------}
function TCarbonControl.GetControlContentRect(var ARect: TRect): Boolean;
var
AClientRect: FPCMacOSAll.Rect;
ClientRegion: FPCMacOSAll.RgnHandle;
begin
Result := False;
ClientRegion := FPCMacOSAll.NewRgn();
try
if OSError(GetControlRegion(ControlRef(Widget), kControlContentMetaPart, ClientRegion),
Self, 'GetControlContentRect', 'GetControlRegion') then Exit;
Result := GetRegionBounds(ClientRegion, AClientRect) <> nil;
if Result then ARect := CarbonRectToRect(AClientRect);
finally
FPCMacOSAll.DisposeRgn(ClientRegion);
end;
{$IFDEF VerboseBounds}
DebugLn('TCarbonControl.GetControlContentRect ' + LCLObject.Name + ' ' + DbgS(ARect) +
' ' + DbgS(Result));
{$ENDIF}
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetFrame
Params: Frame index
Returns: Frame area control
------------------------------------------------------------------------------}
function TCarbonControl.GetFrame: ControlRef;
function TCarbonControl.GetFrame(Index: Integer): ControlRef;
begin
Result := ControlRef(Widget);
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetFrameCount
Returns: Count of control frames
------------------------------------------------------------------------------}
class function TCarbonControl.GetFrameCount: Integer;
begin
Result := 1;
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetForceEmbedInScrollView
Returns: Whether use scroll view even if no scroll bars are needed
@ -315,6 +359,32 @@ begin
Result := False;
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.UpdateContentBounds
Updates bounds of content area
------------------------------------------------------------------------------}
function TCarbonControl.UpdateContentBounds: Boolean;
var
R: TRect;
begin
Result := False;
if not GetClientRect(R) then
begin
DebugLn('TCarbonControl.UpdateContentBounds Error - unable to get client area!');
Exit;
end;
{$IFDEF VerboseBounds}
DebugLn('TCarbonControl.UpdateContentBounds ' + DbgS(R));
{$ENDIF}
if OSError(HIViewSetFrame(Content, RectToCGRect(R)),
Self, 'UpdateContentBounds', SViewFrame) then Exit;
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.EmbedInScrollView
Params: AParams - Creation parameters
@ -347,6 +417,7 @@ end;
function TCarbonControl.EmbedInScrollView(AScrollBars: TScrollStyle): HIViewRef;
var
ScrollOptions: FPCMacOSAll.OptionBits;
Bounds: HIRect;
const
SName = 'EmbedInScrollView';
begin
@ -370,13 +441,17 @@ begin
if OSError(HIScrollViewCreate(ScrollOptions, Result), Self, SName,
'HIScrollViewCreate') then Exit;
// set scroll view bounds
OSError(HIViewGetFrame(Widget, Bounds), Self, SName, 'HIViewGetFrame');
OSError(HIViewSetFrame(Result, Bounds), Self, SName, SViewFrame);
OSError(HIScrollViewSetScrollBarAutoHide(Result,
AScrollBars in [ssNone, ssAutoVertical, ssAutoHorizontal, ssAutoBoth]),
Self, SName, SViewSetScrollBarAutoHide);
OSError(HIViewSetVisible(Widget, True), Self, SName, SViewVisible);
if OSError(HIViewAddSubview(Result, Widget), Self, SName, SViewAddView) then Exit;
OSError(HIViewAddSubview(Result, Widget), Self, SName, SViewAddView);
end;
{------------------------------------------------------------------------------
@ -477,10 +552,15 @@ end;
Invalidates the specified client rect or entire area of control
------------------------------------------------------------------------------}
procedure TCarbonControl.Invalidate(Rect: PRect);
var
I: Integer;
begin
if Rect = nil then
OSError(
HiViewSetNeedsDisplay(Frame, True), Self, SInvalidate, SViewNeedsDisplay)
begin
for I := 0 to GetFrameCount - 1 do
OSError(
HiViewSetNeedsDisplay(Frames[I], True), Self, SInvalidate, SViewNeedsDisplay);
end
else
OSError(
HiViewSetNeedsDisplayInRect(Content, RectToCGRect(Rect^), True), Self,
@ -493,7 +573,7 @@ end;
------------------------------------------------------------------------------}
function TCarbonControl.IsEnabled: Boolean;
begin
Result := IsControlEnabled(Frame);
Result := IsControlEnabled(Frames[0]);
end;
{------------------------------------------------------------------------------
@ -502,7 +582,7 @@ end;
------------------------------------------------------------------------------}
function TCarbonControl.IsVisible: Boolean;
begin
Result := FPCMacOSAll.IsControlVisible(Frame);
Result := FPCMacOSAll.IsControlVisible(Frames[0]);
end;
{------------------------------------------------------------------------------
@ -513,13 +593,43 @@ end;
Changes control enabled
------------------------------------------------------------------------------}
function TCarbonControl.Enable(AEnable: Boolean): Boolean;
var
I: Integer;
begin
Result := not FPCMacOSAll.IsControlEnabled(Frame);
Result := not FPCMacOSAll.IsControlEnabled(Frames[0]);
if AEnable then
OSError(FPCMacOSAll.EnableControl(Frame), Self, SEnable, SEnableControl)
begin
for I := 0 to GetFrameCount - 1 do
OSError(FPCMacOSAll.EnableControl(Frames[I]), Self, SEnable, SEnableControl);
end
else
OSError(FPCMacOSAll.DisableControl(Frame), Self, SEnable, SDisableControl);
for I := 0 to GetFrameCount - 1 do
OSError(FPCMacOSAll.DisableControl(Frames[I]), Self, SEnable, SDisableControl);
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.GetFrameBounds
Params: ARect - TRect
Returns: If function succeeds
Returns the control bounding rectangle relative to the client origin of its
parent
------------------------------------------------------------------------------}
function TCarbonControl.GetFrameBounds(var ARect: TRect): Boolean;
var
BoundsRect: FPCMacOSAll.Rect;
begin
Result := False;
if GetControlBounds(Frames[0], BoundsRect) = nil then
begin
DebugLn('TCarbonControl.GetFrameBounds failed!');
Exit;
end;
ARect := CarbonRectToRect(BoundsRect);
Result := True;
end;
{------------------------------------------------------------------------------
@ -531,14 +641,8 @@ end;
parent
------------------------------------------------------------------------------}
function TCarbonControl.GetBounds(var ARect: TRect): Boolean;
var
AWndRect: FPCMacOSAll.Rect;
begin
Result := FPCMacOSAll.GetControlBounds(Frame, AWndRect) <> nil;
if Result then
ARect := CarbonRectToRect(AWndRect)
else
DebugLn('TCarbonControl.GetBounds failed for ' + DbgSName(LCLObject));
Result := GetFrameBounds(ARect);
end;
{------------------------------------------------------------------------------
@ -557,8 +661,11 @@ const
begin
Result := False;
if OSError(HIViewGetBounds(Frame, BoundsRect), Self, SName, 'HIViewGetBounds') then Exit;
if OSError(HIViewConvertRect(BoundsRect, Frame, nil), Self, SName,
if not GetFrameBounds(ARect) then Exit;
BoundsRect := RectToCGRect(ARect);
BoundsRect.origin.x := 0;
BoundsRect.origin.y := 0;
if OSError(HIViewConvertRect(BoundsRect, Frames[0], nil), Self, SName,
'HIViewConvertRect') then Exit;
if OSError(GetWindowBounds(GetTopParentWindow, kWindowStructureRgn,
@ -570,7 +677,6 @@ begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonControl.SetBounds
Params: ARect - Record for control coordinates
@ -580,21 +686,10 @@ end;
parent
------------------------------------------------------------------------------}
function TCarbonControl.SetBounds(const ARect: TRect): Boolean;
var
R: TRect;
begin
Result := False;
FPCMacOSAll.SetControlBounds(Frame, GetCarbonRect(ARect));
if Content <> ControlRef(Widget) then
begin // adjust content area
if not GetClientRect(R) then
begin
DebugLn('TCarbonControl.SetBounds Error - unable to get client area!');
Exit;
end;
FPCMacOSAll.SetControlBounds(Content, GetCarbonRect(R));
end;
if OSError(HIViewSetFrame(Frames[0], RectToCGRect(ARect)),
Self, SSetBounds, SViewFrame) then Exit;
Result := True;
end;
@ -640,7 +735,7 @@ begin
if Child.HandleAllocated then
begin
RefView := ControlRef(TCarbonWidget(Child.Handle).Widget);
RefView := ControlRef(TCarbonControl(Child.Handle).Frames[0]);
Order := kHIViewZOrderBelow;
Break;
end;
@ -649,8 +744,12 @@ begin
if RefView = nil then Exit;
end;
OSError(HIViewSetZOrder(ControlRef(AChild.Widget), Order, RefView),
OSError(HIViewSetZOrder((AChild as TCarbonControl).Frames[0], Order, RefView),
Self, 'SetChildZPosition', 'HIViewSetZOrder');
if GetFrameCount = 2 then
OSError(HIViewSetZOrder((AChild as TCarbonControl).Frames[1], kHIViewZOrderAbove, (AChild as TCarbonControl).Frames[0]),
Self, 'SetChildZPosition', 'HIViewSetZOrder', 'Frames[1]');
end;
{------------------------------------------------------------------------------
@ -749,9 +848,12 @@ end;
Shows or hides control
------------------------------------------------------------------------------}
procedure TCarbonControl.ShowHide(AVisible: Boolean);
var
I: Integer;
begin
//DebugLn('TCarbonControl.ShowHide ' + DbgSName(LCLobject),' ', DbgS(AVisible));
OSError(HIViewSetVisible(Frame, AVisible), Self, 'ShowHide', SViewVisible);
for I := 0 to GetFrameCount - 1 do
OSError(HIViewSetVisible(Frames[I], AVisible), Self, 'ShowHide', SViewVisible);
end;
{------------------------------------------------------------------------------
@ -868,40 +970,20 @@ end;
Returns the control client rectangle relative to the control origin
------------------------------------------------------------------------------}
function TCarbonControl.GetClientRect(var ARect: TRect): Boolean;
var
AClientRect: FPCMacOSAll.Rect;
ClientRegion: FPCMacOSAll.RgnHandle;
R: OSStatus;
begin
Result := False;
//DebugLn('TCarbonControl.GetClientRect ' + LCLObject.Name);
ClientRegion := FPCMacOSAll.NewRgn();
try
R := GetControlRegion(ControlRef(Widget), kControlContentMetaPart, ClientRegion);
case R of
errInvalidPartCode:
begin
// controls without content area have clientrect = boundsrect
Result := FPCMacOSAll.GetControlBounds(ControlRef(Widget), AClientRect) <> nil;
if Result then
begin
ARect := CarbonRectToRect(AClientRect);
OffsetRect(ARect, -ARect.Left, -ARect.Top);
end;
end;
noErr:
begin
Result := GetRegionBounds(ClientRegion, AClientRect) <> nil;
if Result then ARect := CarbonRectToRect(AClientRect);
//DebugLn('TCarbonControl.GetClientRect ' + LCLObject.Name + ' ' + DbgS(Result));
end;
else
OSError(R, Self, 'GetClientRect', 'GetControlRegion');
end;
finally
FPCMacOSAll.DisposeRgn(ClientRegion);
// controls without content area have clientrect = boundsrect
if GetFrameBounds(ARect) then
begin
OffsetRect(ARect, -ARect.Left, -ARect.Top);
Result := True;
end;
{$IFDEF VerboseBounds}
DebugLn('TCarbonControl.GetClientRect ' + LCLObject.Name + ' ' + DbgS(ARect) +
' ' + DbgS(Result));
{$ENDIF}
end;
{------------------------------------------------------------------------------

View File

@ -108,7 +108,7 @@ const
SizeOf(MousePoint), nil, @MousePoint),
SName, AGetEvent, 'kEventParamWindowMouseLocation') then Exit;
HIViewConvertPoint(MousePoint, nil, Control);
OSError(HIViewConvertPoint(MousePoint, nil, Widget.Content), SName, SViewConvert);
Result.X := Trunc(MousePoint.X);
Result.Y := Trunc(MousePoint.Y);
end;
@ -1185,6 +1185,34 @@ begin
Result := GetBounds(ARect);
end;
{------------------------------------------------------------------------------
Method: TCarbonWindow.GetScrollInfo
Params: SBStyle - Scrollbar type (SB_VERT, SB_HORZ)
ScrollInfo - Record fo scrolling info
Returns: If the function suceeds
Gets the scrolling info of the specified scroll bar
------------------------------------------------------------------------------}
procedure TCarbonWindow.GetScrollInfo(SBStyle: Integer; var ScrollInfo: TScrollInfo);
begin
DebugLn('TCarbonWindow.GetScrollInfo TODO');
end;
{------------------------------------------------------------------------------
Method: TCarbonWindow.SetScrollInfo
Params: SBStyle - Scrollbar type (SB_VERT, SB_HORZ)
ScrollInfo - Scrolling info
Returns: The old scroll bar position
Sets the scrolling info of the specified scroll bar
------------------------------------------------------------------------------}
function TCarbonWindow.SetScrollInfo(SBStyle: Integer;
const ScrollInfo: TScrollInfo): Integer;
begin
Result := 0;
DebugLn('TCarbonWindow.SetScrollInfo TODO');
end;
{------------------------------------------------------------------------------
Method: TCarbonWindow.SetBounds
Params: ARect - Record for window coordinates

View File

@ -89,6 +89,7 @@ function CGRectToRect(const ARect: CGRect): TRect;
function ParamsToHIRect(const AParams: TCreateParams): HIRect;
function CarbonRectToRect(const ARect: FPCMacOSAll.Rect): TRect;
function HIRectToCarbonRect(const ARect: HIRect): FPCMacOSAll.Rect;
function PointToHIPoint(const APoint: TPoint): HIPoint;
function PointToHISize(const APoint: TPoint): HISize;
@ -666,6 +667,19 @@ begin
Result.Bottom := ARect.Bottom;
end;
{------------------------------------------------------------------------------
Name: HIRectToCarbonRect
Params: ARect - HIRect
Returns: Carbon Rect
------------------------------------------------------------------------------}
function HIRectToCarbonRect(const ARect: HIRect): FPCMacOSAll.Rect;
begin
Result.Left := Floor(ARect.origin.x);
Result.Top := Floor(ARect.origin.y);
Result.Right := Ceil(ARect.origin.x + ARect.size.width);
Result.Bottom := Ceil(ARect.origin.y + ARect.size.height);
end;
{------------------------------------------------------------------------------
Name: PointToHIPoint
Params: APoint - Point

View File

@ -74,6 +74,7 @@ type
procedure ValueChanged; override;
public
function GetClientRect(var ARect: TRect): Boolean; override;
function SetBounds(const ARect: TRect): Boolean; override;
procedure Add(ATab: TCarbonTab; AIndex: Integer);
procedure Remove(AIndex: Integer);
procedure SetTabIndex(AIndex: Integer);
@ -189,15 +190,13 @@ begin
Exit;
end;
if OSError(
HIObjectCreate(CustomControlClassID, nil, FUserPane),
Self, SCreateWidget, 'HIObjectCreate') then RaiseCreateWidgetError(LCLObject);
FUserPane := CreateCustomHIView(RectToCGRect(R));
if FUserPane = nil then RaiseCreateWidgetError(LCLObject);
OSError(HIViewSetFrame(FUserPane, RectToCGRect(R)), Self, SCreateWidget, SViewFrame);
OSError(HIViewSetVisible(FUserPane, True), Self, SCreateWidget, SViewVisible);
if OSError(HIViewAddSubview(Control, FUserPane), Self, SCreateWidget,
SViewAddView) then Exit;
SViewAddView) then RaiseCreateWidgetError(LCLObject);
inherited;
@ -385,6 +384,24 @@ begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonTabsControl.SetBounds
Params: ARect - Record for control coordinates
Returns: If function succeeds
Sets the control bounding rectangle relative to the client origin of its
parent
------------------------------------------------------------------------------}
function TCarbonTabsControl.SetBounds(const ARect: TRect): Boolean;
begin
Result := False;
if inherited SetBounds(ARect) then
begin
UpdateContentBounds;
Result := True;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonTabsControl.Add
Params: ATab - Tab to add

View File

@ -1,3 +1,10 @@
{ $Id: $
-----------------------------------------
CarbonThemes.pas - Carbon Theme support
-----------------------------------------
See Themes.pas for licencing and other further information.
}
unit CarbonThemes;
{$mode objfpc}{$H+}
@ -27,10 +34,11 @@ type
function GetDrawState(Details: TThemedElementDetails): ThemeDrawState;
procedure DrawButtonElement(DC: TCarbonDeviceContext; Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
procedure DrawRebarElement(DC: TCarbonDeviceContext; Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
procedure DrawToolBarElement(DC: TCarbonDeviceContext; Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
procedure DrawReBarElement(DC: TCarbonDeviceContext; Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
public
procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; ClipRect: PRect); override;
procedure DrawEdge(DC: HDC; Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal; AContentRect: PRect); override;
procedure DrawIcon(DC: HDC; Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST; Index: Integer); override;
procedure DrawText(DC: HDC; Details: TThemedElementDetails; const S: WideString; R: TRect; Flags, Flags2: Cardinal); override;
@ -42,6 +50,11 @@ implementation
{ TCarbonThemeServices }
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.GetDrawState
Params: Details - Details for themed element
Returns: Draw state of the themed element passed
------------------------------------------------------------------------------}
function TCarbonThemeServices.GetDrawState(Details: TThemedElementDetails): ThemeDrawState;
{
kThemeStateInactive = 0;
@ -68,6 +81,15 @@ begin
Result := kThemeStateActive;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawButtonElement
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
ClipRect - Clipping rectangle
Draws a button element with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawButtonElement(DC: TCarbonDeviceContext;
Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
const
@ -106,6 +128,56 @@ begin
Self, 'DrawButtonElement', 'HIThemeDrawButton');
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawRebarElement
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
ClipRect - Clipping rectangle
Draws a rebar element (splitter) with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawRebarElement(DC: TCarbonDeviceContext;
Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
var
SplitterInfo: HIThemeSplitterDrawInfo;
PlacardInfo: HIThemePlacardDrawInfo;
ARect: HIRect;
const
SName = 'DrawRebarElement';
begin
ARect := RectToCGRect(R);
if Details.Part in [RP_GRIPPER, RP_GRIPPERVERT] then
begin
SplitterInfo.version := 0;
SplitterInfo.State := kThemeStateActive;
SplitterInfo.adornment := kHiThemeSplitterAdornmentNone;
OSError(
HIThemeDrawPaneSplitter(ARect, SplitterInfo, DC.CGContext, kHIThemeOrientationNormal),
Self, SName, 'HIThemeDrawPaneSplitter');
end
else
if Details.Part = RP_BAND then
begin
PlacardInfo.version := 0;
PlacardInfo.State := GetDrawState(Details);
OSError(
HIThemeDrawPlacard(ARect, PlacardInfo, DC.CGContext, kHIThemeOrientationNormal),
Self, SName, 'HIThemeDrawPlacard');
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawToolBarElement
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
ClipRect - Clipping rectangle
Draws a tool bar element with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawToolBarElement(DC: TCarbonDeviceContext;
Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
var
@ -114,6 +186,7 @@ var
begin
if Details.Part = TP_BUTTON then
begin
// TODO: if state is inactive or normal button should not have borders (or maybe I am wrong for mac?)
ButtonDrawInfo.version := 0;
@ -132,57 +205,72 @@ begin
end;
end;
procedure TCarbonThemeServices.DrawReBarElement(DC: TCarbonDeviceContext;
Details: TThemedElementDetails; R: TRect; ClipRect: PRect);
var
SplitterInfo: HIThemeSplitterDrawInfo;
PlacardInfo: HIThemePlacardDrawInfo;
ARect: HIRect;
begin
ARect := RectToCGRect(R);
if Details.Part in [RP_GRIPPER, RP_GRIPPERVERT] then
begin
SplitterInfo.version := 0;
SplitterInfo.State := kThemeStateActive;
SplitterInfo.adornment := kHiThemeSplitterAdornmentNone;
OSError(
HIThemeDrawPaneSplitter(ARect, SplitterInfo, DC.CGContext, kHIThemeOrientationNormal),
Self, 'DrawReBarElement', 'HIThemeDrawPaneSplitter');
end
else
if Details.Part = RP_BAND then
begin
PlacardInfo.version := 0;
PlacardInfo.State := GetDrawState(Details);
OSError(
HIThemeDrawPlacard(ARect, PlacardInfo, DC.CGContext, kHIThemeOrientationNormal),
Self, 'DrawReBarElement', 'HIThemeDrawPlacard');
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.InitThemes
Returns: If the themes are initialized
------------------------------------------------------------------------------}
function TCarbonThemeServices.InitThemes: Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.InitThemes
Returns: If the themes have to be used
------------------------------------------------------------------------------}
function TCarbonThemeServices.UseThemes: Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.ThemedControlsEnabled
Returns: If the themed controls are enabled
------------------------------------------------------------------------------}
function TCarbonThemeServices.ThemedControlsEnabled: Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.ContentRect
Params: DC - Carbon device context
Details - Details for themed element
BoundingRect - Bounding rectangle
Returns: Content rectangle of the passed themed element
------------------------------------------------------------------------------}
function TCarbonThemeServices.ContentRect(DC: HDC;
Details: TThemedElementDetails; BoundingRect: TRect): TRect;
begin
Result := BoundingRect;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawEdge
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
Edge - Type of edge
Flags - Type of border
Draws an edge with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawEdge(DC: HDC;
Details: TThemedElementDetails; const R: TRect; Edge, Flags: Cardinal;
AContentRect: PRect);
begin
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawElement
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
ClipRect - Clipping rectangle
Draws an element with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawElement(DC: HDC;
Details: TThemedElementDetails; const R: TRect; ClipRect: PRect);
var
@ -192,13 +280,23 @@ begin
begin
case Details.Element of
teButton: DrawButtonElement(Context, Details, R, ClipRect);
teToolBar: DrawToolBarElement(Context, Details, R, ClipRect);
// teHeader: TODO: for grid
teRebar: DrawRebarElement(Context, Details, R, ClipRect);
teToolBar: DrawToolBarElement(Context, Details, R, ClipRect);
end;
end;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawIcon
Params: DC - Carbon device context
Details - Details for themed element
R - Bounding rectangle
himl - Image list
Index - Icon index
Draws an icon with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawIcon(DC: HDC;
Details: TThemedElementDetails; const R: TRect; himl: HIMAGELIST;
Index: Integer);
@ -206,17 +304,41 @@ begin
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.HasTransparentParts
Params: Details - Details for themed element
Returns: If the themed element has transparent parts
------------------------------------------------------------------------------}
function TCarbonThemeServices.HasTransparentParts(Details: TThemedElementDetails): Boolean;
begin
Result := True;
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.InternalDrawParentBackground
Params: Window - Handle to window
Target - Carbon device context
Bounds - Bounding rectangle
Draws the parent background with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.InternalDrawParentBackground(Window: HWND;
Target: HDC; Bounds: PRect);
begin
// ?
end;
{------------------------------------------------------------------------------
Method: TCarbonThemeServices.DrawText
Params: DC - Carbon device context
Details - Details for themed element
S - Text string to darw
R - Bounding rectangle
Flags - Draw flags
Flags2 - Extra draw flags
Draws the passed text with native Carbon look
------------------------------------------------------------------------------}
procedure TCarbonThemeServices.DrawText(DC: HDC; Details: TThemedElementDetails;
const S: WideString; R: TRect; Flags, Flags2: Cardinal);
begin

View File

@ -45,11 +45,24 @@ begin
Result:=inherited BeginPaint(Handle, PS);
end;
{------------------------------------------------------------------------------
Method: BitBlt
Params: DestDC - Destination device context
X, Y - Left/top corner of the destination rectangle
Width, Height - Size of the destination rectangle
SrcDC - Source device context
XSrc, YSrc - Left/top corner of the source rectangle
Rop - Raster operation to be performed
Returns: If the function succeeds
Copies a bitmap from a source context into a destination context using the
specified raster operation
------------------------------------------------------------------------------}
function TCarbonWidgetSet.BitBlt(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean;
begin
Result:=inherited BitBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Rop
);
Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc,
Width, Height, 0, 0, 0, Rop);
end;
function TCarbonWidgetSet.CallNextHookEx(hHk: HHOOK; ncode: Integer;
@ -401,6 +414,8 @@ end;
with the object
------------------------------------------------------------------------------}
function TCarbonWidgetSet.DeleteObject(GDIObject: HGDIOBJ): Boolean;
var
CarbonGDIObject: TCarbonGDIObject;
begin
Result := False;
@ -409,14 +424,20 @@ begin
{$ENDIF}
if not CheckGDIObject(GDIObject, 'DeleteObject') then Exit;
CarbonGDIObject := TCarbonGDIObject(GDIObject);
if TCarbonGDIObject(GDIObject).SelCount = 0 then
TCarbonGDIObject(GDIObject).Free
if CarbonGDIObject.Global then
begin
DebugLn('TCarbonWidgetSet.DeleteObject Error - GDIObject: ' +
DbgSName(CarbonGDIObject) + ' is global!');
Exit;
end;
if CarbonGDIObject.SelCount = 0 then CarbonGDIObject.Free
else
begin
DebugLn('TCarbonWidgetSet.DeleteObject Error - GDIObject: ' +
DbgSName(TCarbonGDIObject(GDIObject)) +
' is still selected!');
DbgSName(CarbonGDIObject) + ' is still selected!');
Exit;
end;
@ -447,6 +468,29 @@ begin
TCarbonCursor(Handle).Free;
end;
{------------------------------------------------------------------------------
Method: DrawFocusRect
Params: DC - Handle to device context
Rect - Bounding rectangle
Returns: If the function succeeds
Draws a focus rectangle
------------------------------------------------------------------------------}
function TCarbonWidgetSet.DrawFocusRect(DC: HDC; const Rect: TRect): boolean;
begin
Result := False;
{$IFDEF VerboseWinAPI}
DebugLn('TCarbonWidgetSet.DrawFocusRect DC: ' + DbgS(DC) + ' Rect: ' + DbgS(Rect);
{$ENDIF}
if not CheckDC(DC, 'DrawFrameControl') then Exit;
TCarbonDeviceContext(DC).DrawFocusRect(Rect);
Result := True;
end;
{------------------------------------------------------------------------------
Method: DrawFrameControl
Params: DC - Handle to device context
@ -708,7 +752,7 @@ begin
{$IFDEF VerboseWinAPI}
DebugLn('TCarbonWidgetSet.ExtTextOut DC: ' + DbgS(DC) + ' ' + DbgS(X) +
', ' + DbgS(Y) + ' Str: ' + Str);
', ' + DbgS(Y) + ' Str: ' + Str + ' Count: ' + DbgS(Count));
{$ENDIF}
if not CheckDC(DC, 'ExtTextOut') then Exit;
@ -1474,9 +1518,9 @@ begin
' SBStyle: ' + DbgS(SBStyle));
{$ENDIF}
if not CheckWidget(Handle, 'GetScrollInfo', TCarbonCustomControl) then Exit;
if not CheckWidget(Handle, 'GetScrollInfo') then Exit;
TCarbonCustomControl(Handle).GetScrollInfo(SBStyle, ScrollInfo);
TCarbonWidget(Handle).GetScrollInfo(SBStyle, ScrollInfo);
Result := True;
end;
@ -2673,10 +2717,9 @@ begin
end
else
begin
// TODO: form scrollbars
if not CheckWidget(Handle, 'SetScrollInfo', TCarbonCustomControl) then Exit;
if not CheckWidget(Handle, 'SetScrollInfo') then Exit;
Result := TCarbonCustomControl(Handle).SetScrollInfo(SBStyle, ScrollInfo);
Result := TCarbonWidget(Handle).SetScrollInfo(SBStyle, ScrollInfo);
end;
end;
@ -2765,12 +2808,27 @@ begin
Result := TCarbonWindow(HWnd).Show(nCmdShow);
end;
{------------------------------------------------------------------------------
Method: StretchBlt
Params: DestDC - Destination device context
X, Y - Left/top corner of the destination rectangle
Width, Height - Size of the destination rectangle
SrcDC - Source device context
XSrc, YSrc - Left/top corner of the source rectangle
SrcWidth, SrcHeight - Size of the source rectangle
Rop - Raster operation to be performed
Returns: If the function succeeds
Copies a bitmap from a source rectangle into a destination rectangle using the
specified raster operation. If needed it resizes the bitmap to fit the
dimensions of the destination rectangle. Sizing is done according to the
stretching mode currently set in the destination device context.
------------------------------------------------------------------------------}
function TCarbonWidgetSet.StretchBlt(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; ROp: Cardinal
): Boolean;
SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; ROp: Cardinal): Boolean;
begin
Result:=inherited StretchBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc,
SrcWidth, SrcHeight, ROp);
Result := StretchMaskBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc,
SrcWidth, SrcHeight, 0, 0, 0, Rop);
end;
{------------------------------------------------------------------------------
@ -2815,7 +2873,8 @@ begin
if not CheckDC(SrcDC, SName, 'Src') then Exit;
if not (TCarbonDeviceContext(SrcDC) is TCarbonBitmapContext) then
begin
DebugLn(SName + ' Error - invalid source device context!');
DebugLn(SName + ' Error - invalid source device context ', TCarbonDeviceContext(SrcDC).ClassName,
', expected TCarbonBitmapContext!');
Exit;
end;

View File

@ -71,6 +71,7 @@ function DeleteDC(hDC: HDC): Boolean; override;
function DeleteObject(GDIObject: HGDIOBJ): Boolean; override;
function DestroyCaret(Handle : HWND): Boolean; override;
function DestroyCursor(Handle: HCURSOR): Boolean; override;
function DrawFocusRect(DC: HDC; const Rect: TRect): boolean; override;
function DrawFrameControl(DC: HDC; const Rect: TRect; UType, UState: Cardinal) : Boolean; override;
function DrawEdge(DC: HDC; var ARect: TRect; Edge: Cardinal; grfFlags: Cardinal): Boolean; override;
function DrawText(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect; Flags: Cardinal): Integer; Override;

View File

@ -37,7 +37,7 @@ uses
// widgetset
WSButtons, WSLCLClasses, WSProc,
// LCL Carbon
CarbonDef, CarbonPrivate, CarbonGDIObjects, CarbonWSControls;
CarbonDef, CarbonPrivate, CarbonButtons, CarbonWSControls;
type

View File

@ -37,7 +37,7 @@ uses
// widgetset
WSComCtrls, WSLCLClasses, WSControls, WSProc,
// LCL Carbon
CarbonDef, CarbonPrivate, CarbonStrings, CarbonWSControls;
CarbonDef, CarbonPrivate, CarbonBars, CarbonStrings, CarbonWSControls;
type

View File

@ -31,7 +31,7 @@ interface
uses
// libs
FPCMacOSAll, CarbonUtils, Classes,
FPCMacOSAll, CarbonUtils, Classes, SysUtils,
// LCL
Forms, Controls, Graphics, LCLType, LMessages, LCLProc,
// widgetset
@ -64,6 +64,8 @@ type
private
protected
public
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class procedure AddControl(const AControl: TControl); override;
class procedure DestroyHandle(const AWinControl: TWinControl); override;
class function GetClientBounds(const AWincontrol: TWinControl; var ARect: TRect): Boolean; override;
@ -259,6 +261,25 @@ begin
TCarbonWidget(AWinControl.Handle).ShowHide(AWinControl.Visible);
end;
{------------------------------------------------------------------------------
Method: TCarbonWSWinControl.CreateHandle
Params: AWinControl - LCL control
AParams - Creation parameters
Returns: Handle to the control in Carbon interface
Creates new win control in Carbon interface with the specified parameters
------------------------------------------------------------------------------}
class function TCarbonWSWinControl.CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): TLCLIntfHandle;
begin
raise
Exception.CreateFmt(ClassName + '.CreateHandle Error:' +
'Not implemented - unable to create Carbon win control for %s: %s!',
[AWinControl.Name, AWinControl.ClassName]);
Result := TLCLIntfHandle(nil);
end;
{------------------------------------------------------------------------------
Method: TCarbonWSWinControl.AddControl
Params: AControl - LCL control to add

View File

@ -26,6 +26,9 @@ unit CarbonWSSpin;
interface
// debugging defines
{$I carbondebug.inc}
uses
////////////////////////////////////////////////////
// I M P O R T A N T
@ -33,7 +36,7 @@ uses
// To get as little as posible circles,
// uncomment only when needed for registration
////////////////////////////////////////////////////
// Spin,
Controls, Spin, StdCtrls, LCLType,
////////////////////////////////////////////////////
WSSpin, WSLCLClasses;
@ -45,6 +48,9 @@ type
private
protected
public
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class function GetValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): Single; override;
class procedure UpdateControl(const ACustomFloatSpinEdit: TCustomFloatSpinEdit); override;
end;
{ TCarbonWSFloatSpinEdit }
@ -58,6 +64,51 @@ type
implementation
uses
CarbonEdits, CarbonDef, CarbonDbgConsts;
{ TCarbonWSCustomFloatSpinEdit }
{------------------------------------------------------------------------------
Method: TCarbonWSCustomFloatSpinEdit.CreateHandle
Params: AWinControl - LCL control
AParams - Creation parameters
Returns: Handle to the control in Carbon interface
Creates new spin edit in Carbon interface with the specified parameters
------------------------------------------------------------------------------}
class function TCarbonWSCustomFloatSpinEdit.CreateHandle(const AWinControl: TWinControl;
const AParams: TCreateParams): TLCLIntfHandle;
begin
Result := TLCLIntfHandle(TCarbonSpinEdit.Create(AWinControl, AParams));
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomFloatSpinEdit.GetValue
Params: ACustomFloatSpinEdit - LCL custom float spin edit
Returns: The float spin edit value
------------------------------------------------------------------------------}
class function TCarbonWSCustomFloatSpinEdit.GetValue(const ACustomFloatSpinEdit: TCustomFloatSpinEdit): Single;
begin
Result := 0;
if not CheckHandle(ACustomFloatSpinEdit, Self, 'GetValue') then Exit;
Result := TCarbonSpinEdit(ACustomFloatSpinEdit.Handle).Value;
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomFloatSpinEdit.UpdateControl
Params: ACustomFloatSpinEdit - LCL custom float spin edit
Update the value, min, max and increment of custom float spin edit in Carbon
interface
------------------------------------------------------------------------------}
class procedure TCarbonWSCustomFloatSpinEdit.UpdateControl(const ACustomFloatSpinEdit: TCustomFloatSpinEdit);
begin
if not CheckHandle(ACustomFloatSpinEdit, Self, 'UpdateControl') then Exit;
TCarbonSpinEdit(ACustomFloatSpinEdit.Handle).UpdateControl;
end;
initialization
////////////////////////////////////////////////////
@ -66,7 +117,7 @@ initialization
// To improve speed, register only classes
// which actually implement something
////////////////////////////////////////////////////
// RegisterWSComponent(TCustomFloatSpinEdit, TCarbonWSCustomFloatSpinEdit);
RegisterWSComponent(TCustomFloatSpinEdit, TCarbonWSCustomFloatSpinEdit);
// RegisterWSComponent(TFloatSpinEdit, TCarbonWSFloatSpinEdit);
////////////////////////////////////////////////////
end.
end.

View File

@ -37,7 +37,8 @@ uses
// widgetset
WSStdCtrls, WSLCLClasses, WSControls, WSProc,
// LCL Carbon
CarbonDef, CarbonPrivate, CarbonEdits, CarbonWSControls;
CarbonDef, CarbonPrivate, CarbonBars, CarbonButtons, CarbonEdits,
CarbonWSControls;
type
@ -84,9 +85,9 @@ type
class procedure SetSelLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override;
class procedure SetItemIndex(const ACustomComboBox: TCustomComboBox; NewIndex: integer); override;
class procedure SetMaxLength(const ACustomComboBox: TCustomComboBox; NewLength: integer); override;
class procedure SetStyle(const ACustomComboBox: TCustomComboBox; NewStyle: TComboBoxStyle); override;
class procedure SetReadOnly(const ACustomComboBox: TCustomComboBox; NewReadOnly: boolean); override;
class function GetItems(const ACustomComboBox: TCustomComboBox): TStrings; override;
class procedure Sort(const ACustomComboBox: TCustomComboBox; AList: TStrings; IsSorted: boolean); override;
end;
@ -442,6 +443,21 @@ begin
TCarbonComboBox(ACustomComboBox.Handle).MaxLength := NewLength;
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomComboBox.SetStyle
Params: ACustomComboBox - LCL custom combo box
NewStyle - Style
Sets the style of combo box in Carbon interface
------------------------------------------------------------------------------}
class procedure TCarbonWSCustomComboBox.SetStyle(const ACustomComboBox: TCustomComboBox;
NewStyle: TComboBoxStyle);
begin
if not CheckHandle(ACustomComboBox, Self, 'SetStyle') then Exit;
TCarbonComboBox(ACustomComboBox.Handle).SetReadOnly(ACustomComboBox.ReadOnly);
end;
{------------------------------------------------------------------------------
Method: TCarbonWSCustomComboBox.SetReadOnly
Params: ACustomComboBox - LCL custom combo box
@ -454,7 +470,7 @@ class procedure TCarbonWSCustomComboBox.SetReadOnly(const ACustomComboBox: TCust
begin
if not CheckHandle(ACustomComboBox, Self, 'SetReadOnly') then Exit;
// TODO
TCarbonComboBox(ACustomComboBox.Handle).SetReadOnly(NewReadOnly);
end;
{------------------------------------------------------------------------------