spkToolbar: Add "More options button" to panes. Patch by husker, slightly modified, https://forum.lazarus.freepascal.org/index.php/topic,51552.msg378809.html#msg378809

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7698 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2020-09-26 22:12:42 +00:00
parent e353889d67
commit afaa49277f
3 changed files with 220 additions and 8 deletions

View File

@ -1907,6 +1907,7 @@ begin
PaneBorderHalfSize := round(PANE_BORDER_HALF_SIZE * AXProportion);
PaneHeight := MaxElementHeight + PaneCaptionHeight + 2 * PaneBorderSize;
PaneCaptionHMargin := round(PANE_CAPTION_HMARGIN * AXProportion);
PaneMoreOptionsButtonWidth := round(PANE_MOREOPTIONSBUTTON_WIDTH * AXProportion);
TabCornerRadius := TAB_CORNER_RADIUS;
TabPaneLeftPadding := round(TAB_PANE_LEFTPADDING * AXProportion);

View File

@ -93,7 +93,6 @@ const
/// <summary>Space between groups on a row in pane</summary>
PANE_GROUP_SPACER = 4;
// *******************
// *** Pane layout ***
// *******************
@ -110,7 +109,8 @@ const
PANE_BORDER_HALF_SIZE = 1;
/// <summary>Pane caption horizontal padding</summary>
PANE_CAPTION_HMARGIN = 6;
// Pane 'More options' button width
PANE_MOREOPTIONSBUTTON_WIDTH = 15;
// ************
// *** Tabs ***
@ -239,7 +239,8 @@ var
PaneHeight: Integer;
/// <summary>Pane caption horizontal padding</summary>
PaneCaptionHMargin: Integer;
// Pane 'More options' button width
PaneMoreOptionsButtonWidth : Integer;
// ************
// *** Tabs ***
@ -344,6 +345,7 @@ begin
PaneBorderHalfSize := SpkScaleX(PANE_BORDER_HALF_SIZE, FromDPI, ToDPI);
PaneHeight := MaxElementHeight + PaneCaptionHeight + 2 * PaneBorderSize;
PaneCaptionHMargin := SpkScaleX(PANE_CAPTION_HMARGIN, FromDPI, ToDPI);
PaneMoreOptionsButtonWidth := SpkScaleX(PANE_MOREOPTIONSBUTTON_WIDTH, FromDPI, ToDPI);
TabCornerRadius := TAB_CORNER_RADIUS;
TabPaneLeftPadding := SpkScaleX(TAB_PANE_LEFTPADDING, FromDPI, ToDPI);

View File

@ -19,7 +19,9 @@ uses
Graphics, Controls, Classes, SysUtils, Math, Dialogs,
SpkGraphTools, SpkGUITools, SpkMath,
spkt_Appearance, spkt_Const, spkt_Dispatch, spkt_Exceptions,
spkt_BaseItem, spkt_Items, spkt_Types;
spkt_BaseItem, spkt_Items, spkt_Types,
// Husker
spkt_Tools; // !!!!
type
TSpkPaneState = (psIdle, psHover);
@ -38,6 +40,10 @@ type
Width: integer;
end;
// 'More options' button states
TSpkMoreOptionsButtonState = (mobsIdle, mobsBtnHottrack, mobsBtnPressed);
TSpkMoreOptionsButtonStyle = (mobsPlus, mobsArrow);
TSpkPane = class;
TSpkPane = class(TSpkComponent)
@ -45,6 +51,11 @@ type
FPaneState: TSpkPaneState;
FMouseHoverElement: TSpkMousePaneElement;
FMouseActiveElement: TSpkMousePaneElement;
// 'More options' button
FMoreOptionsButtonState: TSpkMoreOptionsButtonState;
FMoreOptionsButtonStyle: TSpkMoreOptionsButtonStyle;
FInMoreOptionsButton: boolean;
FOnMoreOptionsButtonClick: TNotifyEvent;
protected
FCaption: string;
FRect: T2DIntRect;
@ -58,6 +69,8 @@ type
FLargeImagesWidth: Integer;
FVisible: boolean;
FItems: TSpkItems;
FMoreOptionsButtonRect: T2DIntRect;
FShowMoreOptionsButton: boolean;
// *** Generating a layout of elements ***
function GenerateLayout: TSpkPaneItemsLayout;
@ -79,6 +92,8 @@ type
procedure SetLargeImagesWidth(const Value: Integer);
procedure SetRect(ARect : T2DIntRect);
procedure SetToolbarDispatch(const Value: TSpkBaseToolbarDispatch);
procedure SetShowMoreOptionsButton(const Value: boolean);
procedure SetMoreOptionsButtonStyle(const Value: TSpkMoreOptionsButtonStyle);
public
// *** Constructor, destructor ***
@ -95,10 +110,14 @@ type
function GetWidth: integer;
procedure Draw(ABuffer: TBitmap; ClipRect: T2DIntRect);
function FindItemAt(x, y: integer): integer;
procedure DrawMoreOptionsButton(ABuffer: TBitmap; ClipRect: T2DIntRect);
// *** Support for elements ***
procedure FreeingItem(AItem: TSpkBaseItem);
// *** 'More options' button ***
procedure DoMoreOptionsButtonClick;
property ToolbarDispatch: TSpkBaseToolbarDispatch read FToolbarDispatch write SetToolbarDispatch;
property Appearance: TSpkToolbarAppearance read FAppearance write SetAppearance;
property Rect: T2DIntRect read FRect write SetRect;
@ -111,8 +130,16 @@ type
property Items: TSpkItems read FItems;
published
property Caption: string read FCaption write SetCaption;
property Visible: boolean read FVisible write SetVisible default true;
property Caption: string
read FCaption write SetCaption;
property Visible: boolean
read FVisible write SetVisible default true;
property ShowMoreOptionsButtonStyle: TSpkMoreOptionsButtonStyle
read FMoreOptionsButtonStyle write SetMoreOptionsButtonStyle default mobsPlus;
property ShowMoreOptionsButton: boolean
read FShowMoreOptionsButton write SetShowMoreOptionsButton default false;
property OnMoreOptionsButtonClick: TNotifyEvent
read FOnMoreOptionsButtonClick write FOnMoreOptionsButtonClick;
end;
TSpkPanes = class(TSpkCollection)
@ -161,6 +188,10 @@ type
implementation
// Husker : temp, à déplacer dans les constantes //!!!!!!!!!
//const
// PaneMoreOptionButtonWidth : integer = 15;
{ TSpkPane }
constructor TSpkPane.Create(AOwner: TComponent);
@ -173,6 +204,9 @@ begin
FMouseActiveElement.ElementType := peNone;
FMouseActiveElement.ElementIndex := -1;
FMoreOptionsButtonState := mobsIdle;
FInMoreOptionsButton := False;
FCaption := 'Pane';
{$IFDEF EnhancedRecordSupport}
FRect := T2DIntRect.Create(0,0,0,0);
@ -209,6 +243,18 @@ var
begin
FRect := ARect;
// Set 'More options' button rect
{$IFDEF EnhancedRecordSupport}
FMoreOptionsButtonRect := T2DIntRect.Create(
{$ELSE}
FMoreOptionsButtonRect := Create2DIntRect(
{$ENDIF}
FRect.Right - PaneBorderHalfSize - PaneMoreOptionsButtonWidth,
FRect.Bottom - PaneCaptionHeight - PaneBorderHalfSize,
FRect.Right - PaneBorderHalfSize - 2,
FRect.Bottom - PaneBorderHalfSize - 2
);
// Obliczamy layout
Layout := GenerateLayout;
@ -327,9 +373,17 @@ begin
true
);
// Draw the 'More option' button
DrawMoreOptionsButton(ABuffer, ClipRect);
// Pane label
ABuffer.Canvas.Font.Assign(FAppearance.Pane.CaptionFont);
x := FRect.Left + (FRect.Width - ABuffer.Canvas.TextWidth(FCaption)) div 2;
// Handle visibility of 'More options' button to set Pane label pos
if FShowMoreOptionsButton then
x := FRect.Left + (FRect.Width - PaneMoreOptionsButtonWidth - ABuffer.Canvas.TextWidth(FCaption)) div 2
else
x := FRect.Left + (FRect.Width - ABuffer.Canvas.TextWidth(FCaption)) div 2;
y := FRect.Bottom - PaneBorderSize - PaneCaptionHeight + 1 +
(PaneCaptionHeight - ABuffer.Canvas.TextHeight('Wy')) div 2;
@ -452,6 +506,93 @@ begin
FItems[i].Draw(ABuffer, ClipRect);
end;
{ Drawing procedure for the 'More options' button }
procedure TSpkPane.DrawMoreOptionsButton(ABuffer: TBitmap; ClipRect: T2DIntRect);
const
MOB_SIGNS: array[TSpkMoreOptionsButtonStyle] of string = ('+', #$E2#$87#$B2);
// 'plus', or diagonal arrow with corner like in Excel
var
mobFontColor, mobFrameColor: TColor;
mobGradientFromColor, mobGradientToColor: TColor;
mobInnerLightColor, mobInnerDarkColor: TColor;
mobGradientKind: TBackgroundKind;
mobSign: String; // Holds the icon of the 'More options' button
mobX: Integer; // X and Y position of the '+' sign of the 'More options' button
mobY: Integer;
begin
// Under some conditions, we are not able to draw
// * No dispatcher
if FToolbarDispatch = nil then
exit;
// * No appearance
if FAppearance = nil then
exit;
// Draw the 'More options' button in the right corner of the Pane label background
if FShowMoreOptionsButton then
begin
//FmobButtonState:=mobbsIdle;
//FmobButtonState:=mobbsBtnHottrack;
//FmobButtonState:=mobbsBtnPressed;
// Get colors for drawing
if (FMoreOptionsButtonState = mobsIdle) then
begin
FAppearance.Element.GetIdleColors(False,
mobFontColor, mobFrameColor, mobInnerLightColor, mobInnerDarkColor,
mobGradientFromColor, mobGradientToColor, mobGradientKind
);
end else
if FMoreOptionsButtonState = mobsBtnHottrack then
begin
FAppearance.Element.GetHotTrackColors(False,
mobFontColor, mobFrameColor, mobInnerLightColor, mobInnerDarkColor,
mobGradientFromColor, mobGradientToColor, mobGradientKind
);
end else
if FMoreOptionsButtonState = mobsBtnPressed then
begin
FAppearance.Element.GetActiveColors(False,
mobFontColor, mobFrameColor, mobInnerLightColor, mobInnerDarkColor,
mobGradientFromColor, mobGradientToColor, mobGradientKind
);
end;
// Draw the 'more options' button border
TButtonTools.DrawButton(
ABuffer,
FMoreOptionsButtonRect,
mobFrameColor,
mobInnerLightColor,
mobInnerDarkColor,
mobGradientFromColor,
mobGradientToColor,
mobGradientKind,
false,
false,
false,
false,
1,
ClipRect
);
// Draw the '+' sign in the button
mobSign := MOB_SIGNS[FMoreOptionsButtonStyle];
ABuffer.Canvas.Font.Assign(FAppearance.Pane.CaptionFont);
mobX := FMoreOptionsButtonRect.Left + (FMoreOptionsButtonRect.Width - ABuffer.Canvas.TextWidth(mobSign)) div 2;
mobY := FMoreOptionsButtonRect.Bottom - PaneBorderSize - PaneCaptionHeight + 2 +
(PaneCaptionHeight - ABuffer.Canvas.TextHeight('Wy')) div 2;
TGUITools.DrawText(
ABuffer.Canvas,
mobX,
mobY,
mobSign,
mobFontColor,
ClipRect
);
end;
end;
function TSpkPane.FindItemAt(x, y: integer): integer;
var
i: integer;
@ -478,6 +619,13 @@ begin
FItems.RemoveReference(AItem);
end;
// Support for 'More options' button click
procedure TSpkPane.DoMoreOptionsButtonClick;
begin
if Assigned(FOnMoreOptionsButtonClick) then
FOnMoreOptionsButtonClick(self);
end;
function TSpkPane.GenerateLayout: TSpkPaneItemsLayout;
type
TLayoutRow = array of integer;
@ -717,7 +865,12 @@ begin
// *** The minimum width of the sheet (text) ***
TextW := tmpBitmap.Canvas.TextWidth(FCaption);
PaneCaptionWidth := 2*PaneBorderSize + 2*PaneCaptionHMargin + TextW;
// Widen width to include 'More options' button if necessary
if FShowMoreOptionsButton then
PaneCaptionWidth := 2*PaneBorderSize + 2*PaneCaptionHMargin + TextW + PaneMoreOptionsButtonWidth
else
PaneCaptionWidth := 2*PaneBorderSize + 2*PaneCaptionHMargin + TextW;
// *** The width of the elements of the sheet ***
Layout := GenerateLayout;
@ -738,6 +891,22 @@ end;
procedure TSpkPane.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
// Handle mouse down on 'More options' button
if FInMoreOptionsButton then
begin
FMoreOptionsButtonState := mobsBtnPressed;
// Draw the 'More options' button
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyVisualsChanged;
// Fire OnMoreOptionsButtonClick event
DoMoreOptionsButtonClick;
// Set the button drawing to idle
FMoreOptionsButtonState := mobsIdle;
// Draw the 'More options' button
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyVisualsChanged;
end;
if FMouseActiveElement.ElementType = peItem then
begin
if FMouseActiveElement.ElementIndex <> -1 then
@ -816,6 +985,21 @@ begin
FToolbarDispatch.NotifyVisualsChanged;
end;
// Test if mouse on 'More options' button
if FMoreOptionsButtonRect.Contains(X, Y) then
begin
FInMoreOptionsButton := True;
FMoreOptionsButtonState := mobsBtnHottrack;
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyVisualsChanged;
end else
begin
FInMoreOptionsButton := False;
FMoreOptionsButtonState := mobsIdle;
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyVisualsChanged;
end;
// We're looking for an object under the mouse
i := FindItemAt(X, Y);
if i <> -1 then
@ -882,6 +1066,15 @@ var
begin
ClearActive := not (ssLeft in Shift) and not (ssMiddle in Shift) and not (ssRight in Shift);
// Handle mouse up on 'More options' button
if FInMoreOptionsButton then
begin
FMoreOptionsButtonState := mobsBtnHottrack;
// Draw the 'More options' button
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyVisualsChanged;
end;
if FMouseActiveElement.ElementType = peItem then
begin
if FMouseActiveElement.ElementIndex <> -1 then
@ -989,6 +1182,22 @@ begin
FToolbarDispatch.NotifyItemsChanged;
end;
procedure TSpkPane.SetShowMoreOptionsButton(const Value: boolean);
begin
if FShowMoreOptionsButton = Value then exit;
FShowMoreOptionsButton := Value;
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyItemsChanged;
end;
procedure TSpkPane.SetMoreOptionsButtonStyle(const Value: TSpkMoreOptionsButtonStyle);
begin
if FMoreOptionsButtonStyle = Value then exit;
FMoreOptionsButtonStyle := Value;
if Assigned(FToolbarDispatch) then
FToolbarDispatch.NotifyItemsChanged;
end;
{ TSpkPanes }