From 7ca9314af1bd0369aaa52ade3ea1be917a499d56 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Mon, 22 May 2006 05:13:12 +0000 Subject: [PATCH] Added: Action support Added: TX2Color32 type Fixed: re-selecting the items when designer is activated --- Packages/X2CLMenuBarEditor.dfm | 7 +- Packages/X2CLMenuBarEditor.pas | 17 ++ Source/X2CLGraphics.pas | 93 ++++++++ Source/X2CLMenuBar.pas | 303 ++++++++++++++++++++++-- Source/X2CLMenuBarAnimators.pas | 6 +- Source/X2CLmusikCubeMenuBarPainter.pas | 208 +++++------------ Source/X2CLunaMenuBarPainter.pas | 3 + Test/MenuBar/MainForm.dfm | 310 ++++++++++++------------- Test/MenuBar/MainForm.pas | 14 +- Test/MenuBar/MenuBarTest.dpr | 3 +- 10 files changed, 628 insertions(+), 336 deletions(-) create mode 100644 Source/X2CLGraphics.pas diff --git a/Packages/X2CLMenuBarEditor.dfm b/Packages/X2CLMenuBarEditor.dfm index af3b639..cef4d80 100644 --- a/Packages/X2CLMenuBarEditor.dfm +++ b/Packages/X2CLMenuBarEditor.dfm @@ -14,6 +14,7 @@ object frmMenuBarEditor: TfrmMenuBarEditor FormStyle = fsStayOnTop OldCreateOrder = False Position = poOwnerFormCenter + OnActivate = FormActivate OnClose = FormClose OnCreate = FormCreate OnDestroy = FormDestroy @@ -30,9 +31,6 @@ object frmMenuBarEditor: TfrmMenuBarEditor ReadOnly = True TabOrder = 0 OnChange = tvMenuChange - ExplicitTop = 20 - ExplicitWidth = 252 - ExplicitHeight = 281 end object sbStatus: TStatusBar Left = 0 @@ -43,8 +41,6 @@ object frmMenuBarEditor: TfrmMenuBarEditor item Width = 50 end> - ExplicitTop = 307 - ExplicitWidth = 252 end object tbMenu: TToolBar Left = 0 @@ -58,7 +54,6 @@ object frmMenuBarEditor: TfrmMenuBarEditor List = True ShowCaptions = True TabOrder = 2 - ExplicitWidth = 252 object tbAddGroup: TToolButton Left = 0 Top = 0 diff --git a/Packages/X2CLMenuBarEditor.pas b/Packages/X2CLMenuBarEditor.pas index 1b0266b..d63a7ea 100644 --- a/Packages/X2CLMenuBarEditor.pas +++ b/Packages/X2CLMenuBarEditor.pas @@ -35,6 +35,7 @@ type procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormDestroy(Sender: TObject); procedure tvMenuChange(Sender: TObject; Node: TTreeNode); + procedure FormActivate(Sender: TObject); private FDesigner: IDesigner; FMenuBar: TX2CustomMenuBar; @@ -114,6 +115,22 @@ begin {$ENDIF} end; +procedure TfrmMenuBarEditor.FormActivate(Sender: TObject); +var + item: TX2CustomMenuBarItem; + +begin + if Assigned(tvMenu.Selected) then + begin + item := TX2CustomMenuBarItem(tvMenu.Selected.Data); + + if Assigned(Designer) then + Designer.SelectComponent(item); + end; + + UpdateUI(); +end; + procedure TfrmMenuBarEditor.FormClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(Designer) and Assigned(MenuBar) then diff --git a/Source/X2CLGraphics.pas b/Source/X2CLGraphics.pas new file mode 100644 index 0000000..b79b9f7 --- /dev/null +++ b/Source/X2CLGraphics.pas @@ -0,0 +1,93 @@ +{ + :: Implements various graphics-related classes and functions. + :: + :: Part of the X2Software Component Library + :: http://www.x2software.net/ + :: + :: Last changed: $Date$ + :: Revision: $Rev$ + :: Author: $Author$ +} +unit X2CLGraphics; + +interface +uses + Graphics; + +type + TX2Color32 = type TColor; + + function Color32(AColor: TColor; AAlpha: Byte = 255): TX2Color32; + function DelphiColor(AColor: TX2Color32): TColor; + + function RedValue(AColor: TX2Color32): Byte; + function GreenValue(AColor: TX2Color32): Byte; + function BlueValue(AColor: TX2Color32): Byte; + function AlphaValue(AColor: TX2Color32): Byte; + + function Blend(ABackground: TColor; AForeground: TX2Color32): TColor; + +implementation +uses + Windows; + +function Color32(AColor: TColor; AAlpha: Byte): TX2Color32; +begin + Result := (ColorToRGB(AColor) and $00FFFFFF) or (AAlpha shl 24); +end; + +function DelphiColor(AColor: TX2Color32): TColor; +begin + Result := (AColor and $00FFFFFF); +end; + + +function RedValue(AColor: TX2Color32): Byte; +begin + Result := (AColor and $000000FF); +end; + +function GreenValue(AColor: TX2Color32): Byte; +begin + Result := (AColor and $0000FF00) shr 8; +end; + +function BlueValue(AColor: TX2Color32): Byte; +begin + Result := (AColor and $00FF0000) shr 16; +end; + +function AlphaValue(AColor: TX2Color32): Byte; +begin + Result := (AColor and $FF000000) shr 24; +end; + + +function Blend(ABackground: TColor; AForeground: TX2Color32): TColor; +var + backColor: TX2Color32; + backAlpha: Integer; + foreAlpha: Integer; + +begin + foreAlpha := AlphaValue(AForeground); + + if foreAlpha = 0 then + Result := ABackground + else if foreAlpha = 255 then + Result := DelphiColor(AForeground) + else + begin + backColor := Color32(ABackground); + backAlpha := 256 - foreAlpha; + + Result := RGB(((RedValue(backColor) * backAlpha) + + (RedValue(AForeground) * foreAlpha)) shr 8, + ((GreenValue(backColor) * backAlpha) + + (GreenValue(AForeground) * foreAlpha)) shr 8, + ((BlueValue(backColor) * backAlpha) + + (BlueValue(AForeground) * foreAlpha)) shr 8); + end; +end; + +end. diff --git a/Source/X2CLMenuBar.pas b/Source/X2CLMenuBar.pas index 8a27f82..b944a88 100644 --- a/Source/X2CLMenuBar.pas +++ b/Source/X2CLMenuBar.pas @@ -2,6 +2,9 @@ :: X2CLMenuBar is a generic group/items menu. Through the various painters, :: it can resemble styles such as the musikCube or BBox/Uname-IT menu bars. :: + :: Part of the X2Software Component Library + :: http://www.x2software.net/ + :: :: Last changed: $Date$ :: Revision: $Rev$ :: Author: $Author$ @@ -10,6 +13,7 @@ unit X2CLMenuBar; interface uses + ActnList, Classes, Contnrs, Controls, @@ -31,7 +35,7 @@ const type // #ToDo1 (MvR) 25-3-2006: various Select methods for key support // #ToDo1 (MvR) 1-4-2006: scroll wheel support - // #ToDo1 (MvR) 2-4-2006: OnGetAnimationClass event? + // #ToDo1 (MvR) 29-4-2006: action support TX2CustomMenuBarAnimatorClass = class of TX2CustomMenuBarAnimator; TX2CustomMenuBarAnimator = class; TX2CustomMenuBarPainterClass = class of TX2CustomMenuBarPainter; @@ -62,6 +66,7 @@ type TX2MenuBarSelectAction = (saBefore, saAfter, saBoth); + TX2ComponentNotificationEvent = procedure(Sender: TObject; AComponent: TComponent; Operation: TOperation) of object; TX2MenuBarExpandingEvent = procedure(Sender: TObject; Group: TX2MenuBarGroup; var Allowed: Boolean) of object; TX2MenuBarExpandedEvent = procedure(Sender: TObject; Group: TX2MenuBarGroup) of object; TX2MenuBarSelectedChangingEvent = procedure(Sender: TObject; Item, NewItem: TX2CustomMenUBarItem; var Allowed: Boolean) of object; @@ -158,19 +163,63 @@ type procedure DetachObserver(AObserver: IX2MenuBarPainterObserver); end; + { + :$ Action link for menu items and groups. + } + TX2MenuBarActionLink = class(TActionLink) + private + FClient: TX2CustomMenuBarItem; + protected + procedure AssignClient(AClient: TObject); override; + + function IsCaptionLinked(): Boolean; override; + function IsEnabledLinked(): Boolean; override; + function IsImageIndexLinked(): Boolean; override; + function IsVisibleLinked(): Boolean; override; + procedure SetCaption(const Value: string); override; + procedure SetEnabled(Value: Boolean); override; + procedure SetImageIndex(Value: Integer); override; + procedure SetVisible(Value: Boolean); override; + + property Client: TX2CustomMenuBarItem read FClient; + end; + + { + :$ Provides component notifications for collection items. + } + TX2ComponentNotification = class(TComponent) + private + FOnNotification: TX2ComponentNotificationEvent; + published + protected + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + published + property OnNotification: TX2ComponentNotificationEvent read FOnNotification write FOnNotification; + end; + { :$ Base class for menu items and groups. } TX2CustomMenuBarItem = class(TCollectionItem) private + FAction: TBasicAction; + FActionLink: TX2MenuBarActionLink; FCaption: String; FData: TObject; FEnabled: Boolean; FImageIndex: TImageIndex; FOwnsData: Boolean; FVisible: Boolean; + + FNotification: TX2ComponentNotification; + private + procedure DoActionChange(Sender: TObject); protected + procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); virtual; + + function IsCaptionStored(): Boolean; virtual; function GetMenuBar(): TX2CustomMenuBar; virtual; + procedure SetAction(const Value: TBasicAction); procedure SetCaption(const Value: String); virtual; procedure SetData(const Value: TObject); virtual; procedure SetEnabled(const Value: Boolean); virtual; @@ -182,14 +231,16 @@ type procedure Assign(Source: TPersistent); override; - property Data: TObject read FData write SetData; - property OwnsData: Boolean read FOwnsData write FOwnsData; - property MenuBar: TX2CustomMenuBar read GetMenuBar; + property ActionLink: TX2MenuBarActionLink read FActionLink; + property Data: TObject read FData write SetData; + property OwnsData: Boolean read FOwnsData write FOwnsData; + property MenuBar: TX2CustomMenuBar read GetMenuBar; published - property Caption: String read FCaption write SetCaption; - property Enabled: Boolean read FEnabled write SetEnabled default True; - property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1; - property Visible: Boolean read FVisible write SetVisible default True; + property Action: TBasicAction read FAction write SetAction; + property Caption: String read FCaption write SetCaption stored IsCaptionStored; + property Enabled: Boolean read FEnabled write SetEnabled default True; + property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1; + property Visible: Boolean read FVisible write SetVisible default True; end; { @@ -213,6 +264,8 @@ type TX2MenuBarItem = class(TX2CustomMenuBarItem) private function GetGroup(): TX2MenuBarGroup; + protected + function IsCaptionStored(): Boolean; override; public constructor Create(Collection: TCollection); override; @@ -247,6 +300,8 @@ type procedure SetExpanded(const Value: Boolean); procedure SetItems(const Value: TX2MenuBarItems); protected + protected + function IsCaptionStored(): Boolean; override; procedure SetEnabled(const Value: Boolean); override; procedure InternalSetExpanded(const Value: Boolean); @@ -394,6 +449,15 @@ type function HitTest(const APoint: TPoint): TX2MenuBarHitTest; overload; function HitTest(AX, AY: Integer): TX2MenuBarHitTest; overload; + function SelectFirst(): TX2CustomMenuBarItem; + function SelectLast(): TX2CustomMenuBarItem; + function SelectNext(): TX2CustomMenuBarItem; + function SelectPrior(): TX2CustomMenuBarItem; + + function SelectGroup(AIndex: Integer): TX2MenuBarGroup; + function SelectItem(AIndex: Integer; AGroup: TX2MenuBarGroup = nil): TX2CustomMenuBarItem; overload; + function SelectItem(AIndex: Integer; AGroup: Integer = -1): TX2CustomMenuBarItem; overload; + property Groups: TX2MenuBarGroups read FGroups write SetGroups; property Images: TCustomImageList read FImages write SetImages; property Painter: TX2CustomMenuBarPainter read FPainter write SetPainter; @@ -768,6 +832,72 @@ begin end; +{ TX2MenuBarActionLink } +procedure TX2MenuBarActionLink.AssignClient(AClient: TObject); +begin + FClient := (AClient as TX2CustomMenuBarItem); +end; + +function TX2MenuBarActionLink.IsCaptionLinked(): Boolean; +begin + Result := inherited IsCaptionLinked() and + (Client.Caption = (Action as TCustomAction).Caption); +end; + +function TX2MenuBarActionLink.IsEnabledLinked(): Boolean; +begin + Result := inherited IsCaptionLinked() and + (Client.Enabled = (Action as TCustomAction).Enabled); +end; + +function TX2MenuBarActionLink.IsImageIndexLinked(): Boolean; +begin + Result := inherited IsCaptionLinked() and + (Client.ImageIndex = (Action as TCustomAction).ImageIndex); +end; + +function TX2MenuBarActionLink.IsVisibleLinked(): Boolean; +begin + Result := inherited IsCaptionLinked() and + (Client.Visible = (Action as TCustomAction).Visible); +end; + +procedure TX2MenuBarActionLink.SetCaption(const Value: string); +begin + if IsCaptionLinked() then + Client.Caption := Value; +end; + +procedure TX2MenuBarActionLink.SetEnabled(Value: Boolean); +begin + if IsEnabledLinked() then + Client.Enabled := Value; +end; + +procedure TX2MenuBarActionLink.SetImageIndex(Value: Integer); +begin + if IsImageIndexLinked() then + Client.ImageIndex := Value; +end; + +procedure TX2MenuBarActionLink.SetVisible(Value: Boolean); +begin + if IsVisibleLinked() then + Client.Visible := Value; +end; + + +{ TX2ComponentNotification } +procedure TX2ComponentNotification.Notification(AComponent: TComponent; + Operation: TOperation); +begin + if Assigned(FOnNotification) then + FOnNotification(Self, AComponent, Operation); + + inherited; +end; + + { TX2CustomMenuBarItem } constructor TX2CustomMenuBarItem.Create(Collection: TCollection); begin @@ -782,16 +912,64 @@ end; destructor TX2CustomMenuBarItem.Destroy(); begin Data := nil; + FreeAndNil(FActionLink); + FreeAndNil(FNotification); inherited; end; +procedure TX2CustomMenuBarItem.Assign(Source: TPersistent); +begin + if Source is TX2CustomMenuBarItem then + with TX2CustomMenuBarItem(Source) do + begin + Self.Caption := Caption; + Self.Data := Data; + Self.OwnsData := OwnsData; + end + else + inherited; +end; + + +procedure TX2CustomMenuBarItem.DoActionChange(Sender: TObject); +begin + if Sender = Action then + ActionChange(Sender, False); +end; + +procedure TX2CustomMenuBarItem.ActionChange(Sender: TObject; + CheckDefaults: Boolean); +begin + if Sender is TCustomAction then + with TCustomAction(Sender) do + begin + if (not CheckDefaults) or (not Self.IsCaptionStored()) then + Self.Caption := Caption; + + if (not CheckDefaults) or Self.Enabled then + Self.Enabled := Enabled; + + if (not CheckDefaults) or (Self.ImageIndex = -1) then + Self.ImageIndex := ImageIndex; + + if (not CheckDefaults) or Self.Visible then + Self.Visible := Visible; + end; +end; + + +function TX2CustomMenuBarItem.IsCaptionStored(): Boolean; +begin + Result := (Length(Caption) > 0); +end; + function TX2CustomMenuBarItem.GetMenuBar(): TX2CustomMenuBar; var parentCollection: TCollection; parentOwner: TPersistent; - + begin Result := nil; parentCollection := Collection; @@ -814,19 +992,37 @@ begin end; end; -procedure TX2CustomMenuBarItem.Assign(Source: TPersistent); +procedure TX2CustomMenuBarItem.SetAction(const Value: TBasicAction); begin - if Source is TX2CustomMenuBarItem then - with TX2CustomMenuBarItem(Source) do - begin - Self.Caption := Caption; - Self.Data := Data; - Self.OwnsData := OwnsData; - end - else - inherited; -end; + if Value <> FAction then + begin + if Assigned(FAction) then + FAction.RemoveFreeNotification(FNotification); + FAction := Value; + + if Assigned(FAction) then + begin + if not Assigned(FActionLink) then + begin + FActionLink := TX2MenuBarActionLink.Create(Self); + FActionLink.OnChange := DoActionChange; + end; + + FActionLink.Action := Value; + + if not Assigned(FNotification) then + FNotification := TX2ComponentNotification.Create(nil); + + ActionChange(Value, csLoading in Value.ComponentState); + FAction.FreeNotification(FNotification); + end else + begin + FreeAndNil(FActionLink); + FreeAndNil(FNotification); + end; + end; +end; procedure TX2CustomMenuBarItem.SetCaption(const Value: String); begin @@ -902,6 +1098,13 @@ begin inherited; end; + +function TX2MenuBarItem.IsCaptionStored(): Boolean; +begin + Result := (Caption <> SDefaultItemCaption); +end; + + function TX2MenuBarItem.GetGroup(): TX2MenuBarGroup; begin Result := nil; @@ -1019,6 +1222,11 @@ begin groupCollection.Update(Item); end; +function TX2MenuBarGroup.IsCaptionStored(): Boolean; +begin + Result := (Caption <> SDefaultGroupCaption); +end; + procedure TX2MenuBarGroup.SetEnabled(const Value: Boolean); begin inherited; @@ -1666,6 +1874,58 @@ begin end; +function TX2CustomMenuBar.SelectFirst(): TX2CustomMenuBarItem; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + +function TX2CustomMenuBar.SelectLast(): TX2CustomMenuBarItem; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + +function TX2CustomMenuBar.SelectNext(): TX2CustomMenuBarItem; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + +function TX2CustomMenuBar.SelectPrior(): TX2CustomMenuBarItem; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + + +function TX2CustomMenuBar.SelectGroup(AIndex: Integer): TX2MenuBarGroup; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + +function TX2CustomMenuBar.SelectItem(AIndex: Integer; + AGroup: TX2MenuBarGroup): TX2CustomMenuBarItem; +begin + // #ToDo1 (MvR) 29-4-2006: implement this + Result := nil; +end; + +function TX2CustomMenuBar.SelectItem(AIndex, AGroup: Integer): TX2CustomMenuBarItem; +var + group: TX2MenuBarGroup; + +begin + group := nil; + if (AGroup > 0) and (AGroup < Groups.Count) then + group := Groups[AGroup]; + + Result := SelectItem(AIndex, group); +end; + + + procedure TX2CustomMenuBar.Notification(AComponent: TComponent; Operation: TOperation); begin if Operation = opRemove then @@ -2107,6 +2367,9 @@ begin end; end; + if Assigned(FSelectedItem) and Assigned(FSelectedItem.Action) then + FSelectedItem.ActionLink.Execute(Self); + DoSelectedChanged(); Invalidate(); end; diff --git a/Source/X2CLMenuBarAnimators.pas b/Source/X2CLMenuBarAnimators.pas index 014d30b..43dac53 100644 --- a/Source/X2CLMenuBarAnimators.pas +++ b/Source/X2CLMenuBarAnimators.pas @@ -1,7 +1,9 @@ { - :: Implements the animators for the MenuBar. + :: Implements the animators for the MenuBar. Though they are tightly + :: interlinked (for now), this keeps the main unit clean. :: - :: Though they are tightly interlinked (for now), this keeps the units clean. + :: Part of the X2Software Component Library + :: http://www.x2software.net/ :: :: Last changed: $Date$ :: Revision: $Rev$ diff --git a/Source/X2CLmusikCubeMenuBarPainter.pas b/Source/X2CLmusikCubeMenuBarPainter.pas index 5892bf5..054851a 100644 --- a/Source/X2CLmusikCubeMenuBarPainter.pas +++ b/Source/X2CLmusikCubeMenuBarPainter.pas @@ -1,6 +1,9 @@ { :: Implements a musikCube-style painter for the X2MenuBar. :: + :: Part of the X2Software Component Library + :: http://www.x2software.net/ + :: :: Last changed: $Date$ :: Revision: $Rev$ :: Author: $Author$ @@ -14,41 +17,35 @@ uses ImgList, Windows, + X2CLGraphics, X2CLMenuBar; type - // #ToDo1 (MvR) 19-3-2006: IsStored implementations - // #ToDo1 (MvR) 19-3-2006: cache positions TX2MenuBarmCColor = class(TPersistent) private - FBorderAlpha: Byte; - FBorderColor: TColor; - FFillAlpha: Byte; - FFillColor: TColor; - FOnChange: TNotifyEvent; + FBorder: TX2Color32; + FFill: TX2Color32; + FDefaultBorder: TX2Color32; + FDefaultFill: TX2Color32; + FOnChange: TNotifyEvent; - procedure SetBorderAlpha(const Value: Byte); - procedure SetBorderColor(const Value: TColor); - procedure SetFillAlpha(const Value: Byte); - procedure SetFillColor(const Value: TColor); + procedure SetBorder(const Value: TX2Color32); + procedure SetFill(const Value: TX2Color32); + function IsBorderStored(): Boolean; + function IsFillStored(): Boolean; protected procedure DoChange(); - function MixColors(ABackColor, AForeColor: TColor; AAlpha: Byte): TColor; + procedure SetDefaultColors(ABorder, AFill: TX2Color32); - property OnChange: TNotifyEvent read FOnChange write FOnChange; + property DefaultBorder: TX2Color32 read FDefaultBorder write FDefaultBorder; + property DefaultFill: TX2Color32 read FDefaultFill write FDefaultFill; + property OnChange: TNotifyEvent read FOnChange write FOnChange; public - constructor Create(); - procedure Assign(Source: TPersistent); override; - - function MixBorder(AColor: TColor): TColor; - function MixFill(AColor: TColor): TColor; published - property BorderColor: TColor read FBorderColor write SetBorderColor; - property BorderAlpha: Byte read FBorderAlpha write SetBorderAlpha; - property FillColor: TColor read FFillColor write SetFillColor; - property FillAlpha: Byte read FFillAlpha write SetFillAlpha; + property Border: TX2Color32 read FBorder write SetBorder stored IsBorderStored; + property Fill: TX2Color32 read FFill write SetFill stored IsFillStored; end; TX2MenuBarmCColors = class(TPersistent) @@ -156,57 +153,28 @@ end; procedure TX2MenuBarmusikCubePainter.ResetColors(); begin { Group buttons } - with GroupColors.Hot do - begin - BorderColor := clBtnShadow; - FillAlpha := 128; - FillColor := clBtnShadow; - end; + GroupColors.Hot.SetDefaultColors( Color32(clBtnShadow), + Color32(clBtnShadow, 128)); - with GroupColors.Normal do - begin - BorderAlpha := 64; - BorderColor := clBtnShadow; - FillAlpha := 64; - FillColor := clBtnShadow; - end; + GroupColors.Normal.SetDefaultColors( Color32(clBtnShadow, 64), + Color32(clBtnShadow, 64)); - with GroupColors.Selected do - begin - BorderColor := clBtnShadow; - FillColor := clBtnHighlight; - end; + GroupColors.Selected.SetDefaultColors(Color32(clBtnShadow), + Color32(clBtnHighlight)); { Indicator } - with IndicatorColors.Selected do - begin - BorderAlpha := 252; - BorderColor := clActiveCaption; - FillAlpha := 252; - FillColor := clActiveCaption; - end; + IndicatorColors.Selected.SetDefaultColors(Color32(clActiveCaption, 252), + Color32(clActiveCaption, 252)); { Item buttons } - with ItemColors.Hot do - begin - BorderColor := clBtnShadow; - FillAlpha := 114; - FillColor := clBtnHighlight; - end; + ItemColors.Hot.SetDefaultColors( Color32(clBtnShadow), + Color32(clBtnHighlight, 114)); - with ItemColors.Normal do - begin - BorderAlpha := 50; - BorderColor := clBtnHighlight; - FillAlpha := 50; - FillColor := clBtnHighlight; - end; + ItemColors.Normal.SetDefaultColors( Color32(clBtnHighlight, 50), + Color32(clBtnHighlight, 50)); - with ItemColors.Selected do - begin - BorderColor := clBtnShadow; - FillColor := clBtnHighlight; - end; + ItemColors.Selected.SetDefaultColors( Color32(clBtnShadow), + Color32(clBtnHighlight)); end; @@ -294,9 +262,9 @@ begin begin groupColor := GetColor(GroupColors, AState); - Brush.Color := groupColor.MixFill(Color); + Brush.Color := Blend(Color, groupColor.Fill); Brush.Style := bsSolid; - Pen.Color := groupColor.MixBorder(Color); + Pen.Color := Blend(Color, groupColor.Border); Pen.Style := psSolid; Rectangle(ABounds); @@ -338,16 +306,16 @@ begin itemBounds := ABounds; indicatorBounds := itemBounds; indicatorBounds.Right := indicatorBounds.Left + 6; - Brush.Color := indicatorColor.MixFill(Color); + Brush.Color := Blend(Color, indicatorColor.Fill); Brush.Style := bsSolid; - Pen.Color := indicatorColor.MixBorder(Color); + Pen.Color := Blend(Color, indicatorColor.Border); Pen.Style := psSolid; Rectangle(itemBounds); itemBounds.Left := indicatorBounds.Right; - Brush.Color := itemColor.MixFill(Color); + Brush.Color := Blend(Color, itemColor.Fill); Brush.Style := bsSolid; - Pen.Color := itemColor.MixBorder(Color); + Pen.Color := Blend(Color, itemColor.Border); Pen.Style := psSolid; Rectangle(itemBounds); @@ -447,25 +415,15 @@ end; { TX2MenuBarmCColor } -constructor TX2MenuBarmCColor.Create(); -begin - inherited; - - FBorderAlpha := 255; - FBorderColor := clNone; - FFillAlpha := 255; - FFillColor := clNone; -end; - procedure TX2MenuBarmCColor.Assign(Source: TPersistent); begin if Source is TX2MenuBarmCColor then with TX2MenuBarmCColor(Source) do begin - Self.BorderColor := BorderColor; - Self.BorderAlpha := BorderAlpha; - Self.FillColor := FillColor; - Self.FillAlpha := FillAlpha; + Self.DefaultBorder := DefaultBorder; + Self.DefaultFill := DefaultFill; + Self.Border := Border; + Self.Fill := Fill; end else inherited; @@ -478,77 +436,39 @@ begin FOnChange(Self); end; - -function TX2MenuBarmCColor.MixColors(ABackColor, AForeColor: TColor; - AAlpha: Byte): TColor; -var - cBack: Cardinal; - cFore: Cardinal; - bBack: Byte; - +procedure TX2MenuBarmCColor.SetDefaultColors(ABorder, AFill: TX2Color32); begin - { Source: X2UtGraphics.BlendColors } - cBack := ColorToRGB(ABackColor); - cFore := ColorToRGB(AForeColor); - bBack := 255 - AAlpha; - - Result := RGB(((GetRValue(cBack) * bBack) + - (GetRValue(cFore) * AAlpha)) shr 8, - ((GetGValue(cBack) * bBack) + - (GetGValue(cFore) * AAlpha)) shr 8, - ((GetBValue(cBack) * bBack) + - (GetBValue(cFore) * AAlpha)) shr 8); -end; - -function TX2MenuBarmCColor.MixBorder(AColor: TColor): TColor; -begin - if BorderColor = clNone then - Result := AColor - else - Result := MixColors(AColor, BorderColor, BorderAlpha); -end; - -function TX2MenuBarmCColor.MixFill(AColor: TColor): TColor; -begin - if FillColor = clNone then - Result := AColor - else - Result := MixColors(AColor, FillColor, FillAlpha); + FDefaultBorder := ABorder; + FDefaultFill := AFill; + FBorder := ABorder; + FFill := AFill; end; -procedure TX2MenuBarmCColor.SetBorderAlpha(const Value: Byte); +function TX2MenuBarmCColor.IsBorderStored(): Boolean; begin - if Value <> FBorderAlpha then + Result := (FBorder <> FDefaultBorder); +end; + +function TX2MenuBarmCColor.IsFillStored(): Boolean; +begin + Result := (FFill <> FDefaultFill); +end; + +procedure TX2MenuBarmCColor.SetBorder(const Value: TX2Color32); +begin + if Value <> FBorder then begin - FBorderAlpha := Value; + FBorder := Value; DoChange(); end; end; -procedure TX2MenuBarmCColor.SetBorderColor(const Value: TColor); +procedure TX2MenuBarmCColor.SetFill(const Value: TX2Color32); begin - if Value <> FBorderColor then + if Value <> FFill then begin - FBorderColor := Value; - DoChange(); - end; -end; - -procedure TX2MenuBarmCColor.SetFillAlpha(const Value: Byte); -begin - if Value <> FFillAlpha then - begin - FFillAlpha := Value; - DoChange(); - end; -end; - -procedure TX2MenuBarmCColor.SetFillColor(const Value: TColor); -begin - if Value <> FFillColor then - begin - FFillColor := Value; + FFill := Value; DoChange(); end; end; diff --git a/Source/X2CLunaMenuBarPainter.pas b/Source/X2CLunaMenuBarPainter.pas index d7c11ca..420370e 100644 --- a/Source/X2CLunaMenuBarPainter.pas +++ b/Source/X2CLunaMenuBarPainter.pas @@ -1,6 +1,9 @@ { :: Implements a Uname-IT-style painter for the X2MenuBar. :: + :: Part of the X2Software Component Library + :: http://www.x2software.net/ + :: :: Last changed: $Date$ :: Revision: $Rev$ :: Author: $Author$ diff --git a/Test/MenuBar/MainForm.dfm b/Test/MenuBar/MainForm.dfm index c7b30a6..840294e 100644 --- a/Test/MenuBar/MainForm.dfm +++ b/Test/MenuBar/MainForm.dfm @@ -32,151 +32,6 @@ object frmMain: TfrmMain Height = 13 Caption = 'Animation time (ms):' end - object mbTest: TX2MenuBar - Left = 0 - Top = 0 - Width = 125 - Height = 379 - Align = alLeft - Groups = <> - Images = glMenu - OnCollapsed = mbTestCollapsed - OnCollapsing = mbTestCollapsing - OnExpanded = mbTestExpanded - OnExpanding = mbTestExpanding - OnSelectedChanged = mbTestSelectedChanged - OnSelectedChanging = mbTestSelectedChanging - Painter = mcPainter - Groups = < - item - Caption = 'Share' - ImageIndex = 0 - Expanded = True - Items = < - item - Caption = 'File' - ImageIndex = 0 - end - item - Caption = 'Folder' - ImageIndex = 1 - end - item - Caption = 'Photo' - ImageIndex = 2 - end - item - Caption = 'Video' - ImageIndex = 3 - end - item - Caption = 'Invisible item' - Visible = False - end - item - Caption = 'Disabled item' - Enabled = False - end> - end - item - Caption = 'Group' - ImageIndex = 1 - Expanded = False - Items = < - item - Caption = 'Menu Item' - end> - end - item - Caption = 'Group without items' - ImageIndex = 2 - Expanded = False - Items = <> - end - item - Caption = 'Biiiiig group.' - Expanded = False - Items = < - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end> - end - item - Caption = 'Disabled group' - Enabled = False - Expanded = False - Items = < - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end - item - Caption = 'Menu Item' - end> - end> - end object seAnimationTime: TJvSpinEdit Left = 424 Top = 36 @@ -185,7 +40,7 @@ object frmMain: TfrmMain CheckMinValue = True ButtonKind = bkStandard Value = 250.000000000000000000 - TabOrder = 1 + TabOrder = 0 OnChange = seAnimationTimeChange end object Panel1: TPanel @@ -194,7 +49,7 @@ object frmMain: TfrmMain Width = 133 Height = 77 BevelOuter = bvNone - TabOrder = 2 + TabOrder = 1 object rbmusikCube: TRadioButton Left = 0 Top = 0 @@ -231,7 +86,7 @@ object frmMain: TfrmMain Width = 153 Height = 101 BevelOuter = bvNone - TabOrder = 3 + TabOrder = 2 object rbSliding: TRadioButton Left = 0 Top = 20 @@ -286,7 +141,7 @@ object frmMain: TfrmMain Width = 89 Height = 17 Caption = 'Auto collapse' - TabOrder = 4 + TabOrder = 3 OnClick = chkAutoCollapseClick end object chkAllowCollapseAll: TCheckBox @@ -295,7 +150,7 @@ object frmMain: TfrmMain Width = 101 Height = 17 Caption = 'Allow collapse all' - TabOrder = 6 + TabOrder = 5 OnClick = chkAllowCollapseAllClick end object chkAutoSelectItem: TCheckBox @@ -304,7 +159,7 @@ object frmMain: TfrmMain Width = 101 Height = 17 Caption = 'Auto select item' - TabOrder = 5 + TabOrder = 4 OnClick = chkAutoSelectItemClick end object chkScrollbar: TCheckBox @@ -315,7 +170,7 @@ object frmMain: TfrmMain Caption = 'Scrollbar' Checked = True State = cbChecked - TabOrder = 7 + TabOrder = 6 OnClick = chkScrollbarClick end object chkHideScrollbar: TCheckBox @@ -326,7 +181,7 @@ object frmMain: TfrmMain Caption = 'Hide Scrollbar' Checked = True State = cbChecked - TabOrder = 8 + TabOrder = 7 OnClick = chkHideScrollbarClick end object lbEvents: TListBox @@ -335,7 +190,7 @@ object frmMain: TfrmMain Width = 421 Height = 93 ItemHeight = 13 - TabOrder = 9 + TabOrder = 8 end object Button1: TButton Left = 152 @@ -344,7 +199,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectFirst' Enabled = False - TabOrder = 10 + TabOrder = 9 end object Button2: TButton Left = 152 @@ -353,7 +208,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectPrior' Enabled = False - TabOrder = 11 + TabOrder = 10 end object Button3: TButton Left = 152 @@ -362,7 +217,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectNext' Enabled = False - TabOrder = 12 + TabOrder = 11 end object Button4: TButton Left = 152 @@ -371,7 +226,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectLast' Enabled = False - TabOrder = 13 + TabOrder = 12 end object Button5: TButton Left = 152 @@ -380,7 +235,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectGroupByIndex' Enabled = False - TabOrder = 14 + TabOrder = 13 end object Button6: TButton Left = 152 @@ -389,7 +244,7 @@ object frmMain: TfrmMain Height = 25 Caption = 'SelectItemByIndex' Enabled = False - TabOrder = 15 + TabOrder = 14 end object chkHotHand: TCheckBox Left = 424 @@ -397,9 +252,132 @@ object frmMain: TfrmMain Width = 149 Height = 17 Caption = 'Hand cursor for hot items' - TabOrder = 16 + TabOrder = 15 OnClick = chkHotHandClick end + object mbTest: TX2MenuBar + Left = 0 + Top = 0 + Width = 125 + Height = 379 + Align = alLeft + Groups = < + item + Caption = 'Share' + ImageIndex = 0 + Expanded = True + Items = < + item + Caption = 'File' + ImageIndex = 0 + end + item + Caption = 'Folder' + ImageIndex = 1 + end + item + Caption = 'Photo' + ImageIndex = 2 + end + item + Caption = 'Video' + ImageIndex = 3 + end + item + Caption = 'Invisible item' + Visible = False + end + item + Caption = 'Disabled item' + Enabled = False + end> + end + item + Caption = 'Actions test' + ImageIndex = 1 + Expanded = False + Items = < + item + Action = actTest + Caption = 'I'#39'm an action!' + ImageIndex = 1 + end> + end + item + Caption = 'Group without items' + ImageIndex = 2 + Expanded = False + Items = <> + end + item + Caption = 'Biiiiig group.' + Expanded = False + Items = < + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end + item + end> + end + item + Caption = 'Disabled group' + Enabled = False + Expanded = False + Items = < + item + end + item + end + item + end> + end> + Images = glMenu + OnCollapsed = mbTestCollapsed + OnCollapsing = mbTestCollapsing + OnExpanded = mbTestExpanded + OnExpanding = mbTestExpanding + OnSelectedChanged = mbTestSelectedChanged + OnSelectedChanging = mbTestSelectedChanging + Painter = mcPainter + ExplicitLeft = -6 + end object gcMenu: TX2GraphicContainer Graphics = < item @@ -522,4 +500,14 @@ object frmMain: TfrmMain Left = 152 Top = 36 end + object alMenu: TActionList + Images = glMenu + Left = 236 + Top = 8 + object actTest: TAction + Caption = 'I'#39'm an action!' + ImageIndex = 1 + OnExecute = actTestExecute + end + end end diff --git a/Test/MenuBar/MainForm.pas b/Test/MenuBar/MainForm.pas index 69fde7d..bf558d1 100644 --- a/Test/MenuBar/MainForm.pas +++ b/Test/MenuBar/MainForm.pas @@ -17,11 +17,10 @@ uses X2CLGraphicList, X2CLMenuBar, X2CLmusikCubeMenuBarPainter, - X2CLunaMenuBarPainter; + X2CLunaMenuBarPainter, ActnList; type TfrmMain = class(TForm) - mbTest: TX2MenuBar; mcPainter: TX2MenuBarmusikCubePainter; gcMenu: TX2GraphicContainer; glMenu: TX2GraphicList; @@ -51,6 +50,9 @@ type Button5: TButton; Button6: TButton; chkHotHand: TCheckBox; + mbTest: TX2MenuBar; + alMenu: TActionList; + actTest: TAction; procedure mbTestSelectedChanging(Sender: TObject; Item, NewItem: TX2CustomMenuBarItem; var Allowed: Boolean); procedure mbTestSelectedChanged(Sender: TObject; @@ -70,16 +72,24 @@ type procedure PainterClick(Sender: TObject); procedure AnimationClick(Sender: TObject); procedure seAnimationTimeChange(Sender: TObject); + procedure actTestExecute(Sender: TObject); private procedure Event(const AMsg: String); end; implementation uses + Dialogs, + X2UtHandCursor; {$R *.dfm} +procedure TfrmMain.actTestExecute(Sender: TObject); +begin + ShowMessage('Action saying: hi!'); +end; + procedure TfrmMain.AnimationClick(Sender: TObject); var style: TX2MenuBarAnimationStyle; diff --git a/Test/MenuBar/MenuBarTest.dpr b/Test/MenuBar/MenuBarTest.dpr index 3614f71..51051f7 100644 --- a/Test/MenuBar/MenuBarTest.dpr +++ b/Test/MenuBar/MenuBarTest.dpr @@ -3,7 +3,8 @@ program MenuBarTest; uses Forms, MainForm in 'MainForm.pas' {frmMain}, - X2CLMenuBarAnimators in '..\..\Source\X2CLMenuBarAnimators.pas'; + X2CLMenuBarAnimators in '..\..\Source\X2CLMenuBarAnimators.pas', + X2CLGraphics in '..\..\Source\X2CLGraphics.pas'; {$R *.res}