| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631 |
- {
- ********************************************************************************
- * BGRAExpandPanels Version 1.0 *
- * *
- * *
- * (c) Massimo Magnano, Alexander Roth *
- * *
- * *
- ********************************************************************************
- See BcExpandPanels.txt for changelog and to-do
- }
- unit BCExpandPanels;
- {$mode objfpc}{$H+}
- // for debugging purposes
- //{$DEFINE DEBUG_PAINT}
- interface
- uses
- Controls, Classes, ExtCtrls, Graphics, Math, LResources, Dialogs, SysUtils,
- Buttons, Themes, Types, Menus, BCPanel;
- type
- TBCExpandPanelsBehaviour = (EPHotMouse, EPMultipanel, EPSinglePanel);
- // TBoundEvent=procedure(sender:TObject; ALeft, ATop, AWidth, AHeight: integer) of object;
- TAnimationEvent = procedure(Sender: TObject; deltaLeft, deltaTop, deltaWidth, deltaHeight: integer) of object;
- TNormalProcedure = procedure of object;
- { TBCBoundButton }
- TGlyphLayout =
- (
- glLeft,
- glRight,
- glNone
- );
- TGlyphKind =
- (
- gkArrows,
- gkClose,
- gkMinMax
- );
- TTextLayout =
- (
- tlLeft,
- tlRight,
- tlCenter,
- tlNone
- );
- TBCBoundButtonStyle = (bbsButton, bbsTab, bbsLine, bbsLineDouble,
- bbsLineTop, bbsLineBottom, bbsLineDoubleTop, bbsLineDoubleBottom);
- TBCBoundButton = class(TCustomSpeedButton)
- private
- rColorExpanded: TColor;
- rColorHighlight: TColor;
- rColorShadow: TColor;
- rGlyphKind: TGlyphKind;
- rGlyphLayout: TGlyphLayout;
- rStyle: TBCBoundButtonStyle;
- rTabWidth: Integer;
- rTextLayout: TTextLayout;
- procedure setColorExpanded(AValue: TColor);
- procedure SetColorHighlight(AValue: TColor);
- procedure SetColorShadow(AValue: TColor);
- procedure SetGlyphKind(AValue: TGlyphKind);
- procedure SetGlyphLayout(AValue: TGlyphLayout);
- procedure SetStyle(AValue: TBCBoundButtonStyle);
- procedure SetTabWidth(AValue: Integer);
- procedure SetTextLayout(AValue: TTextLayout);
- protected
- rGlyph :TButtonGlyph;
- rUserGlyphExpanded,
- rUserGlyphCollapsed,
- rGlyphExpanded,
- rGlyphCollapsed :TBitmap;
- procedure SetGlyphCollapsed(AValue: TBitmap);
- procedure SetGlyphExpanded(AValue: TBitmap);
- procedure LoadGlyph(GlyphDST :TBitmap; ResName :String);
- procedure BuildGlyphs;
- procedure Paint; override;
- procedure Loaded; override;
- (* property AllowAllUp;
- property Down;
- property Glyph;
- property GroupIndex;
- property Height; //Don't Decrease visibility :-O
- property HelpContext;
- property HelpKeyword;
- property HelpType;
- property Layout;
- property Left;
- property Margin;
- property Name;
- property NumGlyphs;
- property Spacing;
- property ShowCaption;
- property Tag;
- property Top;
- property Width;
- property Transparent;
- *)
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property Caption;
- property Color nodefault;
- property ColorExpanded: TColor read rColorExpanded write setColorExpanded;
- property ColorHighlight: TColor read rColorHighlight write SetColorHighlight default clDefault;
- property ColorShadow: TColor read rColorShadow write SetColorShadow default clDefault;
- property Font;
- property Flat;
- property GlyphExpanded: TBitmap read rUserGlyphExpanded write SetGlyphExpanded;
- property GlyphCollapsed: TBitmap read rUserGlyphCollapsed write SetGlyphCollapsed;
- property GlyphLayout: TGlyphLayout read rGlyphLayout write SetGlyphLayout default glNone;
- property GlyphKind: TGlyphKind read rGlyphKind write SetGlyphKind default gkArrows;
- property ShowAccelChar;
- property TextLayout: TTextLayout read rTextLayout write SetTextLayout default tlLeft;
- property Style: TBCBoundButtonStyle read rStyle write SetStyle default bbsButton;
- //Negative Values is the % of Total Width, Positive is a Fixed Width
- property TabWidth: Integer read rTabWidth write SetTabWidth default -50;
- end;
- { TBCExpandPanel }
- TBCExpandPanel = class(TBCPanel)
- private
- FEPManagesCollapsing: TNotifyEvent;
- FButton: TBCBoundButton;
- FButtonSize: integer;
- FCollapseKind: TAnchorKind;
- FCollapsed: boolean;
- FAnimated: boolean;
- FOnExpand: TNotifyEvent;
- FOnPreExpand: TNotifyEvent;
- FOnAnimate: TAnimationEvent;
- FOnCollapse: TNotifyEvent;
- FOnPreCollapse: TNotifyEvent;
- FOnButtonClick: TNotifyEvent;
- FInternalOnAnimate: TAnimationEvent;
- FButtonPosition: TAnchorKind;
- FExpandedButtonColor: TColor;
- FCollapsedButtonColor: TColor;
- FExpandedSize: integer;
- FAnimationSpeed: real;
- FTextAlignment: TAlignment;
- rBevelColorHighlight: TColor;
- rBevelColorShadow: TColor;
- rBevelRounded: Boolean;
- StopCircleActions: boolean;
- FAnimating: boolean;
- FVisibleTotal: boolean;
- TargetAnimationSize: integer;
- EndProcedureOfAnimation: TNormalProcedure;
- Timer: TTimer;
- function GetEnabled: Boolean;
- procedure SetBevelColorHighlight(AValue: TColor);
- procedure SetBevelColorShadow(AValue: TColor);
- procedure SetBevelRounded(AValue: Boolean);
- procedure SetEnabled(AValue: Boolean);
- procedure setExpandedSize(Value: integer);
- procedure setButtonSize(Value: integer);
- procedure setButtonPosition(Value: TAnchorKind);
- procedure setCollapseKind(Value: TAnchorKind);
- procedure setAnimationSpeed(Value: real);
- procedure setCollapsed(Value: boolean);
- procedure PositionButton;
- procedure SetRelevantSize(comp: TControl; AKind: TAnchorKind; ASize: Integer);
- function RelevantSize(comp: TControl; akind: TAnchorKind): integer;
- function RelevantOrthogonalSize(comp: TControl; akind: TAnchorKind): integer;
- function DeltaCoordinates(deltaMove, deltaSize: integer): TRect; // the outpot (left,top right, bottom) has all the information: left and top encode the movement. rigth and bottom the size changes
- procedure Animate(aTargetSize: integer);
- procedure SetTextAlignment(AValue: TAlignment);
- procedure TimerAnimateSize(Sender: TObject);
- procedure EndTimerCollapse;
- procedure EndTimerExpand;
- procedure UpdateAll;
- procedure ButtonClick(Sender: TObject);
- procedure DoCollapse;
- procedure DoExpand;
- procedure AdjustClientRect(var ARect: TRect); override;
- property InternalOnAnimate: TAnimationEvent read FInternalOnAnimate write FInternalOnAnimate;
- property EPManagesCollapsing: TNotifyEvent read FEPManagesCollapsing write FEPManagesCollapsing;
- protected
- procedure Loaded; override;
- procedure CreateWnd; override;
- procedure Paint; override;
- public
- property Animating: boolean read FAnimating;
- constructor Create(TheOwner: TComponent); override;
- destructor Destroy; override;
- procedure SetBounds(ALeft, ATop, AWidth, AHeight: integer); override;
- published
- property TextAlignment: TAlignment read FTextAlignment write SetTextAlignment;
- property Enabled: Boolean read GetEnabled write SetEnabled;
- property CollapseKind: TAnchorKind read FCollapseKind write setCollapseKind; //To where should it collapse?
- property ExpandedSize: integer read FExpandedSize write setExpandedSize;
- property ButtonPosition: TAnchorKind read FButtonPosition write setButtonPosition;
- property ButtonSize: integer read FButtonSize write setButtonSize;
- property Button: TBCBoundButton read FButton;
- property AnimationSpeed: real read FAnimationSpeed write setAnimationSpeed;
- property Animated: boolean read FAnimated write FAnimated default True;
- property Collapsed: boolean read FCollapsed write setCollapsed default False;
- property BevelColorHighlight: TColor read rBevelColorHighlight write SetBevelColorHighlight default clBtnHighlight;
- property BevelColorShadow: TColor read rBevelColorShadow write SetBevelColorShadow default clBtnShadow;
- property BevelRounded: Boolean read rBevelRounded write SetBevelRounded default True;
- property OnAnimate: TAnimationEvent read FOnAnimate write FOnAnimate;
- property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
- property OnPreExpand: TNotifyEvent read FOnPreExpand write FOnPreExpand;
- property OnExpand: TNotifyEvent read FOnExpand write FOnExpand;
- property OnCollapse: TNotifyEvent read FOnCollapse write FOnCollapse;
- property OnPreCollapse: TNotifyEvent read FOnPreCollapse write FOnPreCollapse;
- end;
- {==============================================================================
- Class: TBCExpandPanels
- Description:
- ==============================================================================}
- { TBCExpandPanels }
- TBCExpandPanels = class(TComponent)
- private
- { Private-Deklarationen }
- PanelArray: TList;
- // Properties
- FArrangeKind: TAnchorKind;
- FButtonPosition, FCollapseKind: TAnchorKind;
- FButtonGlyphKind: TGlyphKind;
- FButtonGlyphLayout: TGlyphLayout;
- FButtonStyle: TBCBoundButtonStyle;
- FButtonTabWidth: Integer;
- FButtonTextLayout: TTextLayout;
- FOrthogonalAbove: integer;
- FAbove: integer;
- FOrthogonalSize: integer;
- FBehaviour: TBCExpandPanelsBehaviour;
- FOnArrangePanels: TNotifyEvent;
- FFixedSize: integer;
- FUseFixedSize: boolean;
- FAutoCollapseIfTooHigh: boolean;
- FUseClientSize: boolean;
- function RelevantAbove(comp: TControl): integer;
- function RelevantOrthogonalAbove(comp: TControl): integer;
- function RelevantSize(comp: TControl): integer;
- function RelevantOrthogonalSize(comp: TControl): integer;
- procedure setButtonGlyphKind(AValue: TGlyphKind);
- procedure setButtonGlyphLayout(AValue: TGlyphLayout);
- procedure setButtonStyle(AValue: TBCBoundButtonStyle);
- procedure SetButtonTabWidth(AValue: Integer);
- procedure setButtonTextLayout(AValue: TTextLayout);
- procedure WriteRelevantAbove(comp: TBCExpandPanel; above: integer);
- procedure WriteRelevantSize(comp: TBCExpandPanel; size: integer);
- procedure WriteRelevantOrthogonalSize(comp: TBCExpandPanel; size: integer);
- procedure WriteRelevantOrthogonalAbove(comp: TBCExpandPanel; size: integer);
- procedure setArrangeKind(Value: TAnchorKind);
- procedure setButtonPosition(Value: TAnchorKind);
- procedure setCollapseKind(Value: TAnchorKind);
- procedure setUseClientSize(Value: boolean);
- procedure setUseFixedSize(Value: boolean);
- procedure setAutoCollapseIfTooHigh(Value: boolean);
- procedure setFixedSize(Value: integer);
- procedure setOrthogonalAbove(Value: integer);
- procedure setAbove(Value: integer);
- procedure setOrthogonalSize(Value: integer);
- procedure setBehaviour(Value: TBCExpandPanelsBehaviour);
- procedure MakeCorrectButtonClickPointers;
- procedure RollOutOnAnimate(Sender: TObject; deltaLeft, deltaTop, deltaWidth, deltaHeight: integer);
- procedure RollOutClick(Sender: TObject);
- procedure HotTrackSetActivePanel(Value: integer);
- procedure DelLastPanel;
- procedure RollOut1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
- protected
- { Protected-Deklarationen }
- public
- { Public-Deklarationen }
- property OrthogonalAbove: integer read FOrthogonalAbove write setOrthogonalAbove;
- property Above: integer read FAbove write setAbove;
- property OrthogonalSize: integer read FOrthogonalSize write setOrthogonalSize;
- function IdxOfPanel(aname: string): integer; overload;
- procedure CollapseIfTooHigh;
- // procedure SetCorrectSize;
- procedure AddPanel(rollout: TBCExpandPanel);
- procedure InsertPanel(idx: integer; rollout: TBCExpandPanel);
- function DeltePanel(aname: string): boolean; overload;
- function DeltePanel(idx: integer): boolean; overload;
- procedure DelteLastPanel;
- procedure ArrangePanels;
- function Count: integer;
- function Panel(idx: integer): TBCExpandPanel;
- property CollapseKind: TAnchorKind read FCollapseKind write setCollapseKind;
- property ButtonPosition: TAnchorKind read FButtonPosition write setButtonPosition;
- property ButtonGlyphLayout: TGlyphLayout read FButtonGlyphLayout write setButtonGlyphLayout;
- property ButtonGlyphKind: TGlyphKind read FButtonGlyphKind write setButtonGlyphKind;
- property ButtonStyle: TBCBoundButtonStyle read FButtonStyle write setButtonStyle;
- property ButtonTabWidth: Integer read FButtonTabWidth write SetButtonTabWidth;
- property ButtonTextLayout: TTextLayout read FButtonTextLayout write setButtonTextLayout;
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- { Published-Deklarationen }
- // property FixedHeight:integer read FFixedHeight write setFixedSize;
- // property UseFixedHeight:boolean read FUseFixedHeight write setUseFixedSize;
- // property UseClientHeight:boolean read FUseClientHeight write setUseClientSize;
- // property AutoCollapseIfTooHigh:boolean read FAutoCollapseIfTooHigh write setAutoCollapseIfTooHigh;
- property ArrangeKind: TAnchorKind read FArrangeKind write setArrangeKind;
- property OnArrangePanels: TNotifyEvent read FOnArrangePanels write FOnArrangePanels;
- property Behaviour: TBCExpandPanelsBehaviour read FBehaviour write setBehaviour;
- end;
- procedure Register;
- implementation
- uses GraphType, LCLProc;
- const
- //GrayScale a Color : Taken from BGRABitmap package
- redWeightShl10 = 306; // = 0.299
- greenWeightShl10 = 601; // = 0.587
- blueWeightShl10 = 117; // = 0.114
- procedure korrigiere(var w: real; min, max: real);
- var
- temp: real;
- begin
- if max < min then
- begin
- temp := min;
- min := max;
- max := temp;
- end;
- if w < min then
- w := min;
- if w > max then
- w := max;
- end;
- //Function copied from BGRABitmap package may work ;-)
- function Grayscale(AColor :TColor):TColor;
- Var
- rColor, gray :Integer;
- begin
- rColor :=ColorToRGB(AColor);
- gray := (Red(rColor) * redWeightShl10 + Green(rColor) * greenWeightShl10 + Blue(rColor) * blueWeightShl10 + 512) shr 10;
- Result :=RGBToColor(gray, gray, gray);
- end;
- function GetHighlightColor(BaseColor: TColor; Value:Integer): TColor;
- Var
- rColor :Integer;
- begin
- rColor :=ColorToRGB(BaseColor);
- Result := RGBToColor(
- Min(Red(rColor) + Value, $FF),
- Min(Green(rColor) + Value, $FF),
- Min(Blue(rColor) + Value, $FF));
- end;
- function GetShadowColor(BaseColor: TColor; Value:Integer): TColor;
- Var
- rColor :Integer;
- begin
- rColor :=ColorToRGB(BaseColor);
- Result := RGBToColor(
- Max(Red(rColor) - Value, $22),
- Max(Green(rColor) - Value, $22),
- Max(Blue(rColor) - Value, $22));
- end;
- //Canvas Draw Functions
- procedure Frame3d_Rounded(Canvas: TCanvas;
- var ARect: TRect; const FrameWidth : integer; RX, RY:Integer;
- const Style : TGraphicsBevelCut;
- ShadowColor, HighlightColor, InternalColor: TColor);
- var
- DRect: TRect;
- procedure drawUP;
- begin
- inc(DRect.Left,1); inc(DRect.Top,1);
- //is outside the Rect but in this way we don't have a hole of 1 px
- inc(DRect.Right,1); inc(DRect.Bottom,1);
- Canvas.Brush.Color :=ShadowColor;
- Canvas.Brush.Style :=bsSolid;
- Canvas.Pen.Color := clNone;
- Canvas.Pen.Width := 1; //The Shadow is always 1 Pixel
- Canvas.Pen.Style := psClear;
- Canvas.RoundRect(DRect, RX,RY);
- dec(DRect.Left,1); dec(DRect.Top,1);
- dec(DRect.Right,2); dec(DRect.Bottom,2);
- Canvas.Brush.Color :=InternalColor;
- if (InternalColor = clNone)
- then Canvas.Brush.Style :=bsClear
- else Canvas.Brush.Style :=bsSolid;
- Canvas.Pen.Color :=HighlightColor;
- Canvas.Pen.Width := FrameWidth;
- Canvas.Pen.Style := psSolid;
- Canvas.RoundRect(DRect, RX,RY);
- Inc(ARect.Top, FrameWidth);
- Inc(ARect.Left, FrameWidth);
- Dec(ARect.Right, FrameWidth+1); //+The Shadow (1 Pixel) +1?
- Dec(ARect.Bottom, FrameWidth+1);
- end;
- procedure drawFLAT;
- begin
- Canvas.Brush.Color := InternalColor;
- if (InternalColor = clNone)
- then Canvas.Brush.Style :=bsClear
- else Canvas.Brush.Style :=bsSolid;
- Canvas.Pen.Color := clNone;
- Canvas.Pen.Width := FrameWidth;
- Canvas.Pen.Style := psClear;
- Canvas.RoundRect(DRect, RX,RY);
- end;
- procedure drawDOWN;
- begin
- Canvas.Brush.Color :=ShadowColor;
- Canvas.Brush.Style :=bsSolid;
- Canvas.Pen.Color := clNone;
- Canvas.Pen.Width := 1;
- Canvas.Pen.Style := psClear;
- Canvas.RoundRect(DRect, RX,RY);
- inc(DRect.Left,1); inc(DRect.Top,1);
- Canvas.Brush.Color :=InternalColor;
- if (InternalColor = clNone)
- then Canvas.Brush.Style :=bsClear
- else Canvas.Brush.Style :=bsSolid;
- Canvas.Pen.Color :=HighlightColor;
- Canvas.Pen.Width := FrameWidth;
- Canvas.Pen.Style := psSolid;
- Canvas.RoundRect(DRect, RX,RY);
- Inc(ARect.Top, FrameWidth+1); //+The Shadow (1 Pixel)
- Inc(ARect.Left, FrameWidth+1);
- Dec(ARect.Right, FrameWidth);
- Dec(ARect.Bottom, FrameWidth);
- end;
- begin
- DRect :=ARect;
- Case Style of
- bvNone: drawFLAT;
- bvSpace: begin
- drawFLAT;
- InflateRect(ARect, -FrameWidth, -FrameWidth);
- end;
- bvRaised: drawUP;
- bvLowered: drawDOWN;
- end;
- end;
- procedure TBCBoundButton.SetColorHighlight(AValue: TColor);
- begin
- if (rColorHighlight <> AValue) then
- begin
- rColorHighlight := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.setColorExpanded(AValue: TColor);
- begin
- if (rColorExpanded <> AValue) then
- begin
- rColorExpanded := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetColorShadow(AValue: TColor);
- begin
- if (rColorShadow <> AValue) then
- begin
- rColorShadow := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetGlyphKind(AValue: TGlyphKind);
- begin
- if (rGlyphKind <> AValue) then
- begin
- rGlyphKind:=AValue;
- if not(csLoading in ComponentState) then
- begin
- BuildGlyphs;
- Invalidate;
- end;
- end;
- end;
- procedure TBCBoundButton.SetGlyphLayout(AValue: TGlyphLayout);
- begin
- if (rGlyphLayout <> AValue) then
- begin
- rGlyphLayout := AValue;
- if not(csLoading in ComponentState) then
- begin
- BuildGlyphs;
- Invalidate;
- end;
- end;
- end;
- procedure TBCBoundButton.SetStyle(AValue: TBCBoundButtonStyle);
- begin
- if (rStyle <> AValue) then
- begin
- rStyle:=AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetTabWidth(AValue: Integer);
- begin
- if (rTabWidth <> AValue) then
- begin
- rTabWidth:=AValue;
- if not(csLoading in ComponentState) and (rStyle = bbsTab)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetTextLayout(AValue: TTextLayout);
- begin
- if (rTextLayout <> AValue) then
- begin
- rTextLayout := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetGlyphCollapsed(AValue: TBitmap);
- begin
- rUserGlyphCollapsed.Assign(AValue);
- if not(csLoading in ComponentState) then
- begin
- BuildGlyphs;
- Invalidate;
- end;
- end;
- procedure TBCBoundButton.SetGlyphExpanded(AValue: TBitmap);
- begin
- rUserGlyphExpanded.Assign(AValue);
- if not(csLoading in ComponentState) then
- begin
- BuildGlyphs;
- Invalidate;
- end;
- end;
- procedure TBCBoundButton.LoadGlyph(GlyphDST: TBitmap; ResName: String);
- Var
- rGlyphO: TPortableNetworkGraphic;
- begin
- rGlyphO :=TPortableNetworkGraphic.Create;
- rGlyphO.LoadFromLazarusResource(ResName);
- GlyphDST.Assign(rGlyphO);
- FreeAndNil(rGlyphO);
- end;
- procedure TBCBoundButton.BuildGlyphs;
- begin
- if (rGlyphLayout <> glNone) then
- begin
- if (rUserGlyphCollapsed.Empty)
- then Case rGlyphKind of
- gkArrows: case TBCExpandPanel(Owner).CollapseKind of
- akTop: LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_BOTTOM');
- akLeft: LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_RIGHT');
- akRight: LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_LEFT');
- akBottom: LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_TOP');
- end;
- gkClose: LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_CLOSE');
- gkMinMax: if (TBCExpandPanel(Owner).CollapseKind in [akTop, akBottom])
- then LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_MAX_H')
- else LoadGlyph(rGlyphCollapsed, 'BCEXP_PANEL_MAX_V');
- end
- else rGlyphCollapsed.Assign(rUserGlyphCollapsed);
- if (rUserGlyphExpanded.Empty)
- then Case rGlyphKind of
- gkArrows: case TBCExpandPanel(Owner).CollapseKind of
- akTop: LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_TOP');
- akLeft: LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_LEFT');
- akRight: LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_RIGHT');
- akBottom: LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_BOTTOM');
- end;
- gkClose: LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_CLOSE');
- gkMinMax: if (TBCExpandPanel(Owner).CollapseKind in [akTop, akBottom])
- then LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_MIN_H')
- else LoadGlyph(rGlyphExpanded, 'BCEXP_PANEL_MIN_V');
- end
- else rGlyphExpanded.Assign(rUserGlyphExpanded);
- end;
- end;
- procedure TBCBoundButton.Paint;
- var
- paintRect, fRect :TRect;
- xColor,
- xHColor,
- xSColor :TColor;
- middleX,
- middleY,
- txtWidth,
- txtLeft,
- txtTop,
- glyphLeft,
- glyphTop :Integer;
- xCaption :String;
- FButtonPosition :TAnchorKind;
- FCollapsed, Rounded :Boolean;
- procedure drawGlyph(var ATop, ALeft :Integer);
- var
- AWidth, AHeight :Integer;
- begin
- AWidth :=paintRect.Right-paintRect.Left-2;
- AHeight :=paintRect.Bottom-paintRect.Top-2;
- if FCollapsed
- then rGlyph.Glyph.Assign(rGlyphCollapsed)
- else rGlyph.Glyph.Assign(rGlyphExpanded);
- //We must Calculate the Real Position of the Glyph
- Case FButtonPosition of
- akTop,
- akBottom : begin
- if (rGlyphLayout = glLeft)
- then begin
- ALeft :=2;
- ATop :=middleY-(rGlyph.Glyph.Height div 2);
- end
- else begin
- ALeft :=AWidth-rGlyph.Glyph.Width;
- ATop :=middleY-(rGlyph.Glyph.Height div 2);
- end;
- end;
- akLeft :begin
- if (rGlyphLayout = glLeft)
- then begin //Really on Bottom of paintRect
- ALeft :=middleX-(rGlyph.Glyph.Width div 2);
- ATop :=AHeight-rGlyph.Glyph.Height;
- end
- else begin //Really on Top of paintRect
- ALeft :=middleX-(rGlyph.Glyph.Width div 2);
- ATop :=2;
- end;
- end;
- akRight :begin
- if (rGlyphLayout = glLeft)
- then begin //Really on Top of paintRect
- ALeft :=middleX-(rGlyph.Glyph.Width div 2);
- ATop :=2;
- end
- else begin //Really on Bottom of paintRect
- ALeft :=middleX-(rGlyph.Glyph.Width div 2);
- ATop :=AHeight-rGlyph.Glyph.Height;
- end;
- end;
- end;
- rGlyph.Draw(Canvas, paintRect, point(ALeft, ATop), FState, true, 0);
- end;
- procedure drawBtn(const ABorderStyle : TGraphicsBevelCut);
- var
- xTabWidth,
- tY, tX: Integer;
- begin
- Case rStyle of
- bbsButton: Frame3d_Rounded(Canvas, paintRect, 1, 5, 5, ABorderStyle, xSColor, xHColor, xColor);
- bbsTab: begin
- fRect :=paintRect;
- Case FButtonPosition of
- akTop : begin
- //If rTabWidth is Negative Calculate the Tab Width
- if (rTabWidth < 0)
- then xTabWidth :=(fRect.Right-fRect.Left)*-rTabWidth div 100
- else xTabWidth :=rTabWidth;
- inc(paintRect.Left, middleX-(xTabWidth div 2));
- paintRect.Right:=paintRect.Left+xTabWidth;
- Frame3d_Rounded(Canvas, paintRect, 1, 5, 5, ABorderStyle, xSColor, xHColor, xColor);
- tY :=fRect.Bottom-2;
- Canvas.Pen.Style:=psSolid;
- Canvas.Pen.Width:=1;
- Canvas.Pen.Color :=xHColor;
- if Rounded
- then Canvas.MoveTo(2, tY)
- else Canvas.MoveTo(0, tY);
- Canvas.LineTo(paintRect.Left-3, tY);
- Canvas.LineTo(paintRect.Left, tY-3);
- if Rounded
- then Canvas.MoveTo(fRect.Right-4, tY)
- else Canvas.MoveTo(fRect.Right, tY);
- Canvas.LineTo(paintRect.Right+2, tY);
- Canvas.LineTo(paintRect.Right-1, tY-3);
- Canvas.Pen.Color :=xColor;
- Canvas.MoveTo(paintRect.Left-2, tY);
- Canvas.LineTo(paintRect.Right+2, tY);
- dec(tY);
- Canvas.MoveTo(paintRect.Left-1, tY);
- Canvas.LineTo(paintRect.Right+1, tY);
- tY :=fRect.Bottom-1;
- if FCollapsed then Canvas.Pen.Color :=xSColor;
- if Rounded
- then begin
- Canvas.MoveTo(fRect.Left+2, tY);
- Canvas.LineTo(fRect.Right-3, tY);
- end
- else begin
- Canvas.MoveTo(fRect.Left, tY);
- Canvas.LineTo(fRect.Right, tY);
- end;
- end;
- akBottom : begin
- if (rTabWidth < 0)
- then xTabWidth :=(fRect.Right-fRect.Left)*-rTabWidth div 100
- else xTabWidth :=rTabWidth;
- inc(paintRect.Left, middleX-(xTabWidth div 2));
- paintRect.Right:=paintRect.Left+xTabWidth;
- dec(paintRect.Top);
- Frame3d_Rounded(Canvas, paintRect, 1, 5, 5, ABorderStyle, xSColor, xHColor, xColor);
- Canvas.Pen.Style:=psSolid;
- Canvas.Pen.Width:=1;
- Canvas.Pen.Color :=xHColor;
- if Rounded
- then Canvas.MoveTo(2, 1)
- else Canvas.MoveTo(0, 1);
- Canvas.LineTo(paintRect.Left-3, 1);
- Canvas.LineTo(paintRect.Left, 4);
- if Rounded
- then Canvas.MoveTo(fRect.Right-4, 1)
- else Canvas.MoveTo(fRect.Right, 1);
- Canvas.LineTo(paintRect.Right+2, 1);
- Canvas.LineTo(paintRect.Right-1, 4);
- Canvas.Pen.Color :=xColor;
- Canvas.MoveTo(paintRect.Left-2, 1);
- Canvas.LineTo(paintRect.Right+2, 1);
- Canvas.MoveTo(paintRect.Left-1, 2);
- Canvas.LineTo(paintRect.Right+1, 2);
- if FCollapsed then Canvas.Pen.Color :=xSColor;
- if Rounded
- then begin
- Canvas.MoveTo(fRect.Left+2, 0);
- Canvas.LineTo(fRect.Right-3, 0);
- end
- else begin
- Canvas.MoveTo(fRect.Left, 0);
- Canvas.LineTo(fRect.Right, 0);
- end;
- end;
- akLeft : begin
- if (rTabWidth < 0)
- then xTabWidth :=(fRect.Bottom-fRect.Top)*-rTabWidth div 100
- else xTabWidth :=rTabWidth;
- inc(paintRect.Top, middleY-(xTabWidth div 2));
- paintRect.Bottom:=paintRect.Top+xTabWidth;
- Frame3d_Rounded(Canvas, paintRect, 1, 5, 5, ABorderStyle, xSColor, xHColor, xColor);
- tX :=fRect.Right-2;
- Canvas.Pen.Style:=psSolid;
- Canvas.Pen.Width:=1;
- Canvas.Pen.Color :=xHColor;
- if Rounded
- then Canvas.MoveTo(tX, 2)
- else Canvas.MoveTo(tX, 0);
- Canvas.LineTo(tX, paintRect.Top-3);
- Canvas.LineTo(tX-3, paintRect.Top);
- if Rounded
- then Canvas.MoveTo(tX, fRect.Bottom-4)
- else Canvas.MoveTo(tX, fRect.Bottom);
- Canvas.LineTo(tX, paintRect.Bottom+2);
- Canvas.LineTo(tX-3, paintRect.Bottom-1);
- Canvas.Pen.Color :=xColor;
- Canvas.MoveTo(tX, paintRect.Top-2);
- Canvas.LineTo(tX, paintRect.Bottom+2);
- dec(tX);
- Canvas.MoveTo(tX, paintRect.Top-1);
- Canvas.LineTo(tX, paintRect.Bottom+1);
- tX :=fRect.Right-1;
- if FCollapsed then Canvas.Pen.Color :=xSColor;
- if Rounded
- then begin
- Canvas.MoveTo(tX, fRect.Top+2);
- Canvas.LineTo(tX, fRect.Bottom-3);
- end
- else begin
- Canvas.MoveTo(tX, fRect.Top);
- Canvas.LineTo(tX, fRect.Bottom);
- end;
- end;
- akRight : begin
- if (rTabWidth < 0)
- then xTabWidth :=(fRect.Bottom-fRect.Top)*-rTabWidth div 100
- else xTabWidth :=rTabWidth;
- inc(paintRect.Top, middleY-(xTabWidth div 2));
- paintRect.Bottom:=paintRect.Top+xTabWidth;
- dec(paintRect.Left);
- Frame3d_Rounded(Canvas, paintRect, 1, 5, 5, ABorderStyle, xSColor, xHColor, xColor);
- Canvas.Pen.Style:=psSolid;
- Canvas.Pen.Width:=1;
- Canvas.Pen.Color :=xHColor;
- if Rounded
- then Canvas.MoveTo(1, 2)
- else Canvas.MoveTo(1, 0);
- Canvas.LineTo(1, paintRect.Top-3);
- Canvas.LineTo(4, paintRect.Top);
- if Rounded
- then Canvas.MoveTo(1, fRect.Bottom-4)
- else Canvas.MoveTo(1, fRect.Bottom);
- Canvas.LineTo(1, paintRect.Bottom+2);
- Canvas.LineTo(4, paintRect.Bottom-1);
- Canvas.Pen.Color :=xColor;
- Canvas.MoveTo(1, paintRect.Top-2);
- Canvas.LineTo(1, paintRect.Bottom+2);
- Canvas.MoveTo(2, paintRect.Top-1);
- Canvas.LineTo(2, paintRect.Bottom+1);
- if FCollapsed then Canvas.Pen.Color :=xSColor;
- if Rounded
- then begin
- Canvas.MoveTo(0, fRect.Top+2);
- Canvas.LineTo(0, fRect.Bottom-3);
- end
- else begin
- Canvas.MoveTo(0, fRect.Top);
- Canvas.LineTo(0, fRect.Bottom);
- end;
- end;
- end;
- end;
- end;
- end;
- procedure drawText;
- Var
- DTop, DLeft,
- AWidth, AHeight,
- txtH :Integer;
- procedure CalcCuttedCaption(MaxWidth :Integer);
- Var
- txtMaxChars :Integer;
- begin
- txtWidth :=0;
- if (MaxWidth < Canvas.TextWidth('...'))
- then xCaption :=''
- else begin
- txtMaxChars :=Canvas.TextFitInfo(xCaption, MaxWidth);
- txtWidth :=Canvas.TextWidth(xCaption);
- while (txtWidth > MaxWidth) do
- begin
- dec(txtMaxChars, 3); //-1 Chars fit better, -3 Chars for more speed
- xCaption :=Copy(xCaption, 0, txtMaxChars)+'...';
- txtWidth :=Canvas.TextWidth(xCaption);
- end;
- end;
- (* Original Code, Test Speed
- if (txtW > AWidth)
- then begin
- txtMaxChars :=Canvas.TextFitInfo(xCaption, AWidth);
- xCaption :=Copy(xCaption, 0, txtMaxChars-3)+'...';
- txtW :=Canvas.TextWidth(xCaption);
- if (txtW > AWidth)
- then xCaption :='';
- end;
- *)
- end;
- begin
- txtH :=Canvas.TextHeight(xCaption);
- AWidth :=paintRect.Right-paintRect.Left-2;
- AHeight :=paintRect.Bottom-paintRect.Top-2;
- Case FButtonPosition of
- akTop,
- akBottom : begin
- Canvas.Font.Orientation := 0;
- txtTop :=middleY-(txtH div 2);
- if (rGlyphLayout <> glNone) then
- begin
- if (rTextLayout = tlCenter)
- then dec(AWidth, rGlyph.Glyph.Width*2+4)
- else dec(AWidth, rGlyph.Glyph.Width+2)
- end;
- CalcCuttedCaption(AWidth);
- Case rTextLayout of
- tlLeft :begin
- txtLeft :=paintRect.Left+4;
- if (rGlyphLayout = glLeft)
- then inc(txtLeft, rGlyph.Glyph.Width+2);
- end;
- tlRight:begin
- txtLeft :=paintRect.Left+AWidth-txtWidth;
- if (rGlyphLayout = glLeft)
- then inc(txtLeft, rGlyph.Glyph.Width+2);
- end;
- tlCenter:begin
- txtLeft :=middleX-(txtWidth div 2);
- end;
- end;
- //Disabled Position
- DTop :=txtTop+1;
- DLeft :=txtLeft+1;
- end;
- akLeft : begin
- //Vertically from Bottom to Top
- Canvas.Font.Orientation := 900;
- txtLeft:=middleX-(txtH div 2);
- if (rGlyphLayout <> glNone) then
- begin
- if (rTextLayout = tlCenter)
- then dec(AHeight, rGlyph.Glyph.Height*2+4)
- else dec(AHeight, rGlyph.Glyph.Height+2)
- end;
- //Vertically the Max Width is Height
- CalcCuttedCaption(AHeight);
- Case rTextLayout of
- tlLeft :begin //To Bottom of the ClientRect
- txtTop :=paintRect.Top+AHeight-2;
- if (rGlyphLayout = glRight)
- then inc(txtTop, rGlyph.Glyph.Height+2);
- end;
- tlRight:begin //To Top of the ClientRect
- txtTop :=paintRect.Top+txtWidth+2;
- if (rGlyphLayout = glRight)
- then inc(txtTop, rGlyph.Glyph.Height+2);
- end;
- tlCenter:begin
- txtTop :=middleY+(txtWidth div 2);
- end;
- end;
- //Disabled Position
- DTop :=txtTop-1;
- DLeft :=txtLeft+1;
- end;
- akRight : begin
- //Vertically from Top to Bottom
- Canvas.Font.Orientation := -900;
- txtLeft:=middleX+(txtH div 2)+1; //+1 because is better centered
- if (rGlyphLayout <> glNone) then
- begin
- if (rTextLayout = tlCenter)
- then dec(AHeight, rGlyph.Glyph.Height*2+4)
- else dec(AHeight, rGlyph.Glyph.Height+2)
- end;
- CalcCuttedCaption(AHeight);
- Case rTextLayout of
- tlLeft :begin //To Top of the ClientRect
- txtTop :=paintRect.Top+4;
- if (rGlyphLayout = glLeft)
- then inc(txtTop, rGlyph.Glyph.Height+2);
- end;
- tlRight:begin //To Bottom of the ClientRect
- txtTop :=paintRect.Top+AHeight-txtWidth;
- if (rGlyphLayout = glLeft)
- then inc(txtTop, rGlyph.Glyph.Height+2);
- end;
- tlCenter:begin
- txtTop :=middleY-(txtWidth div 2);
- end;
- end;
- //Disabled Position
- DTop :=txtTop+1;
- DLeft :=txtLeft-1;
- end;
- end;
- //Re Test here because we may not have space to draw the text, so now can be empty
- if (xCaption <> '') then
- begin
- if (FState = bsDisabled)
- then begin
- Canvas.Font.Color := clBtnHighlight;
- Canvas.TextOut(DLeft, DTop, xCaption);
- Canvas.Font.Color := clBtnShadow;
- end
- else Canvas.Font.Color := Font.Color;
- Canvas.Brush.Style:=bsClear;
- Canvas.TextOut(txtLeft, txtTop, xCaption);
- end
- else txtWidth:=0;
- end;
- procedure DrawLines;
- var
- d1, d2, d3, d4, dx :Integer;
- isVertical :Boolean;
- procedure calc_d(txtL, txtR, glyphL, glyphR :Integer);
- begin
- if (txtWidth > 0)
- then Case rTextLayout of
- tlLeft: begin
- d1 :=txtR;
- if (rGlyphLayout = glRight)
- then d2 :=glyphL;
- end;
- tlCenter:begin
- d2 :=txtL;
- d3 :=txtR;
- if (rGlyphLayout = glLeft)
- then d1 :=glyphR
- else if (rGlyphLayout = glRight)
- then d4 :=glyphL;
- end;
- tlRight:begin
- d2 :=txtL;
- if (rGlyphLayout = glLeft)
- then d1 :=glyphR;
- end;
- end
- else if (rGlyphLayout = glLeft)
- then d1 :=glyphR
- else if (rGlyphLayout = glRight)
- then d2 :=glyphL;
- end;
- procedure DrawALine(pCenterX, pCenterY :Integer);
- begin
- inc(d2); inc(d4); //LineTo don't paint the last Pixel
- if isVertical
- then begin
- //Avoid go outside the Box
- pCenterX :=EnsureRange(pCenterX, 0, paintRect.Right-2);
- Canvas.Pen.Color := {$ifdef DEBUG_PAINT} clLime {$else} xHColor {$endif};
- Canvas.MoveTo(pCenterX, d1);
- Canvas.LineTo(pCenterX, d2);
- if (d3 > -1) then
- begin
- Canvas.MoveTo(pCenterX, d3);
- Canvas.LineTo(pCenterX, d4);
- end;
- Canvas.Pen.Color := {$ifdef DEBUG_PAINT} clGreen {$else} xSColor {$endif};
- Canvas.MoveTo(pCenterX+1, d1+1);
- Canvas.LineTo(pCenterX+1, d2);
- if (d3 > -1) then
- begin
- Canvas.MoveTo(pCenterX+1, d3+1);
- Canvas.LineTo(pCenterX+1, d4);
- end;
- end
- else begin
- pCenterY :=EnsureRange(pCenterY, 0, paintRect.Bottom-2);
- Canvas.Pen.Color :={$ifdef DEBUG_PAINT} clLime {$else} xHColor {$endif};
- Canvas.MoveTo(d1, pCenterY);
- Canvas.LineTo(d2, pCenterY);
- if (d3 > -1) then
- begin
- Canvas.MoveTo(d3, pCenterY);
- Canvas.LineTo(d4, pCenterY);
- end;
- Canvas.Pen.Color :={$ifdef DEBUG_PAINT} clGreen {$else} xSColor {$endif};
- Canvas.MoveTo(d1+1, pCenterY+1);
- Canvas.LineTo(d2, pCenterY+1);
- if (d3 > -1) then
- begin
- Canvas.MoveTo(d3+1, pCenterY+1);
- Canvas.LineTo(d4, pCenterY+1);
- end;
- end;
- dec(d2); dec(d4); //return to the real Pixels
- end;
- begin
- d3 :=-1;
- isVertical :=(FButtonPosition in [akLeft, akRight]);
- //Assign to (d1-d2) Line All the space
- if isVertical
- then begin
- d1 :=paintRect.Top;
- d2 :=paintRect.Bottom-1;
- end
- else begin
- d1 :=paintRect.Left;
- d2 :=paintRect.Right-1;
- end;
- //Calculate the (d1-d2) (d3-d4) Lines between the Glyph and the Text elements
- if (rStyle in [bbsLine, bbsLineDouble]) then
- begin
- d4 :=d2;
- if isVertical
- then begin
- if (FButtonPosition = akRight)
- then calc_d(txtTop-3, txtTop+txtWidth+2, glyphTop-3, glyphTop+rGlyph.Glyph.Height+2)
- else begin
- //Only in this case (akLeft) the point coordinate is from bottom to top
- d1 :=paintRect.Bottom-1;
- d2 :=paintRect.Top;
- d4 :=d2;
- calc_d(txtTop+2, txtTop-txtWidth-3, glyphTop+rGlyph.Glyph.Height+2, glyphTop-3);
- //Exchange the values for Shadow coerence
- dx :=d1; d1 :=d2; d2 :=dx;
- if (d3 > -1) then begin dx :=d3; d3 :=d4; d4 :=dx; end;
- end;
- end
- else calc_d(txtLeft-3, txtLeft+txtWidth+2, glyphLeft-3, glyphLeft+rGlyph.Glyph.Width+2);
- end;
- //Draw the Lines
- Canvas.Pen.Style:=psSolid;
- Canvas.Pen.Width:=1;
- Case rStyle of
- bbsLine: DrawALine(middleX, middleY);
- bbsLineDouble: begin
- DrawALine(middleX-2, middleY-2);
- DrawALine(middleX+2, middleY+2);
- end;
- bbsLineTop: DrawALine(paintRect.Left, paintRect.Top);
- bbsLineBottom: DrawALine(paintRect.Right-2, paintRect.Bottom-2);
- bbsLineDoubleTop: begin
- DrawALine(paintRect.Left, paintRect.Top);
- DrawALine(paintRect.Left+3, paintRect.Top+3);
- end;
- bbsLineDoubleBottom: begin
- DrawALine(paintRect.Right-5, paintRect.Bottom-5);
- DrawALine(paintRect.Right-2, paintRect.Bottom-2);
- end;
- end;
- end;
- begin
- paintRect :=GetClientRect;
- {$ifdef DEBUG_PAINT}
- Canvas.Brush.Color:=clYellow;
- Canvas.Brush.Style:=bsSolid;
- Canvas.FillRect(paintRect);
- {$endif}
- middleY :=paintRect.Top+((paintRect.Bottom-paintRect.Top) div 2);
- middleX :=paintRect.Left+((paintRect.Right-paintRect.Left) div 2);
- FButtonPosition :=TBCExpandPanel(Owner).FButtonPosition;
- FCollapsed :=TBCExpandPanel(Owner).FCollapsed;
- Rounded :=not(FCollapsed) and TBCExpandPanel(Owner).rBevelRounded;
- if FCollapsed
- then xColor :=Self.Color
- else xColor :=rColorExpanded;
- xCaption :=Caption;
- Case FState of
- Buttons.bsHot:begin
- if (rColorHighlight = clDefault)
- then xHColor :=GetHighlightColor(xColor, 120)
- else xHColor :=rColorHighlight;
- if (rColorShadow = clDefault)
- then xSColor :=GetShadowColor(xColor, 40)
- else xSColor :=rColorShadow;
- xColor :=GetHighlightColor(xColor, 20);
- drawBtn(bvRaised);
- end;
- Buttons.bsDown:begin
- if (rColorHighlight = clDefault)
- then xHColor :=GetHighlightColor(xColor, 60)
- else xHColor :=rColorHighlight;
- if (rColorShadow = clDefault)
- then xSColor :=GetShadowColor(xColor, 60)
- else xSColor :=rColorShadow;
- xColor :=GetHighlightColor(xColor, 20);
- drawBtn(bvLowered);
- end;
- else begin
- if (FState = bsDisabled)
- then xColor :=GrayScale(xColor);
- if Flat
- then xHColor :=xColor
- else if (rColorHighlight = clDefault)
- then xHColor :=GetHighlightColor(xColor, 60)
- else xHColor :=rColorHighlight;
- if (rColorShadow = clDefault)
- then xSColor :=GetShadowColor(xColor, 60)
- else xSColor :=rColorShadow;
- if Flat
- then drawBtn(bvSpace)
- else drawBtn(bvRaised);
- end;
- end;
- if (rGlyphLayout <> glNone)
- then drawGlyph(glyphTop, glyphLeft)
- else begin
- glyphTop :=0;
- glyphLeft:=0;
- end;
- if (rTextLayout <> tlNone) and (xCaption <> '')
- then drawText
- else txtWidth:=0;
- if (rStyle in [bbsLine..bbsLineDoubleBottom])
- then DrawLines;
- end;
- procedure TBCBoundButton.Loaded;
- begin
- inherited Loaded;
- if not(csDesigning in ComponentState) then
- begin
- //IF Used Outside TBCExpandPanel
- if not(Owner is TBCExpandPanel)
- then BuildGlyphs;
- end;
- end;
- constructor TBCBoundButton.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Color :=clSkyBlue;
- rColorExpanded := RGBToColor(23, 136, 248);
- rColorHighlight :=clDefault;
- rColorShadow :=clDefault;
- rGlyphLayout :=glNone;
- rGlyphKind :=gkArrows;
- rTextLayout :=tlLeft;
- Flat :=False;
- rStyle :=bbsButton;
- rTabWidth :=-50;
- //Why FGlyph is Private in ancestor?????
- rGlyph := TButtonGlyph.Create;
- rGlyph.IsDesigning := csDesigning in ComponentState;
- rGlyph.ShowMode := gsmAlways;
- rGlyphExpanded :=TBitmap.Create;
- rGlyphExpanded.Transparent := True;
- rGlyphCollapsed :=TBitmap.Create;
- rGlyphCollapsed.Transparent := True;
- rUserGlyphExpanded :=TBitmap.Create;
- rUserGlyphExpanded.Transparent := True;
- rUserGlyphCollapsed :=TBitmap.Create;
- rUserGlyphCollapsed.Transparent := True;
- SetSubComponent((Owner is TBCExpandPanel));
- // ControlStyle := ControlStyle + [csNoFocus, csNoDesignSelectable];
- end;
- destructor TBCBoundButton.Destroy;
- begin
- FreeAndNil(rGlyphExpanded);
- FreeAndNil(rGlyphCollapsed);
- FreeAndNil(rUserGlyphExpanded);
- FreeAndNil(rUserGlyphCollapsed);
- FreeAndNil(rGlyph);
- inherited Destroy;
- end;
- {TBCExpandPanels}
- constructor TBCExpandPanels.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- PanelArray := TList.Create;
- FCollapseKind := akTop;
- FButtonPosition := akTop;
- FButtonGlyphKind :=gkArrows;
- FButtonGlyphLayout :=glNone;
- FButtonStyle :=bbsButton;
- FButtonTabWidth :=-50;
- FButtonTextLayout :=tlLeft;
- FArrangeKind := akTop;
- FUseFixedSize := False;
- FUseClientSize := False;
- FFixedSize := 400;
- FAutoCollapseIfTooHigh := False;
- FAbove := 10;
- FOrthogonalAbove := 10;
- FOrthogonalSize := 200;
- end;
- destructor TBCExpandPanels.Destroy;
- var
- i: integer;
- begin
- for I := PanelArray.Count - 1 downto 0 do
- PanelArray.Delete(i);
- PanelArray.Free;
- PanelArray := nil;
- inherited Destroy;
- end;
- procedure TBCExpandPanels.AddPanel(rollout: TBCExpandPanel);
- begin
- InsertPanel(PanelArray.Count, rollout);
- end;
- procedure TBCExpandPanels.InsertPanel(idx: integer; rollout: TBCExpandPanel);
- begin
- if Count <= 0 then
- begin
- FAbove := RelevantAbove(rollout);
- FOrthogonalAbove := RelevantOrthogonalAbove(rollout);
- FOrthogonalSize := RelevantOrthogonalSize(rollout);
- end
- else
- begin
- WriteRelevantAbove(rollout, FAbove);
- WriteRelevantOrthogonalAbove(rollout, FOrthogonalAbove);
- WriteRelevantOrthogonalSize(rollout, FOrthogonalSize);
- end;
- with rollout do
- begin
- Tag := Idx;
- FButton.Tag := Idx;
- FButton.OnMouseMove := @RollOut1MouseMove;
- InternalOnAnimate := @RollOutOnAnimate;
- end;
- PanelArray.Insert(idx, rollout);
- if FBehaviour <> EPMultipanel then
- HotTrackSetActivePanel(0); //damit das erste ausgeklappt ist
- ArrangePanels;
- MakeCorrectButtonClickPointers;
- end;
- function TBCExpandPanels.DeltePanel(aname: string): boolean;
- var
- i: integer;
- begin
- Result := False;
- for i := 0 to PanelArray.Count - 1 do
- if TBCExpandPanel(PanelArray[i]).Name = aname then
- begin
- PanelArray.Delete(i);
- Result := True;
- break;
- end;
- ArrangePanels;
- end;
- function TBCExpandPanels.DeltePanel(idx: integer): boolean;
- begin
- Result := False;
- if (idx >= 0) and (idx <= PanelArray.Count - 1) then
- begin
- PanelArray.Delete(idx);
- Result := True;
- end;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.DelteLastPanel;
- begin
- if (PanelArray.Count >= 1) then
- PanelArray.Delete(PanelArray.Count - 1);
- ArrangePanels;
- end;
- procedure TBCExpandPanels.DelLastPanel;
- begin
- PanelArray.Delete(PanelArray.Count - 1);
- end;
- function TBCExpandPanels.RelevantAbove(comp: TControl): integer;
- begin
- case FArrangeKind of
- akLeft: Result := comp.Left;
- akTop: Result := comp.Top;
- end;
- end;
- function TBCExpandPanels.RelevantOrthogonalAbove(comp: TControl): integer;
- begin
- case FArrangeKind of
- akTop: Result := comp.Left;
- akLeft: Result := comp.Top;
- end;
- end;
- function TBCExpandPanels.RelevantSize(comp: TControl): integer;
- begin
- case FArrangeKind of
- akLeft: Result := comp.Width;
- akTop: Result := comp.Height;
- end;
- end;
- function TBCExpandPanels.RelevantOrthogonalSize(comp: TControl): integer;
- begin
- case FArrangeKind of
- akLeft: Result := comp.Height;
- akTop: Result := comp.Width;
- end;
- end;
- procedure TBCExpandPanels.setButtonGlyphKind(AValue: TGlyphKind);
- var
- i: Integer;
- begin
- if (FButtonGlyphKind <> AValue) then
- begin
- FButtonGlyphKind:=AValue;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).Button.GlyphKind := AValue;
- end;
- end;
- procedure TBCExpandPanels.setButtonGlyphLayout(AValue: TGlyphLayout);
- var
- i: Integer;
- begin
- if (FButtonGlyphLayout <> AValue) then
- begin
- FButtonGlyphLayout:=AValue;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).Button.GlyphLayout := AValue;
- end;
- end;
- procedure TBCExpandPanels.setButtonStyle(AValue: TBCBoundButtonStyle);
- var
- i: Integer;
- begin
- if (FButtonStyle <> AValue) then
- begin
- FButtonStyle:=AValue;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).Button.Style := AValue;
- end;
- end;
- procedure TBCExpandPanels.SetButtonTabWidth(AValue: Integer);
- var
- i: Integer;
- begin
- if (FButtonTabWidth <> AValue) then
- begin
- FButtonTabWidth:=AValue;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).Button.TabWidth := AValue;
- end;
- end;
- procedure TBCExpandPanels.setButtonTextLayout(AValue: TTextLayout);
- var
- i: Integer;
- begin
- if (FButtonTextLayout <> AValue) then
- begin
- FButtonTextLayout:=AValue;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).Button.TextLayout := AValue;
- end;
- end;
- procedure TBCExpandPanels.WriteRelevantAbove(comp: TBCExpandPanel; above: integer);
- begin
- case FArrangeKind of
- akLeft: comp.Left := above;
- akTop: comp.Top := above;
- end;
- end;
- procedure TBCExpandPanels.WriteRelevantSize(comp: TBCExpandPanel; size: integer);
- begin
- case FArrangeKind of
- akLeft: comp.Width := size;
- akTop: comp.Height := size;
- end;
- end;
- procedure TBCExpandPanels.WriteRelevantOrthogonalSize(comp: TBCExpandPanel; size: integer);
- begin
- case FArrangeKind of
- akLeft: comp.Height := size;
- akTop: comp.Width := size;
- end;
- end;
- procedure TBCExpandPanels.WriteRelevantOrthogonalAbove(comp: TBCExpandPanel; size: integer);
- begin
- case FArrangeKind of
- akLeft: comp.Top := size;
- akTop: comp.Left := size;
- end;
- end;
- procedure TBCExpandPanels.setArrangeKind(Value: TAnchorKind);
- begin
- case Value of //that is mean, but I haven't implemented the bottom and right yet....
- akRight: Value := akLeft;
- akBottom: Value := akTop;
- end;
- if FArrangeKind = Value then
- exit;
- FArrangeKind := Value;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setButtonPosition(Value: TAnchorKind);
- var
- i: integer;
- begin
- if FButtonPosition = Value then
- exit;
- FButtonPosition := Value;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).ButtonPosition := Value;
- end;
- procedure TBCExpandPanels.setCollapseKind(Value: TAnchorKind);
- var
- i: integer;
- begin
- if FCollapseKind = Value then
- exit;
- FCollapseKind := Value;
- for i := 0 to PanelArray.Count - 1 do
- Panel(i).CollapseKind := Value;
- end;
- procedure TBCExpandPanels.setUseClientSize(Value: boolean);
- begin
- FUseClientSize := Value;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setUseFixedSize(Value: boolean);
- begin
- if FUseFixedSize = Value then
- exit;
- FUseFixedSize := Value;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setAutoCollapseIfTooHigh(Value: boolean);
- begin
- if FAutoCollapseIfTooHigh = Value then
- exit;
- FAutoCollapseIfTooHigh := Value;
- if FAutoCollapseIfTooHigh then
- CollapseIfTooHigh;
- end;
- procedure TBCExpandPanels.setFixedSize(Value: integer);
- var
- r: real;
- begin
- if FFixedSize = Value then
- exit;
- r := Value;
- korrigiere(r, 20, 10000);
- FFixedSize := round(r);
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setOrthogonalAbove(Value: integer);
- begin
- if FOrthogonalAbove = Value then
- exit;
- FOrthogonalAbove := Value;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setAbove(Value: integer);
- begin
- if FAbove = Value then
- exit;
- FAbove := Value;
- ArrangePanels;
- end;
- procedure TBCExpandPanels.setOrthogonalSize(Value: integer);
- var
- i: integer;
- begin
- FOrthogonalSize := Value;
- for I := 0 to PanelArray.Count - 1 do
- WriteRelevantOrthogonalSize(TBCExpandPanel(PanelArray[i]), FOrthogonalSize);
- end;
- procedure TBCExpandPanels.setBehaviour(Value: TBCExpandPanelsBehaviour);
- var
- i: integer;
- isAlreadyOneExpand: boolean;
- begin
- isAlreadyOneExpand := False;
- FBehaviour := Value;
- MakeCorrectButtonClickPointers;
- // look if more then one is open
- for I := 0 to PanelArray.Count - 1 do
- with TBCExpandPanel(PanelArray[i]) do
- if (Behaviour <> EPMultipanel) and not Collapsed then //leave only the first open, if it is not MultiPanel
- if not isAlreadyOneExpand then
- isAlreadyOneExpand := True
- else
- Collapsed := True;
- end;
- procedure TBCExpandPanels.MakeCorrectButtonClickPointers;
- var
- i: integer;
- begin
- // set correct pointers
- for I := 0 to PanelArray.Count - 1 do
- with TBCExpandPanel(PanelArray[i]) do
- if FBehaviour <> EPMultipanel then
- EPManagesCollapsing := @RollOutClick
- else
- EPManagesCollapsing := nil;
- end;
- procedure TBCExpandPanels.CollapseIfTooHigh;
- var
- i, h, max: integer;
- tempanimated: boolean;
- begin
- if Count <= 1 then
- exit;
- h := RelevantAbove(Panel(0));
- max := RelevantSize(Panel(0).Parent);
- for i := 0 to Count - 1 do
- if h + RelevantSize(Panel(i)) > max then
- with Panel(i) do
- begin
- tempanimated := Animated;
- Animated := False;
- Collapsed := True;
- Animated := tempanimated;
- h := h + TBCExpandPanel(Panel(i)).ButtonSize;
- end
- else
- h := h + RelevantSize(Panel(i));
- end;
- procedure TBCExpandPanels.RollOutOnAnimate(Sender: TObject; deltaLeft, deltaTop, deltaWidth, deltaHeight: integer);
- var
- idx, i, size: integer;
- begin
- idx := PanelArray.IndexOf(Sender);
- for i := idx + 1 to PanelArray.Count - 1 do
- begin
- size := RelevantAbove(TBCExpandPanel(PanelArray[i]));
- case FArrangeKind of
- akTop: size := size + deltaTop + deltaHeight;
- akLeft: size := size + deltaLeft + deltaWidth;
- end;
- WriteRelevantAbove(TBCExpandPanel(PanelArray[i]), size);
- end;
- end;
- //procedure TBCExpandPanels.SetCorrectSize;
- //const plus=1; //extra Anstand
- //var
- // i, exSize,
- // countexpanded,
- // SumSize, closedSize:Integer;
- //begin
- // if PanelArray.Count<=0 then
- // exit;
- // SumSize:=FFixedSize;
- // if FUseClientSize then
- // SumSize:=TBCExpandPanel(PanelArray[0]).Parent.Height;
- // countexpanded:=0;
- // closedSize:=0;
- // for I := 0 to PanelArray.count-1 do
- // with TBCExpandPanel(PanelArray[i]) do
- // begin
- // if not Collapsed and not Animating //error producer!!! animating does not neccessairily mean that it is expanding
- // or Collapsed and Animating then
- // inc(countexpanded)
- // else
- // closedSize:=closedSize+Height;
- // end;
- // exSize:=SumSize- FTop- closedSize;
- // case Behaviour of
- // EPMultipanel:
- // if countexpanded>0 then
- // exSize:=trunc(exSize/countexpanded)
- // else
- // exSize:=400;
- // end;
- // for I := 0 to PanelArray.count-1 do
- // with TBCExpandPanel(PanelArray[i]) do
- // begin
- // if not FUseFixedSize and not FUseClientSize then
- // ExpandedSize:=200
- // else
- // ExpandedSize:=exSize;
- // end;
- //end;
- {==============================================================================
- Procedure: ArrangePanels
- Belongs to: TBCExpandPanels
- Result: None
- Parameters:
- Description:
- ==============================================================================}
- procedure TBCExpandPanels.ArrangePanels;
- const
- plus = 1; //extra Anstand
- var
- i, t: integer;
- begin
- if Count <= 0 then
- exit;
- //left setzen!!!
- // SetCorrectSize;
- t := FAbove + plus;
- for I := 0 to PanelArray.Count - 1 do
- begin
- if not TBCExpandPanel(PanelArray[i]).Visible then
- continue;
- WriteRelevantAbove(TBCExpandPanel(PanelArray[i]), t);
- WriteRelevantOrthogonalAbove(TBCExpandPanel(PanelArray[i]), OrthogonalAbove);
- t := t + plus + self.RelevantSize(TBCExpandPanel(PanelArray[i]));
- end;
- if FAutoCollapseIfTooHigh then
- CollapseIfTooHigh;
- if Assigned(FOnArrangePanels) then
- FOnArrangePanels(Self);
- end;
- function TBCExpandPanels.Count: integer;
- begin
- Result := PanelArray.Count;
- end;
- function TBCExpandPanels.Panel(idx: integer): TBCExpandPanel;
- begin
- if idx < Count then
- Result := TBCExpandPanel(PanelArray.Items[idx])
- else
- Result := nil;
- end;
- {==============================================================================
- Procedure: RollOutClick
- Belongs to: TBCExpandPanels
- Result: None
- Parameters:
- Sender : TObject =
- Description:
- ==============================================================================}
- procedure TBCExpandPanels.RollOutClick(Sender: TObject);
- begin
- if (Behaviour <> EPMultipanel) then
- HotTrackSetActivePanel(TBCBoundButton(Sender).Tag);
- end;
- procedure TBCExpandPanels.HotTrackSetActivePanel(Value: integer);
- var
- i: integer;
- begin
- for I := PanelArray.Count - 1 downto 0 do
- TBCExpandPanel(PanelArray[i]).Collapsed := Value <> i;
- end;
- procedure TBCExpandPanels.RollOut1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
- begin
- if (Behaviour = EPHotMouse) and (TBCExpandPanel(PanelArray[TBCBoundButton(Sender).Tag]).Collapsed) then
- HotTrackSetActivePanel(TBCBoundButton(Sender).Tag);
- end;
- function TBCExpandPanels.IdxOfPanel(aname: string): integer;
- var
- i: integer;
- begin
- Result := -1; // is not here
- for i := 0 to PanelArray.Count - 1 do
- if TBCExpandPanel(PanelArray[i]).Name = aname then
- begin
- Result := i;
- break;
- end;
- end;
- { TBCExpandPanel }
- procedure TBCExpandPanel.setCollapsed(Value: boolean);
- begin
- {$ifopt D+}
- debugln('TBCExpandPanel.setCollapsed '+BoolToStr(Collapsed, True));
- {$endif}
- if FCollapsed = Value then
- exit;
- FCollapsed := Value;
- if not(csLoading in ComponentState)
- then if Value
- then DoCollapse
- else DoExpand;
- end;
- procedure TBCExpandPanel.SetRelevantSize(comp: TControl; AKind: TAnchorKind; ASize: Integer);
- begin
- case AKind of
- akTop, akBottom: comp.Height :=ASize;
- akLeft, akRight: comp.Width :=ASize;
- end;
- end;
- function TBCExpandPanel.RelevantSize(comp: TControl; akind: TAnchorKind): integer;
- begin
- case akind of
- akTop, akBottom: Result := comp.Height;
- akLeft, akRight: Result := comp.Width;
- end;
- end;
- function TBCExpandPanel.RelevantOrthogonalSize(comp: TControl; akind: TAnchorKind): integer;
- begin
- case akind of
- akTop, akBottom: Result := comp.Width;
- akLeft, akRight: Result := comp.Height;
- end;
- end;
- function TBCExpandPanel.DeltaCoordinates(deltaMove, deltaSize: integer): TRect;
- begin
- Result := Rect(0, 0, 0, 0);
- case FCollapseKind of
- akTop: Result := Rect(0, 0, 0, deltaSize);
- akLeft: Result := Rect(0, 0, deltaSize, 0);
- akBottom: Result := Rect(0, deltaMove, 0, deltaSize);
- akRight: Result := Rect(deltaMove, 0, deltaSize, 0);
- end;
- end;
- procedure TBCExpandPanel.TimerAnimateSize(Sender: TObject);
- var
- step: real;
- originalsize, size: integer;
- deltaMove, deltaSize: integer;
- delta: TRect;
- vorzeichen: integer;
- begin
- deltaMove := 0;
- deltaSize := 0;
- StopCircleActions := False;
- FAnimating := True;
- step := FAnimationSpeed;
- Size := RelevantSize(Self, FCollapseKind);
- vorzeichen := Sign(TargetAnimationSize - RelevantSize(self, FCollapseKind)); // muss ich delta addieren oder muss ich delta abziehen
- originalsize := ExpandedSize;
- //One huge step if not animated
- if not FAnimated or not (ComponentState * [csLoading, csDesigning] = []) then
- step := abs(Size - TargetAnimationSize);
- //small steps if animated
- if FAnimated and (ComponentState * [csLoading, csDesigning] = []) then
- begin
- step := step * originalsize / 200;
- if step < 3 then
- step := 3;
- end;
- //now actually do something
- if Abs(Size - TargetAnimationSize) > 0 then
- begin
- if Abs(Size - TargetAnimationSize) < abs(step) then // if there is just a little bit left to go, set delta so it can go directly to the end size
- deltaSize := TargetAnimationSize - Size
- else
- deltaSize := vorzeichen * round(step);
- if (CollapseKind = akBottom) or (CollapseKind = akRight) then
- deltaMove := -deltaSize;
- delta := DeltaCoordinates(deltaMove, deltaSize);
- SetBounds(Left + delta.Left, Top + delta.Top, Width + delta.Right, Height + delta.Bottom);
- if assigned(FInternalOnAnimate) then
- FInternalOnAnimate(self, delta.Left, delta.Top, delta.Right, delta.Bottom);
- if assigned(FOnAnimate) then
- FOnAnimate(self, delta.Left, delta.Top, delta.Right, delta.Bottom);
- end;
- if Abs(Size - TargetAnimationSize) = 0 then //it's finished ( executes it NEXT time the timer activates!)
- begin
- Timer.Enabled := False;
- FAnimating := False;
- StopCircleActions := False;
- if assigned(EndProcedureOfAnimation) then
- EndProcedureOfAnimation;
- end;
- end;
- procedure TBCExpandPanel.EndTimerCollapse;
- begin
- if assigned(OnCollapse) then
- OnCollapse(self);
- UpdateAll;
- end;
- procedure TBCExpandPanel.EndTimerExpand;
- begin
- if assigned(OnExpand) then
- OnExpand(self);
- UpdateAll;
- end;
- procedure TBCExpandPanel.UpdateAll;
- begin
- Update;
- //FButton.Update;
- end;
- procedure TBCExpandPanel.setExpandedSize(Value: integer);
- begin
- {$ifopt D+}
- debugln('TBCExpandPanel.setExpandedSize');
- debugln(IntToStr(Value));
- {$endif}
- if (FExpandedSize = Value) then
- exit;
- FExpandedSize := Value;
- if not(csLoading in ComponentState) and not(FCollapsed)
- then Animate(FExpandedSize);
- end;
- function TBCExpandPanel.GetEnabled: Boolean;
- begin
- Result :=inherited Enabled;
- if (FButton.Enabled <> Result) //Paranoic Think
- then FButton.Enabled :=Result;
- end;
- procedure TBCExpandPanel.SetBevelColorHighlight(AValue: TColor);
- begin
- if (rBevelColorHighlight <> AValue) then
- begin
- rBevelColorHighlight := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCExpandPanel.SetBevelColorShadow(AValue: TColor);
- begin
- if (rBevelColorShadow <> AValue) then
- begin
- rBevelColorShadow := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCExpandPanel.SetBevelRounded(AValue: Boolean);
- begin
- if (rBevelRounded <> AValue) then
- begin
- rBevelRounded := AValue;
- if not(csLoading in ComponentState)
- then Invalidate;
- end;
- end;
- procedure TBCExpandPanel.SetEnabled(AValue: Boolean);
- begin
- inherited Enabled :=AValue;
- FButton.Enabled :=AValue;
- end;
- procedure TBCExpandPanel.setButtonSize(Value: integer);
- begin
- if FButtonSize = Value then
- exit;
- FButtonSize := Value;
- PositionButton;
- end;
- procedure TBCExpandPanel.SetBounds(ALeft, ATop, AWidth, AHeight: integer);
- begin
- inherited SetBounds(ALeft, ATop, AWidth, AHeight);
- if not Collapsed and not Animating and (ComponentState * [csLoading] = []) then
- FExpandedSize := RelevantSize(self, FCollapseKind);
- end;
- procedure TBCExpandPanel.setButtonPosition(Value: TAnchorKind);
- var
- wasanimated, wascollpased: boolean;
- begin
- if FButtonPosition = Value then
- exit;
- wasanimated := Animated;
- wascollpased := Collapsed;
- Animated := False;
- if Collapsed then
- Collapsed := False;
- FButtonPosition := Value;
- PositionButton;
- Collapsed := wascollpased;
- Animated := wasanimated;
- Invalidate;
- end;
- procedure TBCExpandPanel.setCollapseKind(Value: TAnchorKind);
- var
- wasanimated, wascollpased: boolean;
- begin
- if FCollapseKind = Value then
- exit;
- wasanimated := Animated;
- wascollpased := Collapsed;
- Animated := False;
- if Collapsed then
- Collapsed := False;
- FCollapseKind := Value;
- //switsch sizes
- case FCollapseKind of
- akLeft, akRight: FExpandedSize := Width;
- akTop, akBottom: FExpandedSize := Height;
- end;
- if not(csLoading in ComponentState) then
- begin
- FButton.BuildGlyphs;
- FButton.Invalidate;
- end;
- Collapsed := wascollpased;
- Animated := wasanimated;
- end;
- procedure TBCExpandPanel.setAnimationSpeed(Value: real);
- begin
- korrigiere(Value, 3, 1000);
- FAnimationSpeed := Value;
- end;
- procedure TBCExpandPanel.PositionButton;
- function ButtonRect: TRect;
- begin
- case FButtonPosition of
- akBottom, akTop: Result := Rect(0, 0, RelevantOrthogonalSize(self, FButtonPosition), FButtonSize);
- akLeft, akRight: Result := Rect(0, 0, FButtonSize, RelevantOrthogonalSize(self, FButtonPosition));
- end;
- //this must come after the thing above!!!
- // this moves the button to the bottom, or the right
- case FButtonPosition of
- akBottom: Result.Top := Result.Top + RelevantSize(self, FButtonPosition) - FButtonSize;
- akRight: Result.Left := Result.Left + RelevantSize(self, FButtonPosition) - FButtonSize;
- end;
- end;
- var
- new: TRect;
- begin
- if StopCircleActions or not(Assigned(FButton)) or (csLoading in ComponentState)
- then exit;
- StopCircleActions := True;
- new := ButtonRect;
- FButton.SetBounds(new.Left, new.Top, new.Right, new.Bottom);
- //set anchors
- case FButtonPosition of
- akBottom: FButton.Anchors := [akTop, akLeft, akBottom, akRight] - [akTop];
- akLeft: FButton.Anchors := [akTop, akLeft, akBottom, akRight] - [akRight];
- akTop: FButton.Anchors := [akTop, akLeft, akBottom, akRight] - [akBottom];
- akRight: FButton.Anchors := [akTop, akLeft, akBottom, akRight] - [akLeft];
- end;
- Invalidate;
- StopCircleActions := False;
- end;
- procedure TBCExpandPanel.ButtonClick(Sender: TObject);
- begin
- if Assigned(FEPManagesCollapsing) then
- FEPManagesCollapsing(self)
- else
- Collapsed := not Collapsed;
- if Assigned(OnButtonClick) then
- OnButtonClick(self);
- end;
- procedure TBCExpandPanel.Animate(aTargetSize: integer);
- var
- storAnimated: boolean;
- begin
- if (FAnimating) then
- begin
- // FinishLastAnimationFast
- storAnimated := FAnimated;
- FAnimated := False;
- TimerAnimateSize(self);
- FAnimated := storAnimated;
- end;
- // Now do animation
- TargetAnimationSize := aTargetSize;
- if (ComponentState * [csLoading, csDesigning] = []) and FAnimated then
- begin
- Timer.Enabled := True;
- Timer.OnTimer := @TimerAnimateSize;
- //EndProcedureOfAnimation := nil; //On Collapse then EndTimerCollapse never Executed
- end
- else
- begin
- TimerAnimateSize(self);
- TimerAnimateSize(self);
- end;
- end;
- procedure TBCExpandPanel.SetTextAlignment(AValue: TAlignment);
- begin
- if FTextAlignment=AValue then Exit;
- FTextAlignment:=AValue;
- Invalidate;
- end;
- procedure TBCExpandPanel.DoCollapse;
- var
- i :Integer;
- curControl: TControl;
- begin
- (* may work but is irrilevant because TSpeedButton is always on Bottom ????why?
- i :=0;
- while (i < ControlCount) do
- begin
- curControl :=Controls[i];
- if not(curControl is TBCBoundButton) then
- begin
- Self.SetChildZPosition(curControl, 0);
- end;
- inc(i)
- end;*)
- if assigned(OnPreCollapse) then
- OnPreCollapse(self);
- //FButton.Color := FCollapsedButtonColor;
- EndProcedureOfAnimation := @EndTimerCollapse;
- Animate(FButtonSize);
- {$ifopt D+}
- debugln('TBCExpandPanel.DoCollapse');
- debugln('FButtonSize ' + IntToStr(FButtonSize));
- {$endif}
- end;
- procedure TBCExpandPanel.DoExpand;
- begin
- if assigned(OnPreExpand) then
- OnPreExpand(self);
- // FButton.ControlStyle := FButton.ControlStyle + [csNoFocus, csNoDesignSelectable];
- // FButton.Parent:=self;
- //FButton.Color := FExpandedButtonColor;
- EndProcedureOfAnimation := @EndTimerExpand;
- Animate(FExpandedSize);
- {$ifopt D+}
- debugln('TBCExpandPanel.DoExpand');
- debugln('FExpandedSize ' + IntToStr(FExpandedSize));
- {$endif}
- end;
- procedure TBCExpandPanel.AdjustClientRect(var ARect: TRect);
- begin
- inherited AdjustClientRect(ARect);
- if Assigned(FButton) then
- case ButtonPosition of
- akTop:
- ARect.Top := ARect.Top + fButton.Height;
- akBottom:
- ARect.Bottom := ARect.Bottom - fButton.Height;
- akLeft:
- ARect.Left := ARect.Left + fButton.Width;
- akRight:
- ARect.Right := ARect.Right - fButton.Width;
- end;
- end;
- procedure TBCExpandPanel.Loaded;
- begin
- inherited Loaded;
- end;
- procedure TBCExpandPanel.CreateWnd;
- begin
- inherited CreateWnd;
- FButton.BuildGlyphs; //Button Loaded is called Before Self.Loaded and cannot Build Glyphs
- (* if (FCollapsed)
- then SetRelevantSize(Self, FButtonPosition, FButtonSize)
- else SetRelevantSize(Self, FButtonPosition, FExpandedSize); *)
- PositionButton;
- end;
- procedure TBCExpandPanel.Paint;
- var
- ARect: TRect;
- TS: TTextStyle;
- begin
- if not(FCollapsed) then
- begin
- ARect := GetClientRect;
- Case FButtonPosition of
- akTop: inc(ARect.Top, FButtonSize);
- akBottom: dec(ARect.Bottom, FButtonSize);
- akLeft: inc(ARect.Left, FButtonSize);
- akRight: dec(ARect.Right, FButtonSize);
- end;
- {$ifdef DEBUG_PAINT}
- Canvas.Brush.Color:=clRed;
- Canvas.Brush.Style:=bsSolid;
- Canvas.FillRect(ARect);
- {$endif}
- // if BevelOuter is set then draw a frame with BevelWidth
- if (BevelOuter <> bvNone)
- then if rBevelRounded
- then Frame3d_Rounded(Self.Canvas, ARect, BevelWidth, 5, 5, BevelOuter,
- rBevelColorShadow, rBevelColorHighlight, Color)
- else Self.Canvas.Frame3d(ARect, BevelWidth, BevelOuter);
- InflateRect(ARect, -BorderWidth, -BorderWidth);
- // if BevelInner is set then skip the BorderWidth and draw a frame with BevelWidth
- if (BevelInner <> bvNone)
- then if rBevelRounded
- then Frame3d_Rounded(Self.Canvas, ARect, BevelWidth, 5, 5, BevelInner,
- rBevelColorShadow, rBevelColorHighlight, Color)
- else Self.Canvas.Frame3d(ARect, BevelWidth, BevelInner);
- if (Self.Caption <> '') then
- begin
- TS := Canvas.TextStyle;
- TS.Alignment := BidiFlipAlignment(Self.TextAlignment, UseRightToLeftAlignment);
- if (BiDiMode <> bdLeftToRight)
- then TS.RightToLeft:= True;
- TS.Layout:= Graphics.tlCenter;
- TS.Opaque:= false;
- TS.Clipping:= false;
- TS.SystemFont:=Canvas.Font.IsDefault;
- if not(Enabled) then
- begin
- Canvas.Font.Color := clBtnHighlight;
- Types.OffsetRect(ARect, 1, 1);
- Self.Canvas.TextRect(ARect, ARect.Left, ARect.Top, Self.Caption, TS);
- Self.Canvas.Font.Color := clBtnShadow;
- Types.OffsetRect(ARect, -1, -1);
- end
- else Self.Canvas.Font.Color := Font.Color;
- Self.Canvas.TextRect(ARect,ARect.Left,ARect.Top, Self.Caption, TS);
- end;
- end;
- end;
- constructor TBCExpandPanel.Create(TheOwner: TComponent);
- begin
- StopCircleActions := True;
- inherited;
- FButtonSize := 27;
- FAnimated := True;
- FCollapseKind := akTop;
- FVisibleTotal := True;
- FCollapsed := False;
- FButtonPosition := akTop;
- FCollapsedButtonColor := clSkyBlue;
- FExpandedButtonColor := RGBToColor(23, 136, 248);
- rBevelColorHighlight:=clBtnHighlight;
- rBevelColorShadow:=clBtnShadow;
- rBevelRounded:=True;
- FExpandedSize := 200;
- Height := FExpandedSize;
- Width := 200;
- FAnimationSpeed := 20;
- Caption := '';
- Timer := TTimer.Create(self);
- Timer.Enabled := False;
- Timer.Name := 'Animationtimer';
- Timer.Interval := 20;
- FButton := TBCBoundButton.Create(self);
- with FButton do
- begin
- Parent := self;
- Name := 'Button';
- Caption := 'Caption';
- ControlStyle := ControlStyle + [csNoFocus, csNoDesignSelectable];
- FButton.OnClick := @self.ButtonClick;
- end;
- StopCircleActions := False;
- //may be only in CreateWnd but the button is greater by some pixels
- PositionButton;
- end;
- destructor TBCExpandPanel.Destroy;
- begin
- timer.Enabled := False;
- Timer.Free;
- if (ComponentState * [csLoading, csDesigning] = []) then
- FButton.Free; // bringt einen Fehler in der Designtime wenn ich das hier mache
- // FButton.Free; // bringt einen Fehler in der Designtime wenn ich das hier mache
- inherited Destroy;
- end;
- {$IFDEF FPC}
- procedure Register;
- begin
- RegisterComponents('BGRA Controls', [TBCExpandPanel, TBCExpandPanels]);
- end;
- {$ENDIF}
- initialization
- {$i BCExpandPanels.lrs}
- end.
|