lazarus/lcl/interfaces/carbon/carbonbuttons.pp
marc 04b4e27b62 * Implemented basic alpha support
* Implemented LCL side of imagelist
* restructured rawimage to more OO

Merged revisions 11289-11617 via svnmerge from 
http://svn.freepascal.org/svn/lazarus/branches/marc-lcl

........
  r11289 | marc | 2007-06-06 22:50:05 +0200 (Wed, 06 Jun 2007) | 1 line
  
  private branch for bitmap rework
........
  r11290 | marc | 2007-06-06 23:30:09 +0200 (Wed, 06 Jun 2007) | 2 lines
  
  * Initial linux and win32 implementation
........
  r11291 | paul | 2007-06-07 03:20:11 +0200 (Thu, 07 Jun 2007) | 3 lines
  
  - fix compilation with fpc 2.3.1
  - remove unneded code for converting cursor mask
  - enabled loading of standard windows status icons instead of LCL
........
  r11292 | paul | 2007-06-07 11:03:27 +0200 (Thu, 07 Jun 2007) | 1 line
  
  - some bugs with mask and alpha
........
  r11299 | marc | 2007-06-08 00:59:26 +0200 (Fri, 08 Jun 2007) | 2 lines
  
  * force alpha channel when PNG has alpha
........
  r11302 | paul | 2007-06-09 04:45:12 +0200 (Sat, 09 Jun 2007) | 1 line
  
  - fix black rectangles instead of manu item images
........
  r11303 | paul | 2007-06-09 04:46:14 +0200 (Sat, 09 Jun 2007) | 1 line
  
  formatting
........
  r11309 | marc | 2007-06-11 02:25:07 +0200 (Mon, 11 Jun 2007) | 3 lines
  
  * Added alpha premultiply
  * Published Colorbox selection property
........
  r11310 | paul | 2007-06-11 19:10:18 +0200 (Mon, 11 Jun 2007) | 1 line
  
  misc
........
  r11312 | marc | 2007-06-12 01:44:03 +0200 (Tue, 12 Jun 2007) | 2 lines
  
  * start with carbon
........
  r11313 | paul | 2007-06-12 14:02:48 +0200 (Tue, 12 Jun 2007) | 1 line
  
  - BitBtn glyph transparency
........
  r11315 | paul | 2007-06-13 05:20:40 +0200 (Wed, 13 Jun 2007) | 1 line
  
  - problems with internal bitmap saving/loading (is was 24bpp when 32bpp needed)
........
  r11319 | paul | 2007-06-14 06:32:04 +0200 (Thu, 14 Jun 2007) | 1 line
  
  - More LCL way of painting images through ThemeServices
........
  r11320 | paul | 2007-06-14 06:32:56 +0200 (Thu, 14 Jun 2007) | 1 line
  
  - ability to override bitbtn glyph to nothing
........
  r11321 | paul | 2007-06-14 06:34:49 +0200 (Thu, 14 Jun 2007) | 1 line
  
  painting headercontrol images through ThemeServices
........
  r11325 | paul | 2007-06-17 10:14:27 +0200 (Sun, 17 Jun 2007) | 1 line
  
  fixing painting of 32bpp bitmaps with no Alpha
........
  r11326 | paul | 2007-06-17 10:16:00 +0200 (Sun, 17 Jun 2007) | 1 line
  
  missed file
........
  r11337 | paul | 2007-06-20 03:44:47 +0200 (Wed, 20 Jun 2007) | 3 lines
  
  - revert previous commit
  - create 24bpp bitmaps by default
........
  r11342 | marc | 2007-06-21 01:47:30 +0200 (Thu, 21 Jun 2007) | 3 lines
  
  * Added Alpha support on Carbon
  * Simplified win32 rawimage_fromdevice
........
  r11343 | paul | 2007-06-21 04:36:28 +0200 (Thu, 21 Jun 2007) | 1 line
  
  - adopt gtk2 code
........
  r11344 | paul | 2007-06-21 04:41:41 +0200 (Thu, 21 Jun 2007) | 1 line
  
  make gtk2 work
........
  r11353 | paul | 2007-06-22 10:12:19 +0200 (Fri, 22 Jun 2007) | 1 line
  
  - default WS imagelist implementation
........
  r11358 | marc | 2007-06-23 13:29:06 +0200 (Sat, 23 Jun 2007) | 2 lines
  
  * Implemented MaskBlit
........
  r11359 | paul | 2007-06-23 20:02:52 +0200 (Sat, 23 Jun 2007) | 1 line
  
  draw new imagelist bitmap on widget canvas
........
  r11371 | marc | 2007-06-25 23:50:13 +0200 (Mon, 25 Jun 2007) | 2 lines
  
  * Rawimage rework
........
  r11372 | marc | 2007-06-25 23:51:00 +0200 (Mon, 25 Jun 2007) | 2 lines
  
  + Added header
........
  r11373 | marc | 2007-06-26 00:05:55 +0200 (Tue, 26 Jun 2007) | 2 lines
  
  * Swapped RGBA <-> ARGB defualt format since most widgetsets use ARGB
........
  r11374 | marc | 2007-06-26 00:09:36 +0200 (Tue, 26 Jun 2007) | 2 lines
  
  * added
........
  r11462 | marc | 2007-07-12 00:16:02 +0200 (Thu, 12 Jul 2007) | 2 lines
  
  + added header
........
  r11463 | marc | 2007-07-12 00:18:49 +0200 (Thu, 12 Jul 2007) | 2 lines
  
  * Added alpha/masked strechblt support
........
  r11464 | marc | 2007-07-12 00:21:27 +0200 (Thu, 12 Jul 2007) | 2 lines
  
  * create DIBSection instead of DIBitmap
........
  r11502 | marc | 2007-07-14 00:23:42 +0200 (Sat, 14 Jul 2007) | 2 lines
  
  * Fixed transparentcolor after loading bitmap
........
  r11505 | marc | 2007-07-14 15:10:56 +0200 (Sat, 14 Jul 2007) | 2 lines
  
  - Removed ARGB dataconversion, internal format is by default the same now
........
  r11531 | marc | 2007-07-17 01:23:34 +0200 (Tue, 17 Jul 2007) | 2 lines
  
  * changed TRawImage into object
........
  r11533 | paul | 2007-07-17 05:10:31 +0200 (Tue, 17 Jul 2007) | 3 lines
  
  - change several occurrence of FillChar(..TRawImageDescription..) with call to Init
  - change imagelist defines to use old imagelist (new is crashes ide)
  - change TWin32ThemeServices to use old imagelist
........
  r11534 | paul | 2007-07-17 05:19:02 +0200 (Tue, 17 Jul 2007) | 3 lines
  
  - change several occurrence of FillChar(..TRawImageDescription..) with call to Init in Qt widgetset
  - change TRawImageDescription.IsEqual and TRawImage.IsEqual
........
  r11535 | paul | 2007-07-17 05:23:53 +0200 (Tue, 17 Jul 2007) | 1 line
  
  - change several occurrence of FillChar(..TRawImageDescription..) with call to Init in wince widgetset
........
  r11554 | marc | 2007-07-18 00:10:11 +0200 (Wed, 18 Jul 2007) | 2 lines
  
  * fixed compilation on 2.0.4
........
  r11555 | marc | 2007-07-18 00:10:44 +0200 (Wed, 18 Jul 2007) | 2 lines
  
  * fixed compilation
........
  r11556 | marc | 2007-07-18 00:11:43 +0200 (Wed, 18 Jul 2007) | 2 lines
  
  * fixed fillchar on TRawImage object
........
  r11572 | marc | 2007-07-19 01:41:35 +0200 (Thu, 19 Jul 2007) | 2 lines
  
  * fixed crash when object has vmt
........
  r11573 | marc | 2007-07-19 01:42:14 +0200 (Thu, 19 Jul 2007) | 2 lines
  
  * Made TRawimage compatible with record again
........
  r11580 | marc | 2007-07-20 01:33:20 +0200 (Fri, 20 Jul 2007) | 2 lines
  
  * enabled newimagelist
........
  r11581 | marc | 2007-07-20 01:33:48 +0200 (Fri, 20 Jul 2007) | 2 lines
  
  * fixed font
........

git-svn-id: trunk@11861 -
2007-08-25 01:49:40 +00:00

476 lines
15 KiB
ObjectPascal

{ $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).CreateSubImage(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.