unit spkt_Buttons; {$mode delphi} {.$Define EnhancedRecordSupport} (******************************************************************************* * * * Plik: spkt_Buttons.pas * * Opis: Modu³ zawieraj¹cy komponenty przycisków dla toolbara. * * Copyright: (c) 2009 by Spook. Jakiekolwiek u¿ycie komponentu bez * * uprzedniego uzyskania licencji od autora stanowi z³amanie * * prawa autorskiego! * * * *******************************************************************************) interface uses Graphics, Classes, Controls, Menus, ActnList, Math, Dialogs, ImgList, Forms, SpkGUITools, SpkGraphTools, SpkMath, spkt_Const, spkt_BaseItem, spkt_Exceptions, spkt_Tools; type TSpkButtonState = (bsIdle, bsBtnHottrack, bsBtnPressed, bsDropdownHottrack, bsDropdownPressed); TSpkMouseButtonElement = (beNone, beButton, beDropdown); TSpkButtonKind = (bkButton, bkButtonDropdown, bkDropdown); type TSpkBaseButton = class; TSpkButtonActionLink = class(TActionLink) private protected FClient : TSpkBaseButton; procedure AssignClient(AClient: TObject); override; function IsOnExecuteLinked: Boolean; override; procedure SetCaption(const Value: string); override; procedure SetEnabled(Value: Boolean); override; procedure SetImageIndex(Value: integer); override; procedure SetVisible(Value: Boolean); override; procedure SetOnExecute(Value: TNotifyEvent); override; public function IsCaptionLinked: Boolean; override; function IsEnabledLinked: Boolean; override; function IsImageIndexLinked: Boolean; override; function IsVisibleLinked: Boolean; override; end; TSpkBaseButton = class abstract(TSpkBaseItem) private FMouseHoverElement : TSpkMouseButtonElement; FMouseActiveElement : TSpkMouseButtonElement; protected FCaption : string; FOnClick : TNotifyEvent; FActionLink : TSpkButtonActionLink; FButtonState : TSpkButtonState; FButtonRect : T2DIntRect; FDropdownRect : T2DIntRect; FButtonKind : TSpkButtonKind; FDropdownMenu : TPopupMenu; // *** Obs³uga rysowania *** /// Zadaniem metody w odziedziczonych klasach jest obliczenie /// rectów przycisku i menu dropdown w zale¿noœci od FButtonState procedure CalcRects; virtual; abstract; function GetDropdownPoint : T2DIntPoint; virtual; abstract; // *** Obs³uga akcji *** procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); virtual; procedure DoActionChange(Sender: TObject); procedure Click; virtual; function GetDefaultCaption: String; virtual; // *** Gettery i settery *** procedure SetEnabled(const Value : boolean); override; procedure SetDropdownMenu(const Value : TPopupMenu); procedure SetRect(const Value: T2DIntRect); override; procedure SetCaption(const Value : string); procedure SetAction(const Value : TBasicAction); virtual; procedure SetButtonKind(const Value : TSpkButtonKind); function GetAction: TBasicAction; property ButtonKind : TSpkButtonKind read FButtonKind write SetButtonKind; property DropdownMenu : TPopupMenu read FDropdownMenu write SetDropdownMenu; public constructor Create(AOwner : TComponent); override; procedure MouseLeave; override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; function GetRootComponent: TComponent; published property Caption : string read FCaption write SetCaption; property Action : TBasicAction read GetAction write SetAction; property OnClick : TNotifyEvent read FOnClick write FOnClick; end; type TSpkLargeButton = class(TSpkBaseButton) private procedure FindBreakPlace(s : string; out Position : integer; out Width : integer); protected FLargeImageIndex: TImageIndex; procedure CalcRects; override; function GetDropdownPoint : T2DIntPoint; override; procedure SetLargeImageIndex(const Value: TImageIndex); public constructor Create(AOwner : TComponent); override; function GetWidth : integer; override; function GetTableBehaviour : TSpkItemTableBehaviour; override; function GetGroupBehaviour : TSpkItemGroupBehaviour; override; function GetSize : TSpkItemSize; override; procedure Draw(ABuffer : TBitmap; ClipRect : T2DIntRect); override; published property LargeImageIndex: TImageIndex read FLargeImageIndex write SetLargeImageIndex default -1; property ButtonKind; property DropdownMenu; end; type TSpkSmallButton = class(TSpkBaseButton) private protected FImageIndex : TImageIndex; FTableBehaviour : TSpkItemTableBehaviour; FGroupBehaviour : TSPkItemGroupBehaviour; FHideFrameWhenIdle : boolean; FShowCaption : boolean; procedure CalcRects; override; function GetDropdownPoint : T2DIntPoint; override; procedure ConstructRects(var BtnRect, DropRect : T2DIntRect); procedure SetImageIndex(const Value : TImageIndex); procedure SetGroupBehaviour(const Value: TSpkItemGroupBehaviour); procedure SetHideFrameWhenIdle(const Value: boolean); procedure SetTableBehaviour(const Value: TSpkItemTableBehaviour); procedure SetShowCaption(const Value: boolean); public constructor Create(AOwner : TComponent); override; function GetWidth : integer; override; function GetTableBehaviour : TSpkItemTableBehaviour; override; function GetGroupBehaviour : TSpkItemGroupBehaviour; override; function GetSize : TSpkItemSize; override; procedure Draw(ABuffer : TBitmap; ClipRect : T2DIntRect); override; published property ShowCaption : boolean read FShowCaption write SetShowCaption; property TableBehaviour : TSpkItemTableBehaviour read FTableBehaviour write SetTableBehaviour; property GroupBehaviour : TSpkItemGroupBehaviour read FGroupBehaviour write SetGroupBehaviour; property HideFrameWhenIdle : boolean read FHideFrameWhenIdle write SetHideFrameWhenIdle; property ImageIndex : TImageIndex read FImageIndex write SetImageIndex default -1; property ButtonKind; property DropdownMenu; end; implementation uses LCLType, LCLIntf, LCLProc, SysUtils, spkt_Pane; { TSpkButtonActionLink } procedure TSpkButtonActionLink.AssignClient(AClient: TObject); begin inherited AssignClient(AClient); FClient:=TSpkBaseButton(AClient); end; function TSpkButtonActionLink.IsCaptionLinked: Boolean; begin result:=(inherited IsCaptionLinked) and (assigned(FClient)) and (FClient.Caption = (Action as TCustomAction).Caption); end; function TSpkButtonActionLink.IsEnabledLinked: Boolean; begin result:=(inherited IsEnabledLinked) and (assigned(FClient)) and (FClient.Enabled = (Action as TCustomAction).Enabled); end; function TSpkButtonActionLink.IsOnExecuteLinked: Boolean; begin Result := inherited IsOnExecuteLinked and (@TSpkBaseButton(FClient).OnClick = @Action.OnExecute); end; function TSpkButtonActionLink.IsImageIndexLinked: Boolean; begin Result := (inherited IsImageIndexLinked) and ( ((FClient is TSpkSmallButton) and (TSpkSmallButton(FClient).ImageIndex = (Action as TCustomAction).ImageIndex)) or ((FClient is TSpkLargeButton) and (TSpkLargeButton(FClient).LargeImageIndex = (Action as TCustomAction).ImageIndex)) ); end; function TSpkButtonActionLink.IsVisibleLinked: Boolean; begin result:=(inherited IsVisibleLinked) and (assigned(FClient)) and (FClient.Visible = (Action as TCustomAction).Visible); end; procedure TSpkButtonActionLink.SetCaption(const Value: string); begin if IsCaptionLinked then FClient.Caption := Value; end; procedure TSpkButtonActionLink.SetEnabled(Value: Boolean); begin if IsEnabledLinked then FClient.Enabled := Value; end; procedure TSpkButtonActionLink.SetImageIndex(Value: integer); begin if IsImageIndexLinked then begin if (FClient is TSpkSmallButton) then (TSpkSmallButton(FClient)).ImageIndex := Value; if (FClient is TSpkLargeButton) then (TSpkLargeButton(FClient)).LargeImageIndex := Value; end; end; procedure TSpkButtonActionLink.SetOnExecute(Value: TNotifyEvent); begin if IsOnExecuteLinked then FClient.OnClick := Value; end; procedure TSpkButtonActionLink.SetVisible(Value: Boolean); begin if IsVisibleLinked then FClient.Visible := Value; end; { TSpkBaseButton } procedure TSpkBaseButton.ActionChange(Sender: TObject; CheckDefaults: Boolean); begin if Sender is TCustomAction then with TCustomAction(Sender) do begin if not CheckDefaults or (Self.Caption = '') or (Self.Caption = GetDefaultCaption) then Self.Caption := Caption; if not CheckDefaults or (Self.Enabled = True) then Self.Enabled := Enabled; if not CheckDefaults or (Self.Visible = True) then Self.Visible := Visible; if not CheckDefaults or not Assigned(Self.OnClick) then Self.OnClick := OnExecute; if self is TSpkSmallButton then begin if not CheckDefaults or (TSpkSmallButton(self).ImageIndex < 0) then TSpkSmallButton(self).ImageIndex := ImageIndex; end; if self is TSpkLargeButton then begin if not CheckDefaults or (TSpkLargeButton(self).LargeImageIndex < 0) then TSpkLargeButton(Self).LargeImageIndex := ImageIndex; end; end; end; constructor TSpkBaseButton.Create(AOwner : TComponent); begin inherited Create(AOwner); FCaption:=GetDefaultCaption; FButtonState:=bsIdle; FButtonKind:=bkButton; {$IFDEF EnhancedRecordSupport} FButtonRect:=T2DIntRect.Create(0, 0, 1, 1); FDropdownRect:=T2DIntRect.Create(0, 0, 1, 1); {$ELSE} FButtonRect.Create(0, 0, 1, 1); FDropdownRect.Create(0, 0, 1, 1); {$ENDIF} FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; end; procedure TSpkBaseButton.Click; begin if Assigned(FOnClick) then FOnClick(self) end; procedure TSpkBaseButton.DoActionChange(Sender: TObject); begin if Sender = Action then ActionChange(Sender, False); end; function TSpkBaseButton.GetAction: TBasicAction; begin if assigned(FActionLink) then result:=FActionLink.Action else result:=nil; end; function TSpkBaseButton.GetDefaultCaption: String; begin result := 'Button'; end; function TSpkBaseButton.GetRootComponent: TComponent; var pane: TSpkBaseItem; tab: TSpkBaseItem; begin result := nil; if Collection <> nil then pane := TSpkBaseItem(Collection.RootComponent) else exit; if (pane <> nil) and (pane.Collection <> nil) then tab := TSpkBaseItem(pane.Collection.RootComponent) else exit; if (tab <> nil) and (tab.Collection <> nil) then result := tab.Collection.RootComponent; end; procedure TSpkBaseButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if FEnabled then begin // Przyciski reaguj¹ tylko na lewy przycisk myszy if Button <> mbLeft then exit; if FMouseActiveElement = beButton then begin if FButtonState<>bsBtnPressed then begin FButtonState:=bsBtnPressed; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseActiveElement = beDropdown then begin if FButtonState<>bsDropdownPressed then begin FButtonState:=bsDropdownPressed; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseActiveElement = beNone then begin if FMouseHoverElement = beButton then begin FMouseActiveElement:=beButton; if FButtonState<>bsBtnPressed then begin FButtonState:=bsBtnPressed; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseHoverElement = beDropdown then begin FMouseActiveElement:=beDropdown; if FButtonState<>bsDropdownPressed then begin FButtonState:=bsDropdownPressed; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end; end; end else begin FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; procedure TSpkBaseButton.MouseLeave; begin if FEnabled then begin if FMouseActiveElement = beNone then begin if FMouseHoverElement = beButton then begin // Placeholder, gdyby zasz³a potrzeba obs³ugi tego zdarzenia end else if FMouseHoverElement = beDropdown then begin // Placeholder, gdyby zasz³a potrzeba obs³ugi tego zdarzenia end; end; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end else begin FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; procedure TSpkBaseButton.MouseMove(Shift: TShiftState; X, Y: Integer); var NewMouseHoverElement : TSpkMouseButtonElement; begin if FEnabled then begin {$IFDEF EnhancedRecordSupport} if FButtonRect.Contains(T2DIntPoint.Create(X,Y)) then {$ELSE} if FButtonRect.Contains(X,Y) then {$ENDIF} NewMouseHoverElement:=beButton else if (FButtonKind = bkButtonDropdown) and {$IFDEF EnhancedRecordSupport} (FDropdownRect.Contains(T2DIntPoint.Create(X,Y))) then {$ELSE} (FDropdownRect.Contains(X,Y)) then {$ENDIF} NewMouseHoverElement:=beDropdown else NewMouseHoverElement:=beNone; if FMouseActiveElement = beButton then begin if (NewMouseHoverElement = beNone) and (FButtonState<>bsIdle) then begin FButtonState:=bsIdle; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end else if (NewMouseHoverElement = beButton) and (FButtonState<>bsBtnPressed) then begin FButtonState:=bsBtnPressed; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseActiveElement = beDropdown then begin if (NewMouseHoverElement = beNone) and (FButtonState<>bsIdle) then begin FButtonState:=bsIdle; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end else if (NewMouseHoverElement = beDropdown) and (FButtonState<>bsDropdownPressed) then begin FButtonState:=bsDropdownPressed; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseActiveElement = beNone then begin // Z uwagi na uproszczon¹ obs³ugê myszy w przycisku, nie ma potrzeby // informowaæ poprzedniego elementu o tym, ¿e mysz opuœci³a jego obszar. if NewMouseHoverElement = beButton then begin if FButtonState<>bsBtnHottrack then begin FButtonState:=bsBtnHottrack; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end else if NewMouseHoverElement = beDropdown then begin if FButtonState<>bsDropdownHottrack then begin FButtonState:=bsDropdownHottrack; if FToolbarDispatch<>nil then FToolbarDispatch.NotifyVisualsChanged; end; end; end; FMouseHoverElement:=NewMouseHoverElement; end else begin FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; procedure TSpkBaseButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ClearActive : boolean; DropPoint: T2DIntPoint; begin if FEnabled then begin // Przyciski reaguj¹ tylko na lewy przycisk myszy if Button <> mbLeft then exit; ClearActive:=not(ssLeft in Shift); if FMouseActiveElement = beButton then begin // Zdarzenie zadzia³a tylko wtedy, gdy przycisk myszy zosta³ puszczony nad // przyciskiem if FMouseHoverElement = beButton then begin if FButtonKind in [bkButton, bkButtonDropdown] then begin Click; FButtonState:=bsBtnHottrack; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end else if FButtonKind = bkDropdown then begin if assigned(FDropdownMenu) then begin DropPoint:=FToolbarDispatch.ClientToScreen(GetDropdownPoint); FDropdownMenu.Popup(DropPoint.x, DropPoint.y); FButtonState:=bsBtnHottrack; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; end else if FMouseActiveElement = beDropDown then begin // Zdarzenie zadzia³a tylko wtedy, gdy przycisk myszy zosta³ puszczony nad // przyciskiem DropDown if FMouseHoverElement = beDropDown then begin if assigned(FDropdownMenu) then begin DropPoint:=FToolbarDispatch.ClientToScreen(GetDropdownPoint); FDropdownMenu.Popup(DropPoint.x, DropPoint.y); FButtonState:=bsBtnHottrack; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; if (ClearActive) and (FMouseActiveElement<>FMouseHoverElement) then begin // Z uwagi na uproszczon¹ obs³ugê, nie ma potrzeby informowaæ poprzedniego // elementu o tym, ¿e mysz opuœci³a jego obszar. if FMouseHoverElement = beButton then begin if FButtonState<>bsBtnHottrack then begin FButtonState:=bsBtnHottrack; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseHoverElement = beDropdown then begin if FButtonState<>bsDropdownHottrack then begin FButtonState:=bsDropdownHottrack; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end else if FMouseHoverElement = beNone then begin if FButtonState <> bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; if ClearActive then begin FMouseActiveElement:=beNone; end; end else begin FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; procedure TSpkBaseButton.SetAction(const Value: TBasicAction); begin if Value = nil then begin FActionLink.Free; FActionLink := nil; end else begin if FActionLink = nil then FActionLink := TSpkButtonActionLink.Create(self); FActionLink.Action := Value; FActionLink.OnChange := DoActionChange; ActionChange(Value, csLoading in Value.ComponentState); end; end; procedure TSpkBaseButton.SetButtonKind(const Value: TSpkButtonKind); begin FButtonKind:=Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkBaseButton.SetCaption(const Value: string); begin FCaption:=Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkBaseButton.SetDropdownMenu(const Value: TPopupMenu); begin FDropdownMenu:=Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkBaseButton.SetEnabled(const Value: boolean); begin inherited; if not(FEnabled) then begin // Jeœli przycisk zosta³ wy³¹czony, zostaje natychmiast prze³¹czony // w stan Idle i zerowane s¹ elementy aktywne i pod mysz¹. Jeœli zosta³ // w³¹czony, jego stan zmieni siê podczas pierwszej akcji myszy. FMouseHoverElement:=beNone; FMouseActiveElement:=beNone; if FButtonState<>bsIdle then begin FButtonState:=bsIdle; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; end; end; procedure TSpkBaseButton.SetRect(const Value: T2DIntRect); begin inherited; CalcRects; end; { TSpkLargeButton } procedure TSpkLargeButton.CalcRects; begin {$IFDEF EnhancedRecordSupport} if FButtonKind = bkButtonDropdown then begin FButtonRect:=T2DIntRect.Create(FRect.Left, FRect.Top, FRect.Right, FRect.Bottom - LARGEBUTTON_DROPDOWN_FIELD_SIZE); FDropdownRect:=T2DIntRect.Create(FRect.Left, FRect.Bottom - LARGEBUTTON_DROPDOWN_FIELD_SIZE + 1, FRect.Right, FRect.Bottom); end else begin FButtonRect:=FRect; FDropdownRect:=T2DIntRect.Create(0, 0, 0, 0); end; {$ELSE} if FButtonKind = bkButtonDropdown then begin FButtonRect.Create(FRect.Left, FRect.Top, FRect.Right, FRect.Bottom - LARGEBUTTON_DROPDOWN_FIELD_SIZE); FDropdownRect.Create(FRect.Left, FRect.Bottom - LARGEBUTTON_DROPDOWN_FIELD_SIZE + 1, FRect.Right, FRect.Bottom); end else begin FButtonRect:=FRect; FDropdownRect.Create(0, 0, 0, 0); end; {$ENDIF} end; constructor TSpkLargeButton.Create(AOwner: TComponent); begin inherited; FLargeImageIndex:=-1; end; procedure TSpkLargeButton.Draw(ABuffer: TBitmap; ClipRect: T2DIntRect); var FrameColor: TColor; InnerLightColor: TColor; InnerDarkColor: TColor; GradientFromColor: TColor; GradientToColor: TColor; GradientKind : TBackgroundKind; DrawRgn, TmpRgn : HRGN; x: Integer; y: Integer; FontColor: TColor; BreakPos: Integer; BreakWidth: Integer; s: string; TextHeight: Integer; begin if FToolbarDispatch=nil then exit; if FAppearance=nil then exit; if (FRect.width<2*LARGEBUTTON_RADIUS) or (FRect.Height<2*LARGEBUTTON_RADIUS) then exit; if FButtonKind in [bkButton, bkDropdown] then begin {$REGION 'Tryb bez dodatkowego przycisku z rozwijanym menu'} // *** T³o *** if not(FEnabled) then begin {$REGION 'T³o dla disabled'} // Brak t³a {$ENDREGION} end else if FButtonState = bsIdle then begin {$REGION 'T³o dla Idle'} // Brak t³a {$ENDREGION} end else if FButtonState = bsBtnHottrack then begin {$REGION 'T³o dla HotTrack'} TGuiTools.DrawRoundRect(ABuffer.Canvas, {$IFDEF EnhancedRecordSupport} T2DIntRect.Create(FButtonRect.left, FButtonRect.Top, FButtonRect.Right, FButtonRect.Bottom), {$ELSE} Create2DIntRect(FButtonRect.left, FButtonRect.Top, FButtonRect.Right, FButtonRect.Bottom), {$ENDIF} LARGEBUTTON_RADIUS, FAppearance.Element.HotTrackGradientFromColor, FAppearance.Element.HotTrackGradientToColor, FAppearance.Element.HotTrackGradientType, ClipRect); TGuiTools.DrawAARoundFrame(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntRect.Create(FButtonRect.left+1, FButtonRect.top+1, FButtonRect.right-1, FButtonRect.Bottom-1), {$ELSE} Create2DIntRect(FButtonRect.left+1, FButtonRect.top+1, FButtonRect.right-1, FButtonRect.Bottom-1), {$ENDIF} LARGEBUTTON_RADIUS, FAppearance.Element.HotTrackInnerLightColor, ClipRect); TGuiTools.DrawAARoundFrame(ABuffer, FButtonRect, LARGEBUTTON_RADIUS, FAppearance.Element.HotTrackFrameColor, ClipRect); {$ENDREGION} end else if FButtonState = bsBtnPressed then begin {$REGION 'T³o dla Pressed'} TGuiTools.DrawRoundRect(ABuffer.Canvas, {$IFDEF EnhancedRecordSupport} T2DIntRect.Create(FButtonRect.left, FButtonRect.Top, FButtonRect.Right, FButtonRect.Bottom), {$ELSE} Create2DIntRect(FButtonRect.left, FButtonRect.Top, FButtonRect.Right, FButtonRect.Bottom), {$ENDIF} LARGEBUTTON_RADIUS, FAppearance.Element.ActiveGradientFromColor, FAppearance.Element.ActiveGradientToColor, FAppearance.Element.ActiveGradientType, ClipRect); TGuiTools.DrawAARoundFrame(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntRect.Create(FButtonRect.left+1, FButtonRect.top+1, FButtonRect.right-1, FButtonRect.Bottom-1), {$ELSE} Create2DIntRect(FButtonRect.left+1, FButtonRect.top+1, FButtonRect.right-1, FButtonRect.Bottom-1), {$ENDIF} LARGEBUTTON_RADIUS, FAppearance.Element.ActiveInnerLightColor, ClipRect); TGuiTools.DrawAARoundFrame(ABuffer, FButtonRect, LARGEBUTTON_RADIUS, FAppearance.Element.ActiveFrameColor, ClipRect); {$ENDREGION} end else raise InternalException.create('TSpkLargeButton.Draw: Nieprawid³owa wartoœæ FButtonState!'); // *** Ikona *** if not(FEnabled) then begin {$REGION 'Ikona wy³¹czona'} if (FLargeImageIndex>=0) and (FDisabledLargeImages<>nil) and (FLargeImageIndex=0) and (FLargeImages<>nil) and (FLargeImageIndex=0) and (FLargeImages<>nil) and (FLargeImageIndex0 then begin // Tekst z³amany TextHeight:=ABuffer.Canvas.Textheight('Wy'); s:=copy(FCaption, 1, BreakPos-1); x:=FRect.Left + (FRect.width - ABuffer.Canvas.Textwidth(s)) div 2; y:=FRect.Top + LARGEBUTTON_CAPTION_TOP_RAIL - TextHeight div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, s, FontColor, ClipRect); s:=copy(FCaption, BreakPos+1, length(FCaption) - BreakPos); x:=FRect.Left + (FRect.width - ABuffer.Canvas.Textwidth(s)) div 2; y:=FRect.Top + LARGEBUTTON_CAPTION_BOTTOM_RAIL - TextHeight div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, s, FontColor, ClipRect); end else begin // Tekst nie z³amany TextHeight:=ABuffer.Canvas.Textheight('Wy'); x:=FButtonRect.Left + (FButtonRect.width - ABuffer.Canvas.Textwidth(FCaption)) div 2; y:=FRect.Top + LARGEBUTTON_CAPTION_TOP_RAIL - TextHeight div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, FCaption, FontColor, ClipRect); end; if FButtonKind = bkDropdown then begin // Chevron strza³ki w dó³ if not(FEnabled) then begin case FButtonState of bsIdle: FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.IdleCaptionColor); bsBtnHottrack, bsDropdownHottrack : FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.HotTrackCaptionColor); bsBtnPressed, bsDropdownPressed: FontColor:=TColorTools.ColorToGrayscale(FAppearance.ELement.ActiveCaptionColor); end; end else begin case FButtonState of bsIdle: FontColor:=FAppearance.Element.IdleCaptionColor; bsBtnHottrack, bsDropdownHottrack : FontColor:=FAppearance.Element.HotTrackCaptionColor; bsBtnPressed, bsDropdownPressed: FontColor:=FAppearance.ELement.ActiveCaptionColor; end; end; ABuffer.Canvas.Font.Charset:=DEFAULT_CHARSET; ABuffer.Canvas.Font.Name:='Marlett'; ABuffer.Canvas.Font.Size:=8; ABuffer.Canvas.Font.Style:=[]; ABuffer.Canvas.Font.Orientation:=0; x:=FButtonRect.Left + (FButtonRect.width - ABuffer.Canvas.Textwidth('u')) div 2; y:=FButtonRect.bottom - ABuffer.Canvas.Textheight('u') - LARGEBUTTON_CHEVRON_HMARGIN; TGUITools.DrawText(ABuffer.Canvas, x, y, 'u', FontColor, ClipRect); end; {$ENDREGION} end else begin {$REGION 'Tryb z rozwijanym menu'} // *** T³o *** if not(FEnabled) then begin {$REGION 'T³o dla Disabled'} // {$ENDREGION} end else if FButtonState = bsIdle then begin {$REGION 'T³o dla Idle'} // {$ENDREGION} end else if (FButtonState = bsBtnHottrack) or (FButtonState = bsDropdownHottrack) or (FButtonState = bsBtnPressed) or (FButtonState = bsDropdownPressed) then begin {$REGION 'T³o dla aktywnego'} // *** Przycisk *** {$REGION 'Ustalanie kolorów'} if FButtonState = bsBtnHottrack then begin FrameColor:=FAppearance.Element.HotTrackFrameColor; InnerLightColor:=FAppearance.Element.HotTrackInnerLightColor; GradientFromColor:=FAppearance.Element.HotTrackGradientFromColor; GradientToColor:=FAppearance.Element.HotTrackGradientToColor; GradientKind:=FAppearance.Element.HotTrackGradientType; end else if FButtonState = bsBtnPressed then begin FrameColor:=FAppearance.Element.ActiveFrameColor; InnerLightColor:=FAppearance.Element.ActiveInnerLightColor; GradientFromColor:=FAppearance.Element.ActiveGradientFromColor; GradientToColor:=FAppearance.Element.ActiveGradientToColor; GradientKind:=FAppearance.Element.ActiveGradientType; end else begin FrameColor:=TColorTools.Brighten(FAppearance.Element.HotTrackFrameColor,40); InnerLightColor:=TColorTools.Brighten(FAppearance.Element.HotTrackInnerLightColor,40); GradientFromColor:=TColorTools.Brighten(FAppearance.Element.HotTrackGradientFromColor,40); GradientToColor:=TColorTools.Brighten(FAppearance.Element.HotTrackGradientToColor,40); GradientKind:=FAppearance.Element.HotTrackGradientType; end; {$ENDREGION} {$REGION 'T³o przycisku'} DrawRgn:=CreateRectRgn(FButtonRect.Left, FButtonRect.Top + LARGEBUTTON_RADIUS, FButtonRect.Right + 1, FButtonRect.Bottom); TmpRgn:=CreateRectRgn(FButtonRect.left + LARGEBUTTON_RADIUS, FButtonRect.Top, FButtonRect.right - LARGEBUTTON_RADIUS + 1, FButtonRect.Top + LARGEBUTTON_RADIUS); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TmpRgn:=CreateEllipticRgn(FButtonRect.Left, FButtonRect.Top, FButtonRect.Left + 2 * LARGEBUTTON_RADIUS + 1, FButtonRect.Top + 2 * LARGEBUTTON_RADIUS + 1); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TmpRgn:=CreateEllipticRgn(FButtonRect.Right - 2 * LARGEBUTTON_RADIUS + 1, FButtonRect.Top, FButtonRect.Right + 2, FButtonRect.Top + 2 * LARGEBUTTON_RADIUS + 1); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TGuiTools.DrawRegion(ABuffer.Canvas, DrawRgn, FRect, GradientFromColor, GradientToColor, GradientKind, ClipRect); DeleteObject(DrawRgn); {$ENDREGION} {$REGION 'Ramka przycisku'} // Wewnêtrzna ramka TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FButtonRect.Left + 1, FButtonRect.Top + 1), {$ELSE} Create2DIntPoint(FButtonRect.Left + 1, FButtonRect.Top + 1), {$ENDIF} LARGEBUTTON_RADIUS, cpLeftTop, InnerLightColor, ClipRect); TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FButtonRect.Right - LARGEBUTTON_RADIUS, FButtonRect.Top + 1), {$ELSE} Create2DIntPoint(FButtonRect.Right - LARGEBUTTON_RADIUS, FButtonRect.Top + 1), {$ENDIF} LARGEBUTTON_RADIUS, cpRightTop, InnerLightColor, ClipRect); TGuiTools.DrawHLine(ABuffer, FButtonRect.Left + LARGEBUTTON_RADIUS + 1, FButtonRect.Right - LARGEBUTTON_RADIUS - 1, FButtonRect.Top + 1, InnerLightColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FButtonRect.Left + 1, FButtonRect.Top + LARGEBUTTON_RADIUS + 1, FButtonRect.Bottom, InnerLightColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FButtonRect.Right - 1, FButtonRect.Top + LARGEBUTTON_RADIUS + 1, FButtonRect.Bottom, InnerLightColor, ClipRect); if FButtonState = bsBtnPressed then TGuiTools.DrawHLine(ABuffer, FButtonRect.Left + 1, FButtonRect.Right - 1, FButtonRect.Bottom, FrameColor, ClipRect) else TGuiTools.DrawHLine(ABuffer, FButtonRect.Left + 1, FButtonRect.Right - 1, FButtonRect.Bottom, InnerLightColor, ClipRect); // Zewnêtrzna ramka TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FButtonRect.Left, FButtonRect.Top), {$ELSE} Create2DIntPoint(FButtonRect.Left, FButtonRect.Top), {$ENDIF} LARGEBUTTON_RADIUS, cpLeftTop, FrameColor, ClipRect); TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FButtonRect.Right - LARGEBUTTON_RADIUS + 1, FButtonRect.Top), {$ELSE} Create2DIntPoint(FButtonRect.Right - LARGEBUTTON_RADIUS + 1, FButtonRect.Top), {$ENDIF} LARGEBUTTON_RADIUS, cpRightTop, FrameColor, ClipRect); TGuiTools.DrawHLine(ABuffer, FButtonRect.Left + LARGEBUTTON_RADIUS, FButtonRect.Right - LARGEBUTTON_RADIUS, FButtonRect.Top, FrameColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FButtonRect.Left, FButtonRect.Top + LARGEBUTTON_RADIUS, FButtonRect.Bottom, FrameColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FButtonRect.Right, FButtonRect.Top + LARGEBUTTON_RADIUS, FButtonRect.Bottom, FrameColor, ClipRect); {$ENDREGION} // *** Dropdown *** {$REGION 'Ustalanie kolorów'} if FButtonState = bsDropdownHottrack then begin FrameColor:=FAppearance.Element.HotTrackFrameColor; InnerLightColor:=FAppearance.Element.HotTrackInnerLightColor; InnerDarkColor:=FAppearance.Element.HotTrackInnerDarkColor; GradientFromColor:=FAppearance.Element.HotTrackGradientFromColor; GradientToColor:=FAppearance.Element.HotTrackGradientToColor; GradientKind:=FAppearance.Element.HotTrackGradientType; end else if FButtonState = bsDropdownPressed then begin FrameColor:=FAppearance.Element.ActiveFrameColor; InnerLightColor:=FAppearance.Element.ActiveInnerLightColor; InnerDarkColor:=FAppearance.Element.ActiveInnerDarkColor; GradientFromColor:=FAppearance.Element.ActiveGradientFromColor; GradientToColor:=FAppearance.Element.ActiveGradientToColor; GradientKind:=FAppearance.Element.ActiveGradientType; end else begin FrameColor:=TColorTools.Brighten(FAppearance.Element.HotTrackFrameColor,20); InnerLightColor:=TColorTools.Brighten(FAppearance.Element.HotTrackInnerLightColor,20); InnerDarkColor:=TColorTools.Brighten(FAppearance.Element.HotTrackInnerDarkColor,20); GradientFromColor:=TColorTools.Brighten(FAppearance.Element.HotTrackGradientFromColor,20); GradientToColor:=TColorTools.Brighten(FAppearance.Element.HotTrackGradientToColor,20); GradientKind:=FAppearance.Element.HotTrackGradientType; end; {$ENDREGION} {$REGION 'T³o dropdown'} DrawRgn:=CreateRectRgn(FDropdownRect.left, FDropdownRect.Top, FDropdownRect.Right + 1, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1); TmpRgn:=CreateRectRgn(FDropdownRect.left + LARGEBUTTON_RADIUS, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1, FDropdownRect.Right - LARGEBUTTON_RADIUS + 1, FDropdownRect.Bottom + 1); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TmpRgn:=CreateEllipticRgn(FDropdownRect.Left, FDropdownRect.bottom - 2 * LARGEBUTTON_RADIUS + 1, FDropdownRect.left + 2 * LARGEBUTTON_RADIUS + 1, FDropdownRect.Bottom + 2); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TmpRgn:=CreateEllipticRgn(FDropdownRect.Right - 2 * LARGEBUTTON_RADIUS + 1, FDropdownRect.Bottom - 2 * LARGEBUTTON_RADIUS + 1, FDropdownRect.Right + 2, FDropdownRect.Bottom + 2); CombineRgn(DrawRgn, DrawRgn, TmpRgn, RGN_OR); DeleteObject(TmpRgn); TGuiTools.DrawRegion(ABuffer.Canvas, DrawRgn, FRect, GradientFromColor, GradientToColor, GradientKind, ClipRect); DeleteObject(DrawRgn); {$ENDREGION} {$REGION 'Ramka dropdown'} // Wewnêtrzna ramka TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FDropdownRect.Left + 1, FDropdownRect.Bottom - LARGEBUTTON_RADIUS), {$ELSE} Create2DIntPoint(FDropdownRect.Left + 1, FDropdownRect.Bottom - LARGEBUTTON_RADIUS), {$ENDIF} LARGEBUTTON_RADIUS, cpLeftBottom, InnerLightColor); TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FDropdownRect.right - LARGEBUTTON_RADIUS, FDropdownRect.Bottom - LARGEBUTTON_RADIUS), {$ELSE} Create2DIntPoint(FDropdownRect.right - LARGEBUTTON_RADIUS, FDropdownRect.Bottom - LARGEBUTTON_RADIUS), {$ENDIF} LARGEBUTTON_RADIUS, cpRightBottom, InnerLightColor); TGuiTools.DrawHLine(ABuffer, FDropdownRect.Left + LARGEBUTTON_RADIUS + 1, FDropdownRect.Right - LARGEBUTTON_RADIUS - 1, FDropdownRect.Bottom - 1, InnerLightColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FDropdownRect.Left + 1, FDropDownRect.Top + 1, FDropDownRect.Bottom - LARGEBUTTON_RADIUS - 1, InnerLightColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FDropdownRect.Right - 1, FDropDownRect.Top + 1, FDropDownRect.Bottom - LARGEBUTTON_RADIUS - 1, InnerLightColor, ClipRect); if FButtonState = bsDropdownPressed then TGuiTools.DrawHLine(ABuffer, FDropdownRect.Left + 1, FDropdownRect.Right - 1, FDropdownRect.Top, FrameColor, ClipRect) else TGuiTools.DrawHLine(ABuffer, FDropdownRect.Left + 1, FDropdownRect.Right - 1, FDropdownRect.Top, InnerDarkColor, ClipRect); // Zewnêtrzna ramka TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FDropdownRect.Left, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1), {$ELSE} Create2DIntPoint(FDropdownRect.Left, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1), {$ENDIF} LARGEBUTTON_RADIUS, cpLeftBottom, FrameColor); TGuiTools.DrawAARoundCorner(ABuffer, {$IFDEF EnhancedRecordSupport} T2DIntPoint.Create(FDropdownRect.right - LARGEBUTTON_RADIUS + 1, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1), {$ELSE} Create2DIntPoint(FDropdownRect.right - LARGEBUTTON_RADIUS + 1, FDropdownRect.Bottom - LARGEBUTTON_RADIUS + 1), {$ENDIF} LARGEBUTTON_RADIUS, cpRightBottom, FrameColor); TGuiTools.DrawHLine(ABuffer, FDropdownRect.Left + LARGEBUTTON_RADIUS, FDropdownRect.Right - LARGEBUTTON_RADIUS, FDropdownRect.Bottom, FrameColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FDropdownRect.Left, FDropDownRect.Top, FDropDownRect.Bottom - LARGEBUTTON_RADIUS, FrameColor, ClipRect); TGuiTools.DrawVLine(ABuffer, FDropdownRect.Right, FDropDownRect.Top, FDropDownRect.Bottom - LARGEBUTTON_RADIUS, FrameColor, ClipRect); {$ENDREGION} {$ENDREGION} end else raise InternalException.create('TSpkLargeButton.Draw: Nieprawid³owa wartoœæ FButtonState!'); // *** Ikona *** if not(FEnabled) then begin {$REGION 'Ikona wy³¹czona'} if (FLargeImageIndex>=0) and (FDisabledLargeImages<>nil) and (FLargeImageIndex=0) and (FLargeImages<>nil) and (FLargeImageIndex=0) and (FLargeImages<>nil) and (FLargeImageIndex0 then for i := 1 to length(s) do if s[i]=' ' then begin if i>1 then BeforeWidth:=Bitmap.Canvas.TextWidth(copy(s,1,i-1)) else BeforeWidth:=0; if inil then GlyphWidth:=2 * LARGEBUTTON_GLYPH_MARGIN + FLargeImages.Width else GlyphWidth:=0; // *** Tekst *** if FButtonKind = bkButton then begin // £amiemy etykietê FindBreakPlace(FCaption,BreakPos,RowWidth); TextWidth:=2 * LARGEBUTTON_CAPTION_HMARGIN + RowWidth; end else begin // Nie ³amiemy etykiety Bitmap.canvas.font.assign(FAppearance.Element.CaptionFont); TextWidth:=2 * LARGEBUTTON_CAPTION_HMARGIN + Bitmap.Canvas.TextWidth(FCaption); end; result:=max(LARGEBUTTON_MIN_WIDTH, max(GlyphWidth, TextWidth)); end; procedure TSpkLargeButton.SetLargeImageIndex(const Value: TImageIndex); begin FLargeImageIndex:=Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; { TSpkSmallButton } procedure TSpkSmallButton.CalcRects; var RectVector : T2DIntVector; begin ConstructRects(FButtonRect, FDropdownRect); {$IFDEF EnhancedRecordSupport} RectVector:=T2DIntVector.Create(FRect.Left, FRect.Top); {$ELSE} RectVector.Create(FRect.Left, FRect.Top); {$ENDIF} FButtonRect:=FButtonRect + RectVector; FDropdownRect:=FDropdownRect + RectVector; end; procedure TSpkSmallButton.ConstructRects(var BtnRect, DropRect: T2DIntRect); var BtnWidth : integer; DropdownWidth: Integer; Bitmap : TBitmap; TextWidth: Integer; AdditionalPadding: Boolean; begin {$IFDEF EnhancedRecordSupport} BtnRect:=T2DIntRect.Create(0, 0, 0, 0); DropRect:=T2DIntRect.Create(0, 0, 0, 0); {$ELSE} BtnRect.Create(0, 0, 0, 0); DropRect.Create(0, 0, 0, 0); {$ENDIF} if not(assigned(FToolbarDispatch)) then exit; if not(assigned(FAppearance)) then exit; Bitmap:=FToolbarDispatch.GetTempBitmap; if not(assigned(Bitmap)) then exit; // *** Niezale¿nie od rodzaju, musi byæ miejsce dla ikony i/lub tekstu *** BtnWidth:=0; AdditionalPadding:=false; // Ikona if FImageIndex<>-1 then begin BtnWidth:=BtnWidth + SMALLBUTTON_PADDING + SMALLBUTTON_GLYPH_WIDTH; AdditionalPadding:=true; end; // Tekst if FShowCaption then begin Bitmap.Canvas.Font.assign(FAppearance.Element.CaptionFont); TextWidth:=Bitmap.Canvas.TextWidth(FCaption); BtnWidth:=BtnWidth + SMALLBUTTON_PADDING + TextWidth; AdditionalPadding:=true; end; // Padding za tekstem lub ikon¹ if AdditionalPadding then BtnWidth:=BtnWidth + SMALLBUTTON_PADDING; // Szerokoœæ zawartoœci przycisku musi wynosiæ co najmniej SMALLBUTTON_MIN_WIDTH BtnWidth:=max(SMALLBUTTON_MIN_WIDTH, BtnWidth); // *** Dropdown *** case FButtonKind of bkButton: begin // Lewa krawêdŸ przycisku if FGroupBehaviour in [gbContinuesGroup, gbEndsGroup] then BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH else BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH; // Prawa krawêdŸ przycisku if (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) then BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH else BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH; {$IFDEF EnhancedRecordSupport} BtnRect:=T2DIntRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect:=T2DIntRect.Create(0, 0, 0, 0); {$ELSE} BtnRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect.Create(0, 0, 0, 0); {$ENDIF} end; bkButtonDropdown: begin // Lewa krawêdŸ przycisku if FGroupBehaviour in [gbContinuesGroup, gbEndsGroup] then BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH else BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH; // Prawa krawêdŸ przycisku BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH; // Lewa krawêdŸ i zawartoœæ pola dropdown DropdownWidth:=SMALLBUTTON_HALF_BORDER_WIDTH + SMALLBUTTON_DROPDOWN_WIDTH; // Prawa krawêdŸ pola dropdown if (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) then DropdownWidth:=DropdownWidth + SMALLBUTTON_HALF_BORDER_WIDTH else DropdownWidth:=DropdownWidth + SMALLBUTTON_BORDER_WIDTH; {$IFDEF EnhancedRecordSupport} BtnRect:=T2DIntRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect:=T2DIntRect.Create(BtnRect.right+1, 0, BtnRect.right+DropdownWidth, PANE_ROW_HEIGHT - 1); {$ELSE} BtnRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect.Create(BtnRect.right+1, 0, BtnRect.right+DropdownWidth, PANE_ROW_HEIGHT - 1); {$ENDIF} end; bkDropdown: begin // Lewa krawêdŸ przycisku if FGroupBehaviour in [gbContinuesGroup, gbEndsGroup] then BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH else BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH; // Prawa krawêdŸ przycisku if (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) then BtnWidth:=BtnWidth + SMALLBUTTON_HALF_BORDER_WIDTH else BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH; // Dodatkowy obszar na dropdown + miejsce na œrodkow¹ krawêdŸ, // dla kompatybilnoœci wymiarów z dkButtonDropdown BtnWidth:=BtnWidth + SMALLBUTTON_BORDER_WIDTH + SMALLBUTTON_DROPDOWN_WIDTH; {$IFDEF EnhancedRecordSupport} BtnRect:=T2DIntRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect:=T2DIntRect.Create(0, 0, 0, 0); {$ELSE} BtnRect.Create(0, 0, BtnWidth - 1, PANE_ROW_HEIGHT - 1); DropRect.Create(0, 0, 0, 0); {$ENDIF} end; end; end; constructor TSpkSmallButton.Create(AOwner: TComponent); begin inherited Create(AOwner); FImageIndex:=-1; FTableBehaviour:=tbContinuesRow; FGroupBehaviour:=gbSingleItem; FHideFrameWhenIdle:=false; FShowCaption:=true; end; procedure TSpkSmallButton.Draw(ABuffer: TBitmap; ClipRect: T2DIntRect); var FontColor: TColor; x: Integer; y: Integer; begin if FToolbarDispatch=nil then exit; if FAppearance=nil then exit; if (FRect.width<2*LARGEBUTTON_RADIUS) or (FRect.Height<2*LARGEBUTTON_RADIUS) then exit; // *** Przycisk *** // T³o i ramka {$REGION 'Rysowanie przycisku'} if (FButtonState = bsIdle) and (not(FHideFrameWhenIdle)) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FButtonRect, IdleFrameColor, IdleInnerLightColor, IdleInnerDarkColor, IdleGradientFromColor, IdleGradientToColor, IdleGradientType, (FGroupBehaviour in [gbContinuesGroup, gbEndsGroup]), (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) or (FButtonKind = bkButtonDropdown), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState=bsBtnHottrack) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FButtonRect, HotTrackFrameColor, HotTrackInnerLightColor, HotTrackInnerDarkColor, HotTrackGradientFromColor, HotTrackGradientToColor, HotTrackGradientType, (FGroupBehaviour in [gbContinuesGroup, gbEndsGroup]), (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) or (FButtonKind = bkButtonDropdown), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState = bsBtnPressed) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FButtonRect, ActiveFrameColor, ActiveInnerLightColor, ActiveInnerDarkColor, ActiveGradientFromColor, ActiveGradientToColor, ActiveGradientType, (FGroupBehaviour in [gbContinuesGroup, gbEndsGroup]), (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) or (FButtonKind = bkButtonDropdown), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState in [bsDropdownHottrack, bsDropdownPressed]) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FButtonRect, TColorTools.Brighten(HotTrackFrameColor,40), TColorTools.Brighten(HotTrackInnerLightColor,40), TColorTools.Brighten(HotTrackInnerDarkColor,40), TColorTools.Brighten(HotTrackGradientFromColor,40), TColorTools.Brighten(HotTrackGradientToColor,40), HotTrackGradientType, (FGroupBehaviour in [gbContinuesGroup, gbEndsGroup]), (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]) or (FButtonKind = bkButtonDropdown), false, false, SMALLBUTTON_RADIUS, ClipRect); end; {$ENDREGION} // Ikona if not(FEnabled) then begin {$REGION 'Ikona wy³¹czona'} if (FImageIndex>=0) and (FDisabledImages<>nil) and (FImageIndex=0) and (FImages<>nil) and (FImageIndex=0) and (FImages<>nil) and (FImageIndex-1 then x:=x + 2 * SMALLBUTTON_PADDING + SMALLBUTTON_GLYPH_WIDTH else x:=x + SMALLBUTTON_PADDING; y:=FButtonRect.Top + (FButtonRect.Height - ABuffer.Canvas.TextHeight('Wy')) div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, FCaption, FontColor, ClipRect); end; // *** Dropdown *** if FButtonKind = bkButton then begin // Nic dodatkowego do rysowania end else if FButtonKind = bkButtonDropdown then begin // T³o i ramka {$REGION 'Rysowanie dropdowna'} if (FButtonState = bsIdle) and (not(FHideFrameWhenIdle)) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FDropdownRect, IdleFrameColor, IdleInnerLightColor, IdleInnerDarkColor, IdleGradientFromColor, IdleGradientToColor, IdleGradientType, true, (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState in [bsBtnHottrack, bsBtnPressed]) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FDropdownRect, TColorTools.Brighten(HottrackFrameColor, 40), TColorTools.Brighten(HottrackInnerLightColor, 40), TColorTools.Brighten(HottrackInnerDarkColor, 40), TColorTools.Brighten(HottrackGradientFromColor, 40), TColorTools.Brighten(HottrackGradientToColor, 40), HottrackGradientType, true, (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState = bsDropdownHottrack) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FDropdownRect, HottrackFrameColor, HottrackInnerLightColor, HottrackInnerDarkColor, HottrackGradientFromColor, HottrackGradientToColor, HottrackGradientType, true, (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]), false, false, SMALLBUTTON_RADIUS, ClipRect); end else if (FButtonState = bsDropdownPressed) then begin with FAppearance.Element do TButtonTools.DrawButton(ABuffer, FDropdownRect, ActiveFrameColor, ActiveInnerLightColor, ActiveInnerDarkColor, ActiveGradientFromColor, ActiveGradientToColor, ActiveGradientType, true, (FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup]), false, false, SMALLBUTTON_RADIUS, ClipRect); end; // Chevron if not(FEnabled) then begin FontColor:=clNone; case FButtonState of bsIdle: FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.IdleCaptionColor); bsBtnHottrack, bsDropdownHottrack : FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.HotTrackCaptionColor); bsBtnPressed, bsDropdownPressed: FontColor:=TColorTools.ColorToGrayscale(FAppearance.ELement.ActiveCaptionColor); end; end else begin FontColor:=clNone; case FButtonState of bsIdle: FontColor:=FAppearance.Element.IdleCaptionColor; bsBtnHottrack, bsDropdownHottrack : FontColor:=FAppearance.Element.HotTrackCaptionColor; bsBtnPressed, bsDropdownPressed: FontColor:=FAppearance.ELement.ActiveCaptionColor; end; end; ABuffer.Canvas.Font.Charset:=DEFAULT_CHARSET; ABuffer.Canvas.Font.Name:='Marlett'; ABuffer.Canvas.Font.Size:=8; ABuffer.Canvas.Font.Style:=[]; ABuffer.Canvas.Font.Orientation:=0; if FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup] then x:=FDropdownRect.Right - SMALLBUTTON_HALF_BORDER_WIDTH - (SMALLBUTTON_DROPDOWN_WIDTH + ABuffer.Canvas.Textwidth('u')) div 2 + 1 else x:=FDropdownRect.Right - SMALLBUTTON_BORDER_WIDTH - (SMALLBUTTON_DROPDOWN_WIDTH + ABuffer.Canvas.Textwidth('u')) div 2 + 1; y:=FDropdownRect.top + (FDropdownRect.height - ABuffer.Canvas.Textheight('u')) div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, 'u', FontColor, ClipRect); {$ENDREGION} end else if FButtonKind = bkDropdown then begin // Chevron dropdown if not(FEnabled) then begin FontColor:=clNone; case FButtonState of bsIdle: FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.IdleCaptionColor); bsBtnHottrack, bsDropdownHottrack : FontColor:=TColorTools.ColorToGrayscale(FAppearance.Element.HotTrackCaptionColor); bsBtnPressed, bsDropdownPressed: FontColor:=TColorTools.ColorToGrayscale(FAppearance.ELement.ActiveCaptionColor); end; end else begin FontColor:=clNone; case FButtonState of bsIdle: FontColor:=FAppearance.Element.IdleCaptionColor; bsBtnHottrack, bsDropdownHottrack : FontColor:=FAppearance.Element.HotTrackCaptionColor; bsBtnPressed, bsDropdownPressed: FontColor:=FAppearance.ELement.ActiveCaptionColor; end; end; ABuffer.Canvas.Font.Charset:=DEFAULT_CHARSET; ABuffer.Canvas.Font.Name:='Marlett'; ABuffer.Canvas.Font.Size:=8; ABuffer.Canvas.Font.Style:=[]; ABuffer.Canvas.Font.Orientation:=0; if FGroupBehaviour in [gbBeginsGroup, gbContinuesGroup] then x:=FButtonRect.Right - SMALLBUTTON_HALF_BORDER_WIDTH - (SMALLBUTTON_DROPDOWN_WIDTH + ABuffer.Canvas.Textwidth('u')) div 2 + 1 else x:=FButtonRect.Right - SMALLBUTTON_BORDER_WIDTH - (SMALLBUTTON_DROPDOWN_WIDTH + ABuffer.Canvas.Textwidth('u')) div 2 + 1; y:=FButtonRect.top + (FButtonRect.height - ABuffer.Canvas.Textheight('u')) div 2; TGUITools.DrawText(ABuffer.Canvas, x, y, 'u', FontColor, ClipRect); end; {$ENDREGION} end; function TSpkSmallButton.GetDropdownPoint: T2DIntPoint; begin {$IFDEF EnhancedRecordSupport} if FButtonKind in [bkButtonDropdown, bkDropdown] then result:=T2DIntPoint.Create(FButtonRect.left, FButtonRect.bottom+1) else result:=T2DIntPoint.Create(0,0); {$ELSE} if FButtonKind in [bkButtonDropdown, bkDropdown] then result.Create(FButtonRect.left, FButtonRect.bottom+1) else result.Create(0,0); {$ENDIF} end; function TSpkSmallButton.GetGroupBehaviour: TSpkItemGroupBehaviour; begin result:=FGroupBehaviour; end; function TSpkSmallButton.GetSize: TSpkItemSize; begin result:=isNormal; end; function TSpkSmallButton.GetTableBehaviour: TSpkItemTableBehaviour; begin result:=FTableBehaviour; end; function TSpkSmallButton.GetWidth: integer; var BtnRect, DropRect : T2DIntRect; begin result:=-1; if FToolbarDispatch=nil then exit; if FAppearance=nil then exit; ConstructRects(BtnRect, DropRect); if FButtonKind = bkButtonDropdown then result:=DropRect.Right+1 else result:=BtnRect.Right+1; end; procedure TSpkSmallButton.SetGroupBehaviour( const Value: TSpkItemGroupBehaviour); begin FGroupBehaviour := Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkSmallButton.SetHideFrameWhenIdle(const Value: boolean); begin FHideFrameWhenIdle := Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyVisualsChanged; end; procedure TSpkSmallButton.SetImageIndex(const Value: TImageIndex); begin FImageIndex:=Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkSmallButton.SetShowCaption(const Value: boolean); begin FShowCaption := Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; procedure TSpkSmallButton.SetTableBehaviour( const Value: TSpkItemTableBehaviour); begin FTableBehaviour := Value; if assigned(FToolbarDispatch) then FToolbarDispatch.NotifyMetricsChanged; end; end.