diff --git a/components/jvcllaz/design/JvCtrls/images/images.txt b/components/jvcllaz/design/JvCtrls/images/images.txt index 0e69eec03..65c80bbcd 100644 --- a/components/jvcllaz/design/JvCtrls/images/images.txt +++ b/components/jvcllaz/design/JvCtrls/images/images.txt @@ -25,6 +25,7 @@ tjvgroupheader_200.png tjvrollout.png tjvrollout_150.png tjvrollout_200.png +tjvbehaviorlabel.bmp tjvcombolistbox.bmp tjvlookupautocomplete.bmp tjvinstalllabel.bmp diff --git a/components/jvcllaz/design/JvCtrls/images/tjvbehaviorlabel.bmp b/components/jvcllaz/design/JvCtrls/images/tjvbehaviorlabel.bmp new file mode 100644 index 000000000..a778da179 Binary files /dev/null and b/components/jvcllaz/design/JvCtrls/images/tjvbehaviorlabel.bmp differ diff --git a/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_150.png b/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_150.png new file mode 100644 index 000000000..98dfd5d99 Binary files /dev/null and b/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_150.png differ diff --git a/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_200.png b/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_200.png new file mode 100644 index 000000000..827b01e3e Binary files /dev/null and b/components/jvcllaz/design/JvCtrls/images/tjvmovablebevel_200.png differ diff --git a/components/jvcllaz/design/JvCtrls/jvbehaviorlabeleditor.pas b/components/jvcllaz/design/JvCtrls/jvbehaviorlabeleditor.pas new file mode 100644 index 000000000..e1c48aa51 --- /dev/null +++ b/components/jvcllaz/design/JvCtrls/jvbehaviorlabeleditor.pas @@ -0,0 +1,97 @@ +{----------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvBandsReg.PAS, released on 2002-05-26. + +The Initial Developer of the Original Code is John Doe. +Portions created by John Doe are Copyright (C) 2003 John Doe. +All Rights Reserved. + +Contributor(s): + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Known Issues: +-----------------------------------------------------------------------------} +// $Id$ + +unit JvBehaviorLabelEditor; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + PropEdits; +// DesignEditors, DesignIntf; + +type + TJvLabelBehaviorProperty = class(TStringProperty) + public + function AutoFill: Boolean; override; + procedure SetValue(const Value: string); override; + procedure GetValues(Proc: TGetStrProc); override; + function GetAttributes: TPropertyAttributes; override; + end; + +implementation + +uses + JvBehaviorLabel; //, JvDsgnTypes; + +function TJvLabelBehaviorProperty.AutoFill: Boolean; +begin + Result := inherited AutoFill; + // if you want to fix the flickering when double-clicking a value, uncomment line below: + // Result := False; +end; + +function TJvLabelBehaviorProperty.GetAttributes: TPropertyAttributes; +begin + Result := [paValueList, paRevertable, paMultiSelect]; +end; + +procedure TJvLabelBehaviorProperty.GetValues(Proc: TGetStrProc); +var + S: TStringList; + I: Integer; +begin + S := TStringList.Create; + try + GetRegisteredLabelBehaviorOptions(S); + S.Sort; + for I := 0 to S.Count -1 do + Proc(S[I]); + finally + S.Free; + end; +end; + +procedure TJvLabelBehaviorProperty.SetValue(const Value: string); +{ +var wp -- to do + List: IDesignerSelections; + LDesigner: IJvFormDesigner; + } +begin + inherited SetValue(Value); + { + List := CreateSelectionList; + Designer.GetSelections(List); + LDesigner := Designer; // keep Designer alive + LDesigner.SetSelections(nil); + LDesigner.SetSelections(List); + //Designer.Modified; + } +end; + +end. diff --git a/components/jvcllaz/design/JvCtrls/jvctrlsreg.pas b/components/jvcllaz/design/JvCtrls/jvctrlsreg.pas index 13688eec5..556d7d2c1 100644 --- a/components/jvcllaz/design/JvCtrls/jvctrlsreg.pas +++ b/components/jvcllaz/design/JvCtrls/jvctrlsreg.pas @@ -15,6 +15,7 @@ implementation uses Classes, Controls, ActnList, PropEdits, JvDsgnConsts, + JvBehaviorLabel, JvBehaviorLabelEditor, JvMovableBevel, JvRuler, JvGroupHeader, JvRollOut, JvHtControls, JvHint, JvHTHintForm, JvComboListBox, JvInstallLabel, JvOfficeColorPanel, @@ -23,11 +24,13 @@ uses procedure Register; begin RegisterComponents(RsPaletteJvclVisual, [ + TJvBehaviorLabel, TJvMovableBevel, TJvMovablePanel, TJvRuler, TJvGroupHeader, TJvRollOut, TJvHint, TJvHTLabel, TJvHTListbox, TJvHTCombobox, TJvComboListBox, TJvOfficeColorPanel, TJvLookupAutoComplete, TJvInstallLabel ]); + RegisterPropertyEditor(TypeInfo(TJvLabelBehaviorName), TJvBehaviorLabel, 'Behavior', TJvLabelBehaviorProperty); RegisterPropertyEditor(TypeInfo(TCaption), TJvHTLabel, 'Caption', TJvHintProperty); RegisterActions(RsJVCLActionsCategory, [TJvRollOutAction], nil); end; diff --git a/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpi b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpi new file mode 100644 index 000000000..f042cd9fd --- /dev/null +++ b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpi @@ -0,0 +1,81 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <BuildModes> + <Item Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="JvCtrlsLazR"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="JvBehaviorLabelDemo.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="JvBehaviorLblMainFrmU.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="JvBehaviorLblMainFrm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="..\..\bin\$(TargetCPU)-$(TargetOS)\JvBehaviorLabelDemo"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpr b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpr new file mode 100644 index 000000000..7886eacb8 --- /dev/null +++ b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLabelDemo.lpr @@ -0,0 +1,14 @@ +program JvBehaviorLabelDemo; + +uses + Interfaces, Forms, + JvBehaviorLblMainFrmU in 'JvBehaviorLblMainFrmU.pas' {JvBehaviorLblMainFrm}; + +{$R *.res} + +begin + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TJvBehaviorLblMainFrm, JvBehaviorLblMainFrm); + Application.Run; +end. diff --git a/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.lfm b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.lfm new file mode 100644 index 000000000..9e9eb66f6 --- /dev/null +++ b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.lfm @@ -0,0 +1,281 @@ +object JvBehaviorLblMainFrm: TJvBehaviorLblMainFrm + Left = 327 + Height = 304 + Top = 118 + Width = 572 + AutoSize = True + BorderStyle = bsDialog + Caption = 'JvBehaviorLabel Demo' + ClientHeight = 304 + ClientWidth = 572 + Color = clBtnFace + Font.Color = clWindowText + LCLVersion = '2.1.0.0' + object lblCodeBreaker: TJvBehaviorLabel + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = Owner + Left = 24 + Height = 22 + Top = 18 + Width = 259 + Behavior = 'CodeBreaker' + BehaviorOptions.DecodedText = 'ENTER THE MATRIX!' + BehaviorOptions.Interval = 5 + Alignment = taCenter + AutoSize = False + BorderSpacing.Left = 24 + BorderSpacing.Top = 18 + Caption = 'x6/yhjSkhHHDski"=90sd' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + ShowAccelChar = False + Transparent = False + end + object lblAppearing: TJvBehaviorLabel + AnchorSideLeft.Control = lblCodeBreaker + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = lblCodeBreaker + Left = 301 + Height = 22 + Top = 18 + Width = 259 + Behavior = 'Appearing' + BehaviorOptions.Delay = 10 + BehaviorOptions.Pixels = 2 + Alignment = taCenter + AutoSize = False + BorderSpacing.Left = 18 + BorderSpacing.Right = 24 + Caption = 'MAKE ME APPEAR' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object lblBlinking: TJvBehaviorLabel + AnchorSideLeft.Control = lblCodeBreaker + AnchorSideTop.Control = btnCodeBreak + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 22 + Top = 91 + Width = 259 + Behavior = 'Blinking' + BehaviorOptions.Interval = 220 + Alignment = taCenter + AutoSize = False + BorderSpacing.Top = 18 + Caption = 'BLINK ME' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object lblBouncing: TJvBehaviorLabel + AnchorSideLeft.Control = lblAppearing + AnchorSideTop.Control = lblBlinking + Left = 301 + Height = 22 + Top = 91 + Width = 259 + Behavior = 'Bouncing' + BehaviorOptions.Interval = 12 + BehaviorOptions.Pixels = 4 + Alignment = taCenter + AutoSize = False + Caption = 'BOUNCE ME' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object lblScrolling: TJvBehaviorLabel + AnchorSideLeft.Control = lblCodeBreaker + AnchorSideTop.Control = btnBlink + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 22 + Top = 164 + Width = 259 + Behavior = 'Scrolling' + BehaviorOptions.Interval = 70 + Alignment = taCenter + AutoSize = False + BorderSpacing.Top = 18 + Caption = 'SCROLL ME' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object lblSpecial: TJvBehaviorLabel + AnchorSideLeft.Control = lblAppearing + AnchorSideTop.Control = lblScrolling + Left = 301 + Height = 22 + Top = 164 + Width = 259 + Behavior = 'Special' + BehaviorOptions.Interval = 35 + Alignment = taCenter + AutoSize = False + Caption = 'I ACT IN A SPECIAL WAY' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object lblTyping: TJvBehaviorLabel + AnchorSideLeft.Control = lblCodeBreaker + AnchorSideTop.Control = btnScroll + AnchorSideTop.Side = asrBottom + Left = 24 + Height = 22 + Top = 237 + Width = 259 + Behavior = 'Typing' + Alignment = taCenter + AutoSize = False + BorderSpacing.Top = 18 + Caption = 'TYPE THE TEXT' + Color = clBlack + Font.CharSet = ANSI_CHARSET + Font.Color = clLime + Font.Height = -19 + Font.Name = 'Courier New' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object btnCodeBreak: TButton + AnchorSideLeft.Control = lblCodeBreaker + AnchorSideTop.Control = lblCodeBreaker + AnchorSideTop.Side = asrBottom + Left = 38 + Height = 25 + Top = 48 + Width = 80 + BorderSpacing.Left = 14 + BorderSpacing.Top = 8 + Caption = '&CodeBreaker' + OnClick = btnCodeBreakClick + TabOrder = 0 + end + object btnAppear: TButton + AnchorSideLeft.Control = lblAppearing + AnchorSideTop.Control = btnCodeBreak + Left = 315 + Height = 25 + Top = 48 + Width = 80 + BorderSpacing.Left = 14 + Caption = '&Appearing' + OnClick = btnAppearClick + TabOrder = 1 + end + object btnBlink: TButton + AnchorSideLeft.Control = btnCodeBreak + AnchorSideTop.Control = lblBlinking + AnchorSideTop.Side = asrBottom + Left = 38 + Height = 25 + Top = 121 + Width = 80 + BorderSpacing.Top = 8 + Caption = '&Blinking' + OnClick = btnBlinkClick + TabOrder = 2 + end + object btnBounce: TButton + AnchorSideLeft.Control = btnAppear + AnchorSideTop.Control = btnBlink + Left = 315 + Height = 25 + Top = 121 + Width = 80 + Caption = 'B&ouncing' + OnClick = btnBounceClick + TabOrder = 3 + end + object btnScroll: TButton + AnchorSideLeft.Control = btnCodeBreak + AnchorSideTop.Control = lblScrolling + AnchorSideTop.Side = asrBottom + Left = 38 + Height = 25 + Top = 194 + Width = 80 + BorderSpacing.Top = 8 + Caption = '&Scrolling' + OnClick = btnScrollClick + TabOrder = 4 + end + object btnSpecial: TButton + AnchorSideLeft.Control = btnAppear + AnchorSideTop.Control = btnScroll + Left = 315 + Height = 25 + Top = 194 + Width = 80 + Caption = 'S&pecial' + OnClick = btnSpecialClick + TabOrder = 5 + end + object btnType: TButton + AnchorSideLeft.Control = btnCodeBreak + AnchorSideTop.Control = lblTyping + AnchorSideTop.Side = asrBottom + Left = 38 + Height = 25 + Top = 267 + Width = 80 + BorderSpacing.Top = 8 + BorderSpacing.Bottom = 18 + Caption = '&Typing' + OnClick = btnTypeClick + TabOrder = 6 + end + object btnAll: TButton + AnchorSideLeft.Control = btnAppear + AnchorSideTop.Control = btnType + Left = 315 + Height = 25 + Top = 267 + Width = 80 + Caption = 'Do ''em all!' + OnClick = btnAllClick + TabOrder = 7 + end +end diff --git a/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.pas b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.pas new file mode 100644 index 000000000..98bf12330 --- /dev/null +++ b/components/jvcllaz/examples/JvBehaviorLabel/JvBehaviorLblMainFrmU.pas @@ -0,0 +1,135 @@ +{****************************************************************** + + JEDI-VCL Demo + + Copyright (C) 2002 Project JEDI + + Original author: + + You may retrieve the latest version of this file at the JEDI-JVCL + home page, located at http://jvcl.delphi-jedi.org + + The contents of this file are used with permission, subject to + the Mozilla Public License Version 1.1 (the "License"); you may + not use this file except in compliance with the License. You may + obtain a copy of the License at + http://www.mozilla.org/MPL/MPL-1_1Final.html + + Software distributed under the License is distributed on an + "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + +******************************************************************} + +unit JvBehaviorLblMainFrmU; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, JvBehaviorLabel; + +type + TJvBehaviorLblMainFrm = class(TForm) + lblCodeBreaker: TJvBehaviorLabel; + btnCodeBreak: TButton; + lblAppearing: TJvBehaviorLabel; + btnAppear: TButton; + lblBlinking: TJvBehaviorLabel; + btnBlink: TButton; + lblBouncing: TJvBehaviorLabel; + btnBounce: TButton; + lblScrolling: TJvBehaviorLabel; + btnScroll: TButton; + lblSpecial: TJvBehaviorLabel; + btnSpecial: TButton; + lblTyping: TJvBehaviorLabel; + btnType: TButton; + btnAll: TButton; + procedure btnCodeBreakClick(Sender: TObject); + procedure btnAppearClick(Sender: TObject); + procedure btnBlinkClick(Sender: TObject); + procedure btnBounceClick(Sender: TObject); + procedure btnScrollClick(Sender: TObject); + procedure btnSpecialClick(Sender: TObject); + procedure btnTypeClick(Sender: TObject); + procedure btnAllClick(Sender: TObject); + private + procedure DoCodeBreakStart(Sender:TObject); + procedure DoCodeBreakStop(Sender:TObject); + public + end; + +var + JvBehaviorLblMainFrm: TJvBehaviorLblMainFrm; + +implementation + +{$R *.lfm} + +procedure TJvBehaviorLblMainFrm.btnCodeBreakClick(Sender: TObject); +begin + Randomize; + lblCodeBreaker.OnStart := nil; + lblCodeBreaker.OnStop := nil; + if lblCodeBreaker.Caption = TJvLabelCodeBreaker(lblCodeBreaker.BehaviorOptions).DecodedText then + lblCodeBreaker.Caption := 'x6/yhjSkhHHDski"=90sd'; + // this might trigger the OnStart/OnStop events, so set to nil + lblCodeBreaker.BehaviorOptions.Active := not lblCodeBreaker.BehaviorOptions.Active; + lblCodeBreaker.OnStart := @DoCodeBreakStart; + lblCodeBreaker.OnStop := @DoCodeBreakStop; +end; + +procedure TJvBehaviorLblMainFrm.DoCodeBreakStart(Sender: TObject); +begin + lblCodeBreaker.Caption := 'BREAK THE CODE'; +end; + +procedure TJvBehaviorLblMainFrm.DoCodeBreakStop(Sender: TObject); +begin + ShowMessage('Congratulations! You''ve hacked the system!'); +end; + +procedure TJvBehaviorLblMainFrm.btnAppearClick(Sender: TObject); +begin + lblAppearing.Alignment := taCenter; + lblAppearing.BehaviorOptions.Active := not lblAppearing.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnBlinkClick(Sender: TObject); +begin + lblBlinking.BehaviorOptions.Active := not lblBlinking.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnBounceClick(Sender: TObject); +begin + lblBouncing.BehaviorOptions.Active := not lblBouncing.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnScrollClick(Sender: TObject); +begin + lblScrolling.BehaviorOptions.Active := not lblScrolling.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnSpecialClick(Sender: TObject); +begin + lblSpecial.BehaviorOptions.Active := not lblSpecial.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnTypeClick(Sender: TObject); +begin + lblTyping.BehaviorOptions.Active := not lblTyping.BehaviorOptions.Active; +end; + +procedure TJvBehaviorLblMainFrm.btnAllClick(Sender: TObject); +var i:integer; +begin + for i := 0 to ControlCount -1 do + if (Controls[i] <> btnAll) and (Controls[i] is TButton) then + TButton(Controls[i]).Click; +end; + +end. diff --git a/components/jvcllaz/packages/jvctrlslazr.lpk b/components/jvcllaz/packages/jvctrlslazr.lpk index 9f777d0e9..ae30cc611 100644 --- a/components/jvcllaz/packages/jvctrlslazr.lpk +++ b/components/jvcllaz/packages/jvctrlslazr.lpk @@ -17,7 +17,7 @@ Movable bevel and panel, ruler, exandable panel (RollOut), group header, hyperte "/> <License Value="The JVCL is released in accordance with the MPL 1.1 license. To get your own copy or read it, go to http://www.mozilla.org/MPL/MPL-1.1.html. "/> <Version Major="1" Release="6"/> - <Files Count="10"> + <Files Count="11"> <Item1> <Filename Value="..\run\JvCtrls\jvhint.pas"/> <UnitName Value="JvHint"/> @@ -58,6 +58,10 @@ Movable bevel and panel, ruler, exandable panel (RollOut), group header, hyperte <Filename Value="..\run\JvCtrls\jvofficecolorpanel.pas"/> <UnitName Value="JvOfficeColorPanel"/> </Item10> + <Item11> + <Filename Value="..\run\JvCtrls\jvbehaviorlabel.pas"/> + <UnitName Value="JvBehaviorLabel"/> + </Item11> </Files> <RequiredPkgs Count="3"> <Item1> diff --git a/components/jvcllaz/resource/jvctrlsreg.res b/components/jvcllaz/resource/jvctrlsreg.res index 3da02600b..ed0e9ca0a 100644 Binary files a/components/jvcllaz/resource/jvctrlsreg.res and b/components/jvcllaz/resource/jvctrlsreg.res differ diff --git a/components/jvcllaz/run/JvCtrls/jvbehaviorlabel.pas b/components/jvcllaz/run/JvCtrls/jvbehaviorlabel.pas new file mode 100644 index 000000000..d97681e7e --- /dev/null +++ b/components/jvcllaz/run/JvCtrls/jvbehaviorlabel.pas @@ -0,0 +1,1294 @@ +{----------------------------------------------------------------------------- +The contents of this file are subject to the Mozilla Public License +Version 1.1 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/MPL-1.1.html + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is: JvBehaviorLabel.PAS, released on 2003-03-24. + +The Initial Developer of the Original Code is Peter Thörnqvist [peter3 at sourceforge dot net] +Portions created by Peter Thörnqvist are Copyright (C) 2003 Peter Thörnqvist. +All Rights Reserved. + +Contributor(s): +Sébastien Buysse [sbuysse att buypin dott com] - original author of the merged components +Michael Beck [mbeck att bigfoot dott com]. + +You may retrieve the latest version of this file at the Project JEDI's JVCL home page, +located at http://jvcl.delphi-jedi.org + +Description: +* TJvBehaviorLabel is a merging of several label components in JVCL: JvSpecialLabel, + JvRealLabel, JvBouncingLabel, JvBlinkingLabel and JvAppearingLabel +* To change the way the label works, change the Behavior property: this in turn changes the + BehaviorOptions property to show only options available for the current Behavior. +* New behaviors can be added by creating a sub-class of TJvLabelBehavior, implement the + functionality and register it with RegisterLabelBehaviorOptions. + +Known Issues: +* Changing Behavior at design-time does not update the BehaviorOptions property unless + you collapse / expand the Options property in the OI manually. No known solution yet. SOLVED + +-----------------------------------------------------------------------------} +// $Id$ + +unit JvBehaviorLabel; + +{$mode objfpc}{$H+} + +interface + +uses + LCLIntf, Classes, //Windows, Messages, + Controls, StdCtrls, ExtCtrls; //, JvExStdCtrls; + +type + TJvCustomBehaviorLabel = class; + + TJvLabelBehaviorName = string; + TJvLabelScrollDirection = (sdLeftToRight, sdRightToLeft); + TJvAppearDirection = (drFromLeft, drFromRight, drFromTop, drFromBottom); + + // TJvLabelBehavior is the base class for label behaviors + // To create a new behavior, derive a new class from this base class, + // add appropriate published properties, override the Start, Stop and possibly the OwnerResize methods. + // Register the new behavior by calling RegisterLabelBehaviorOptions + TJvLabelBehavior = class(TPersistent) + private + FLabel: TJvCustomBehaviorLabel; + FTmpActive: Boolean; + FActive: Boolean; + FTemporary: Boolean; + procedure SetActive(const Value: Boolean); + protected + // Call Suspend to store the current state of the Active property and + // set Active to False. If the behavior was already inactive, Suspend does nothing + procedure Suspend; + // Call Resume to set the Active property to the state it was in before calling Suspend. + // Resume sets Active to True if it was True when Suspend was called. + // If Active was False before calling Suspend, Resume does nothing + procedure Resume; + // OwnerResize is called when the OwnerLabel is resized. Override this + // method to do special processing when the OwnerLabel changes it's size or position. + // OwnerResize does nothing in this class + procedure OwnerResize; virtual; + // Start is automatically called when Active is set to True + // Override this method to take special action when the behavior is "started". + // Start does nothing in this class + procedure Start; virtual; + // Stop is automatically called when Active is set to True + // Override this method to take special action when the behavior is "stopped". + // Stop does nothing in this class + procedure Stop; virtual; + // The label that the behavior is acting upon + property OwnerLabel: TJvCustomBehaviorLabel read FLabel; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); virtual; + destructor Destroy; override; + published + // Set Active to True to enable the behavior and set it to False to disable it. + // Active calls Start and Stop as appropriate + property Active: Boolean read FActive write SetActive default False; + end; + + // TJvLabelNone implements no special behavior + TJvLabelNone = class(TJvLabelBehavior) + published + property Active; + end; + + // TJvLabelBlink implements a blinking behavior + TJvLabelBlink = class(TJvLabelBehavior) + private + FDelay: Cardinal; + FInterval: Cardinal; + FTimer: TTimer; + FToggled: Boolean; + procedure SetDelay(const Value: Cardinal); + procedure SetInterval(const Value: Cardinal); + procedure DoTimerEvent(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // Delay specifies the initial delay before the blinking starts. Delay is specified in milliseconds. + property Delay: Cardinal read FDelay write SetDelay default 100; + // Interval specifies the number f milliseconds that elapses between "blinks" + property Interval: Cardinal read FInterval write SetInterval default 400; + end; + + // TJvLabelBounce implements a bouncing label + // NOTE that to use this behavior, the labels Align property should be set to alNone + TJvLabelBounce = class(TJvLabelBehavior) + private + FOriginalRect: TRect; + FInterval: Cardinal; + FParent: TWinControl; + FDirection: Integer; + FTimer: TTimer; + FPixels: Integer; + procedure SetInterval(const Value: Cardinal); + procedure SetPixels(const Value: Integer); + procedure DoTimerEvent(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // Interval specifies the number of milliseconds that elapses between "bounces" + // Lower values will make the label move faster + property Interval: Cardinal read FInterval write SetInterval default 20; + // Pixels specifes the number of pixels the label is moved at each bounce. + // Lower values will make the label move slower and smoother. Compensate by decreasing the value of Interval + property Pixels: Integer read FPixels write SetPixels default 6; + end; + + // TJvLabelScroll implements a scrolling behavior, a behavior where the text is scrolled horizontally + // This is sometimes also referred to as a "marquee" + TJvLabelScroll = class(TJvLabelBehavior) + private + FInterval: Cardinal; + FDirection: TJvLabelScrollDirection; + FTimer: TTimer; + FPadding: Boolean; + procedure SetDirection(const Value: TJvLabelScrollDirection); + procedure SetInterval(const Value: Cardinal); + procedure DoTimerEvent(Sender: TObject); + procedure SetPadding(Value: Boolean); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // Set Padding to True to simulate the Caption being scrolled "around the Edge" of the + // label. This property is implemented such that the text is right-padded with spaces + property Padding: Boolean read FPadding write SetPadding default False; + // Interval specifies the number of milliseconds that elapses between each scroll + // A lower Interval increases the speed of the scroll + property Interval: Cardinal read FInterval write SetInterval default 50; + // Direction specifies the direction of the scroll. Possible values are + // sdLeftToRight - the text is scrolled from left to right + // sdRightToLeft - the text is scrolled from right to left + property Direction: TJvLabelScrollDirection read FDirection write SetDirection default sdLeftToRight; + end; + + // TJvLabelAppear implements a behavior where the label appears + // from one edge, moves across the form and stops at the other edge + // NOTE that to use this behavior, the labels Align property should be set to alNone + TJvLabelAppear = class(TJvLabelBehavior) + private + FParent: TWinControl; + FDelay: Cardinal; + FInterval: Cardinal; + FPixels: Integer; + FAppearFrom: TJvAppearDirection; + FTimer: TTimer; + FOriginalRect: TRect; + FFirst: Boolean; + procedure SetDelay(const Value: Cardinal); + procedure SetInterval(const Value: Cardinal); + procedure DoTimerEvent(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // Delay sets the initial delay before the label starts moving + property Delay: Cardinal read FDelay write SetDelay default 100; + // Interval sets the number of milliseconds that elapses between each move of the label + property Interval: Cardinal read FInterval write SetInterval default 20; + // Pixels sets number of piels the label moves at each interval + property Pixels: Integer read FPixels write FPixels default 3; + // AppearFrom sets the edge from which the label appears. It also specifies the direction the label moves in + // Possible values for AppearFrom are: + // drFromLeft - label appears from the parents left edge and moves to the right edge where it stops + // drFromRight - label appears from the parents right edge and moves to the left edge where it stops + // drFromTop - label appears from the parents top edge and moves to the bottom edge where it stops + // drFromBottom - label appears from the parents bottom edge and moves to the top edge where it stops + property AppearFrom: TJvAppearDirection read FAppearFrom write FAppearFrom default drFromRight; + end; + + // TJvLabelTyping implements a behavior where the label's original Caption is typed + // into the label character by character + TJvLabelTyping = class(TJvLabelBehavior) + private + FMakeErrors: Boolean; + FInterval: Cardinal; + FTextPos: Integer; + FTimer: TTimer; + procedure SetInterval(const Value: Cardinal); + procedure SetMakeErrors(const Value: Boolean); + procedure DoTimerEvent(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // MakeErrors specifies whether the typing sometimes contains errors. Errors are + // removed after a short delay and the correct characters are "typed" instead. + property MakeErrors: Boolean read FMakeErrors write SetMakeErrors default True; + // Interval sets the speed of the typing in milliseconds + property Interval: Cardinal read FInterval write SetInterval default 100; + end; + + // TJvLabelSpecial implements a behavior where each character of the Caption is + // started at #32 (space) and automatically incremented up to it's final value. + // When the final value is reached, the next character of the original Caption is + // added and incremented. This proceeds until the entire original Caption is shown in the label. + TJvLabelSpecial = class(TJvLabelBehavior) + private + FInterval: Cardinal; + FTextPos: Integer; + FCharValue: Integer; + FTimer: TTimer; + procedure SetInterval(const Value: Cardinal); + procedure DoTimerEvent(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property Active; + // Interval sets the number of milliseconds that elapses between increments + property Interval: Cardinal read FInterval write SetInterval default 20; + end; + + // TJvLabelCodeBreaker "decodes" the text in the label to the + // text in DecodedText. Interval sets the number of milliseconds between + // "decode attempts", i.e character changes + TJvLabelCodeBreaker = class(TJvLabelBehavior) + private + FScratchPad: TCaption; + FDecodedText: TCaption; + FInterval: Integer; + FCurrentPos: Integer; + FTimer: TTimer; + procedure SetInterval(const Value: Integer); + procedure DoTimer(Sender: TObject); + protected + procedure Start; override; + procedure Stop; override; + public + constructor Create(ALabel: TJvCustomBehaviorLabel); override; + published + property DecodedText: TCaption read FDecodedText write FDecodedText; + property Interval: Integer read FInterval write SetInterval default 10; + end; + + TJvLabelBehaviorOptionsClass = class of TJvLabelBehavior; + + TJvCustomBehaviorLabel = class(TCustomLabel) //TJvExCustomLabel) + private + FBehavior: TJvLabelBehaviorName; + FOptions: TJvLabelBehavior; + FOnStart: TNotifyEvent; + FOnStop: TNotifyEvent; + FUseEffectText: Boolean; + FEffectText: TCaption; + function GetOptions: TJvLabelBehavior; + function BehaviorStored: Boolean; + procedure UpdateDesigner; + procedure SetBehavior(const Value: TJvLabelBehaviorName); + procedure SetOptions(const Value: TJvLabelBehavior); + procedure SetUseEffectText(const Value: Boolean); + protected + procedure Loaded; override; + procedure Resize; override; + procedure DoStart; dynamic; + procedure DoStop; dynamic; + + function GetLabelText: string; override; + property Behavior: TJvLabelBehaviorName read FBehavior write SetBehavior stored BehaviorStored; + property Caption; + property BehaviorOptions: TJvLabelBehavior read GetOptions write SetOptions; + property OnStart: TNotifyEvent read FOnStart write FOnStart; + property OnStop: TNotifyEvent read FOnStop write FOnStop; + public + constructor Create(AComponent: TComponent); override; + destructor Destroy; override; + + // do not make these published + property EffectText: TCaption read FEffectText write FEffectText; + property UseEffectText: Boolean read FUseEffectText write SetUseEffectText; + end; + + TJvBehaviorLabel = class(TJvCustomBehaviorLabel) + published + property BiDiMode; + property DragCursor; + property OnEndDock; + property OnStartDock; + property ParentBiDiMode; + property Behavior; + property BehaviorOptions; + property OnMouseEnter; + property OnMouseLeave; +// property OnParentColorChange; + property OnStart; + property OnStop; + + property Align; + property Alignment; + property Anchors; + property AutoSize; + property BorderSpacing; + property Caption; + property Color; + property Constraints; + property OnEndDrag; + property DragKind; + property DragMode; + property Enabled; + property FocusControl; + property Font; + property ParentColor; + property ParentFont; + property ParentShowHint; + property PopupMenu; + property ShowAccelChar; + property ShowHint; + property Transparent; + property Layout; + property Visible; + property WordWrap; + property OnClick; + property OnContextPopup; + property OnDblClick; + property OnDragDrop; + property OnDragOver; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnStartDrag; + end; + + // register a new behaviour +procedure RegisterLabelBehaviorOptions(const Name: TJvLabelBehaviorName; BehaviorOptionsClass: + TJvLabelBehaviorOptionsClass); +// returns the class of the behaviour named Name or TJvLabelBehavior if Name not registered +function GetLabelBehaviorOptionsClass(const Name: TJvLabelBehaviorName): TJvLabelBehaviorOptionsClass; +// returns the registered name of BehaviorOptionsClass or an empty string if BehaviorOptionsClass is not registered +function GetLabelBehaviorName(BehaviorOptionsClass: TJvLabelBehaviorOptionsClass): string; +// Copies the internal TStrings list to Strings where each Strings[] is the name of a +// registered class and each Objects[] is a pointer to the corresponding class +procedure GetRegisteredLabelBehaviorOptions(Strings: TStrings); + + +implementation + +uses + SysUtils, Forms, + JvTypes, JvResources; + +var + AllBehaviorOptions: TStringList = nil; + +function GetLabelBehaviorOptionsClass(const Name: TJvLabelBehaviorName): TJvLabelBehaviorOptionsClass; +var + I: Integer; +begin + Result := TJvLabelBehavior; + if AllBehaviorOptions <> nil then + begin + I := AllBehaviorOptions.IndexOf(Name); + if I >= 0 then + Result := TJvLabelBehaviorOptionsClass(AllBehaviorOptions.Objects[I]); + end; +end; + +function GetLabelBehaviorName(BehaviorOptionsClass: TJvLabelBehaviorOptionsClass): string; +var + I: Integer; +begin + Result := ''; + if AllBehaviorOptions <> nil then + begin + I := AllBehaviorOptions.IndexOfObject(TObject(BehaviorOptionsClass)); + if I >= 0 then + Result := AllBehaviorOptions[I]; + end; +end; + +procedure GetRegisteredLabelBehaviorOptions(Strings: TStrings); +begin + if Strings <> nil then + Strings.Assign(AllBehaviorOptions); +end; + +procedure RegisterLabelBehaviorOptions(const Name: TJvLabelBehaviorName; + BehaviorOptionsClass: TJvLabelBehaviorOptionsClass); +begin + if AllBehaviorOptions = nil then + begin + AllBehaviorOptions := TStringList.Create; + AllBehaviorOptions.Sorted := True; + end; + if AllBehaviorOptions.IndexOf(Name) >= 0 then + Exit; + // raise Exception.CreateFmt('Options %s already registered!',[Name]); // can't raise here: we are probably in an initialization section + AllBehaviorOptions.AddObject(Name, TObject(BehaviorOptionsClass)); +end; + +procedure NeedBehaviorLabel(const ClassName: string); +begin + raise EJVCLException.CreateResFmt(@RsENeedBehaviorLabel, [ClassName]); +end; + +procedure NoOwnerLabelParent(const ClassName: string); +begin + raise EJVCLException.CreateResFmt(@RsENoOwnerLabelParent, [ClassName]); +end; + +//=== { TJvLabelBehavior } =================================================== + +constructor TJvLabelBehavior.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create; + if ALabel = nil then + NeedBehaviorLabel(ClassName); + FLabel := ALabel; + FActive := False; +end; + +destructor TJvLabelBehavior.Destroy; +begin + FTemporary := True; + Stop; + inherited Destroy; +end; + +procedure TJvLabelBehavior.OwnerResize; +begin + // +end; + +procedure TJvLabelBehavior.Resume; +begin + Active := FTmpActive; + FTemporary := False; +end; + +procedure TJvLabelBehavior.SetActive(const Value: Boolean); +begin + if FActive <> Value then + begin + if FActive then + Stop; + FActive := Value; + if FActive then + Start; + end; +end; + +procedure TJvLabelBehavior.Start; +begin + if not FTemporary then + OwnerLabel.DoStart; +end; + +procedure TJvLabelBehavior.Stop; +begin + if not FTemporary then + OwnerLabel.DoStop; +end; + +procedure TJvLabelBehavior.Suspend; +begin + FTmpActive := Active; + FTemporary := True; + Active := False; +end; + +//=== { TJvCustomBehaviorLabel } ============================================= + +constructor TJvCustomBehaviorLabel.Create(AComponent: TComponent); +begin + // registration + if not Assigned(AllBehaviorOptions) then + begin + RegisterLabelBehaviorOptions(RsNoneCaption, TJvLabelNone); + RegisterLabelBehaviorOptions('Blinking', TJvLabelBlink); + RegisterLabelBehaviorOptions('Bouncing', TJvLabelBounce); + RegisterLabelBehaviorOptions('Scrolling', TJvLabelScroll); + RegisterLabelBehaviorOptions('Typing', TJvLabelTyping); + RegisterLabelBehaviorOptions('Appearing', TJvLabelAppear); + RegisterLabelBehaviorOptions('Special', TJvLabelSpecial); + RegisterLabelBehaviorOptions('CodeBreaker', TJvLabelCodeBreaker); + end; + + inherited Create(AComponent); + FBehavior := RsNoneCaption; + FUseEffectText := False; + FEffectText := ''; +end; + +destructor TJvCustomBehaviorLabel.Destroy; +begin + FreeAndNil(FOptions); + inherited Destroy; +end; + +procedure TJvCustomBehaviorLabel.DoStart; +begin + if Assigned(FOnStart) then + FOnStart(Self); +end; + +procedure TJvCustomBehaviorLabel.DoStop; +begin + if Assigned(FOnStop) then + FOnStop(Self); +end; + + +function TJvCustomBehaviorLabel.GetLabelText: string; +begin + if UseEffectText then + Result := EffectText + else + Result := inherited GetLabelText; +end; + + + + +function TJvCustomBehaviorLabel.BehaviorStored: Boolean; +begin + Result := FBehavior <> RsNoneCaption; +end; + +function TJvCustomBehaviorLabel.GetOptions: TJvLabelBehavior; +begin + if FOptions = nil then + begin + // (p3) this doesn't update Options in the OI at DT (unless you collapse/expand the property) + FOptions := GetLabelBehaviorOptionsClass(FBehavior).Create(Self); + UpdateDesigner; + end; + Result := FOptions; +end; + +procedure TJvCustomBehaviorLabel.Loaded; +begin + inherited Loaded; + + // Start method usually exits immediately when the component is loading. + // As a result, when the component is loaded, we must start the behavior + // or the user won't see anything (Mantis 4809) + if BehaviorOptions.Active then + BehaviorOptions.Start; +end; + +procedure TJvCustomBehaviorLabel.Resize; +begin + inherited Resize; + BehaviorOptions.OwnerResize; +end; + +procedure TJvCustomBehaviorLabel.SetBehavior(const Value: TJvLabelBehaviorName); +var + S: TStringList; +begin + if FBehavior <> Value then + begin + S := TStringList.Create; + try + GetRegisteredLabelBehaviorOptions(S); + if S.IndexOf(Value) < 0 then + Exit; + finally + S.Free; + end; + // (p3) this doesn't update Options in the OI at DT (unless you collapse/expand the property) + FBehavior := Value; + FreeAndNil(FOptions); + UpdateDesigner; + end; +end; + +procedure TJvCustomBehaviorLabel.SetOptions(const Value: TJvLabelBehavior); +begin + if Value = nil then + Behavior := '' + else + if (FOptions = nil) or (FOptions.ClassType <> Value.ClassType) then + Behavior := GetLabelBehaviorName(TJvLabelBehaviorOptionsClass(Value.ClassType)); + UpdateDesigner; +end; + +procedure TJvCustomBehaviorLabel.SetUseEffectText(const Value: Boolean); +begin + if Value <> FUseEffectText then + begin + FUseEffectText := Value; + if ComponentState * [csLoading, csDestroying] = [] then + Repaint; + end; +end; + +procedure TJvCustomBehaviorLabel.UpdateDesigner; +var + F: TCustomForm; +begin + if csDesigning in ComponentState then + begin + F := GetParentForm(Self); + if (F <> nil) and (F.Designer <> nil) then + F.Designer.Modified; + end; +end; + +//=== { TJvLabelBlink } ====================================================== + +constructor TJvLabelBlink.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + ALabel.EffectText := ''; + FDelay := 100; + FInterval := 400; +end; + +procedure TJvLabelBlink.DoTimerEvent(Sender: TObject); +begin + FTimer.Enabled := False; + FTimer.Interval := FInterval; + FToggled := not FToggled; + OwnerLabel.UseEffectText := FToggled; + FTimer.Enabled := FInterval > 0; +end; + +procedure TJvLabelBlink.SetDelay(const Value: Cardinal); +begin + if FDelay <> Value then + begin + Suspend; + FDelay := Value; + Resume; + end; +end; + +procedure TJvLabelBlink.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelBlink.Start; +begin + inherited Start; + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTimer.Interval := FDelay; + FToggled := False; + if FDelay = 0 then + FDelay := 1; + FTimer.Enabled := True; // not (csDesigning in OwnerLabel.ComponentState); +end; + +procedure TJvLabelBlink.Stop; +begin + if FTimer <> nil then + begin + FreeAndNil(FTimer); + OwnerLabel.UseEffectText := False; + end; + inherited Stop; +end; + +//=== { TJvLabelBounce } ===================================================== + +constructor TJvLabelBounce.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FInterval := 20; + FPixels := 6; +end; + +procedure TJvLabelBounce.DoTimerEvent(Sender: TObject); +begin + FTimer.Enabled := False; + if Pixels = 0 then + Pixels := Random(8); + with OwnerLabel do + case FDirection of + 0: + if (Left - Pixels <= 0) or (Top + Height + Pixels >= FParent.ClientHeight) then + begin + FDirection := Random(4); + // Pixels := Random(8); + end + else + begin + Left := Left - Pixels; + Top := Top + Pixels; + end; + 1: + if (Top + Height + Pixels >= FParent.ClientHeight) or + (Left + Width + Pixels >= FParent.ClientWidth) then + begin + FDirection := Random(4); + // Pixels := Random(8); + end + else + begin + Top := Top + Pixels; + Left := Left + Pixels; + end; + 2: + if (Left - Pixels <= 0) or (Top - Pixels <= 0) then + begin + FDirection := Random(4); + // Pixels := Random(8); + end + else + begin + Left := Left - Pixels; + Top := Top - Pixels; + end; + 3: + if (Left + Width + Pixels > FParent.ClientWidth) or (Top - Pixels <= 0) then + begin + FDirection := Random(4); + // Pixels := Random(8); + end + else + begin + Left := Left + Pixels; + Top := Top - Pixels; + end; + end; + FTimer.Enabled := True; +end; + +procedure TJvLabelBounce.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + if FInterval <= 0 then + FInterval := 20; + Resume; + end; +end; + +procedure TJvLabelBounce.SetPixels(const Value: Integer); +begin + if FPixels <> Value then + begin + Suspend; + FPixels := Value; + if FPixels <= 0 then + FPixels := 6; + Resume; + end; +end; + +procedure TJvLabelBounce.Start; +begin + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + FParent := OwnerLabel.Parent; + if FParent = nil then + NoOwnerLabelParent(ClassName); + inherited Start; + FOriginalRect := OwnerLabel.BoundsRect; + Randomize; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTimer.Interval := Interval; + FTimer.Enabled := True; +end; + +procedure TJvLabelBounce.Stop; +begin + FreeAndNil(FTimer); + if not IsRectEmpty(FOriginalRect) then + OwnerLabel.BoundsRect := FOriginalRect; + inherited Stop; +end; + +//=== { TJvLabelScroll } ===================================================== + +constructor TJvLabelScroll.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FInterval := 50; + FDirection := sdLeftToRight; +end; + +procedure TJvLabelScroll.DoTimerEvent(Sender: TObject); +var + Tmp: TCaption; +begin + FTimer.Enabled := False; + if OwnerLabel.Caption <> '' then + begin + Tmp := OwnerLabel.EffectText; + if FDirection = sdLeftToRight then + Tmp := Tmp[Length(Tmp)] + Copy(Tmp, 1, Length(Tmp) - 1) + else + Tmp := Copy(Tmp, 2, Length(Tmp) - 1) + Tmp[1]; + OwnerLabel.EffectText := Tmp; + OwnerLabel.Repaint; + end; + FTimer.Enabled := True; +end; + +procedure TJvLabelScroll.SetDirection(const Value: TJvLabelScrollDirection); +begin + if FDirection <> Value then + begin + Suspend; + FDirection := Value; + Resume; + end; +end; + +procedure TJvLabelScroll.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelScroll.SetPadding(Value: Boolean); +var + Tmp: TCaption; +begin + FPadding := Value; + Tmp := ''; + while OwnerLabel.Canvas.TextWidth(Tmp) < OwnerLabel.Width do + Tmp := Tmp + ' '; + if Value then + OwnerLabel.EffectText := OwnerLabel.Caption + Tmp + else + OwnerLabel.EffectText := OwnerLabel.Caption; +end; + +procedure TJvLabelScroll.Start; +begin + inherited Start; + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTimer.Interval := Interval; + SetPadding(Padding); + OwnerLabel.UseEffectText := True; + FTimer.Enabled := True; +end; + +procedure TJvLabelScroll.Stop; +begin + FreeAndNil(FTimer); + OwnerLabel.UseEffectText := False; + inherited Stop; +end; + +//=== { TJvLabelAppear } ===================================================== + +constructor TJvLabelAppear.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FDelay := 100; + FInterval := 20; + FPixels := 3; + FAppearFrom := drFromRight; +end; + +procedure TJvLabelAppear.DoTimerEvent(Sender: TObject); +var + FWidth, FHeight: Integer; + FSuspend: Boolean; +begin + FWidth := FOriginalRect.Right - FOriginalRect.Left; + FHeight := FOriginalRect.Bottom - FOriginalRect.Top; + FSuspend := False; + if FFirst then + begin + case FAppearFrom of + drFromRight: + begin + OwnerLabel.Left := FParent.ClientWidth; + OwnerLabel.Width := 0; + end; + drFromLeft: + OwnerLabel.Left := -OwnerLabel.Width; + drFromTop: + OwnerLabel.Top := -OwnerLabel.Height; + drFromBottom: + begin + OwnerLabel.Top := FParent.ClientHeight; + OwnerLabel.Height := 0; + end; + end; + OwnerLabel.Visible := True; + FFirst := False; + end; + + case FAppearFrom of + drFromRight: + begin + if Abs(OwnerLabel.Left - FOriginalRect.Left) < Pixels then + begin + OwnerLabel.Left := FOriginalRect.Left; + FSuspend := True; + end + else + OwnerLabel.Left := OwnerLabel.Left - Pixels; + if OwnerLabel.Width <> FWidth then + begin + if OwnerLabel.Left + FWidth < FParent.ClientWidth then + OwnerLabel.Width := FWidth + else + OwnerLabel.Width := FParent.ClientWidth - OwnerLabel.Left - 2; + end; + end; + drFromLeft: + if Abs(OwnerLabel.Left - FOriginalRect.Left) < Pixels then + begin + OwnerLabel.Left := FOriginalRect.Left; + FSuspend := True; + end + else + OwnerLabel.Left := OwnerLabel.Left + Pixels; + drFromTop: + if Abs(OwnerLabel.Top - FOriginalRect.Top) < Pixels then + begin + OwnerLabel.Top := FOriginalRect.Top; + FSuspend := True; + end + else + OwnerLabel.Top := OwnerLabel.Top + Pixels; + drFromBottom: + begin + if Abs(OwnerLabel.Top - FOriginalRect.Top) < Pixels then + begin + OwnerLabel.Top := FOriginalRect.Top; + FSuspend := True; + end + else + OwnerLabel.Top := OwnerLabel.Top - Pixels; + if OwnerLabel.Height <> FHeight then + begin + if OwnerLabel.Top + FHeight < FParent.ClientHeight then + OwnerLabel.Height := FHeight + else + OwnerLabel.Height := FParent.ClientHeight - OwnerLabel.Top - 2; + end; + end; + end; + FTimer.Interval := Interval; + if FSuspend then + Active := False + else + FTimer.Enabled := True; +end; + +procedure TJvLabelAppear.SetDelay(const Value: Cardinal); +begin + if FDelay <> Value then + begin + Suspend; + FDelay := Value; + Resume; + end; +end; + +procedure TJvLabelAppear.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelAppear.Start; +begin + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + FParent := OwnerLabel.Parent; + if FParent = nil then + NoOwnerLabelParent(ClassName); + inherited Start; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTimer.Interval := Delay; + FFirst := True; + FOriginalRect := OwnerLabel.BoundsRect; + FTimer.Enabled := True; +end; + +procedure TJvLabelAppear.Stop; +begin + FreeAndNil(FTimer); + if not IsRectEmpty(FOriginalRect) then + OwnerLabel.BoundsRect := FOriginalRect; + inherited Stop; +end; + +//=== { TJvLabelTyping } ===================================================== + +constructor TJvLabelTyping.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FInterval := 100; + FMakeErrors := True; +end; + +procedure TJvLabelTyping.DoTimerEvent(Sender: TObject); +var + Tmp: TCaption; + I: Integer; +begin + FTimer.Enabled := False; + if FTextPos <= Length(OwnerLabel.Caption) then + begin + Tmp := Copy(OwnerLabel.Caption, 1, FTextPos - 1); + I := Random(10); + if (I = 7) and MakeErrors then + Tmp := Tmp + Char(Ord(OwnerLabel.Caption[FTextPos]) - Random(10)) + else + Tmp := Tmp + OwnerLabel.Caption[FTextPos]; + if (MakeErrors) and (I <> 7) then + FTimer.Interval := Interval + else + FTimer.Interval := Interval * 2; + OwnerLabel.EffectText := Tmp; + OwnerLabel.Repaint; + Inc(FTextPos); + FTimer.Enabled := True; + end + else + Active := False; +end; + +procedure TJvLabelTyping.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelTyping.SetMakeErrors(const Value: Boolean); +begin + if FMakeErrors <> Value then + begin + Suspend; + FMakeErrors := Value; + Resume; + end; +end; + +procedure TJvLabelTyping.Start; +begin + inherited Start; + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTimer.Interval := Interval; + Randomize; + OwnerLabel.EffectText := ''; + OwnerLabel.UseEffectText := True; + FTextPos := 1; + FTimer.Enabled := True; +end; + +procedure TJvLabelTyping.Stop; +begin + FreeAndNil(FTimer); + OwnerLabel.UseEffectText := False; + inherited Stop; +end; + +//=== { TJvLabelSpecial } ==================================================== + +constructor TJvLabelSpecial.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FInterval := 20; +end; + +procedure TJvLabelSpecial.DoTimerEvent(Sender: TObject); +begin + FTimer.Enabled := False; + if FTextPos < Length(OwnerLabel.Caption) then + begin + if FCharValue > Ord(OwnerLabel.Caption[FTextPos]) then + begin + Inc(FTextPos); + FCharValue := 32; + end; + OwnerLabel.EffectText := Copy(OwnerLabel.Caption, 1, FTextPos) + Char(FCharValue); + OwnerLabel.Repaint; + Inc(FCharValue); + FTimer.Enabled := True; + end + else + Active := False; +end; + +procedure TJvLabelSpecial.SetInterval(const Value: Cardinal); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelSpecial.Start; +begin + inherited Start; + if OwnerLabel.ComponentState * [csLoading, csDestroying] <> [] then + Exit; + if FTimer = nil then + begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimerEvent; + end; + FTextPos := 1; + FCharValue := 32; + OwnerLabel.EffectText := ''; + OwnerLabel.UseEffectText := True; + FTimer.Interval := Interval; + FTimer.Enabled := True; +end; + +procedure TJvLabelSpecial.Stop; +begin + FreeAndNil(FTimer); + OwnerLabel.UseEffectText := False; + inherited Stop; +end; + +//=== { TJvLabelCodeBreaker } ================================================ + +constructor TJvLabelCodeBreaker.Create(ALabel: TJvCustomBehaviorLabel); +begin + inherited Create(ALabel); + FInterval := 10; +end; + +procedure TJvLabelCodeBreaker.DoTimer(Sender: TObject); +begin + FTimer.Enabled := False; + if (FCurrentPos > Length(FScratchPad)) or (FCurrentPos > Length(DecodedText)) then + begin + OwnerLabel.EffectText := DecodedText; + OwnerLabel.Repaint; + Active := False; + OwnerLabel.UseEffectText := False; + Exit; + end + else + if FScratchPad[FCurrentPos] <> DecodedText[FCurrentPos] then + begin + FScratchPad[FCurrentPos] := Char(32 + Random(Ord(DecodedText[FCurrentPos]) + 10)); + // OwnerLabel.EffectText := Copy(OwnerLabel.Caption, 1, FCurrentPos - 1) + + // FScratchPad[FCurrentPos] + Copy(OwnerLabel.Caption, FCurrentPos + 1, MaxInt); + // (p3) this is the same without the copying... + OwnerLabel.EffectText := FScratchPad; + OwnerLabel.Repaint; + end + else + Inc(FCurrentPos); + // (p3) this seems unnecessary since we have an Interval property +// Sleep(FInterval); + FTimer.Enabled := True; +end; + +procedure TJvLabelCodeBreaker.SetInterval(const Value: Integer); +begin + if FInterval <> Value then + begin + Suspend; + FInterval := Value; + Resume; + end; +end; + +procedure TJvLabelCodeBreaker.Start; +begin + inherited Start; + FCurrentPos := 1; + if (Interval > 0) and (OwnerLabel.Caption <> '') and (DecodedText <> '') then + begin + FScratchPad := OwnerLabel.Caption; + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.OnTimer := @DoTimer; + FTimer.Interval := Interval; + FTimer.Enabled := True; + OwnerLabel.UseEffectText := True; + end + else + Active := False; +end; + +procedure TJvLabelCodeBreaker.Stop; +begin + FreeAndNil(FTimer); + OwnerLabel.Caption := OwnerLabel.EffectText; + OwnerLabel.UseEffectText := False; + inherited Stop; +end; + +finalization + FreeAndNil(AllBehaviorOptions); + +end.