{ *************************************************************************** * * * This source is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This code is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * A copy of the GNU General Public License is available on the World * * Wide Web at . You can also * * obtain it by writing to the Free Software Foundation, * * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * *************************************************************************** * This unit is part of the visual component SplashAbout * Code is adapted from the Lazarus IDE code * by minesadorada@charcodelvalle.com } unit scrolltextclass; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,LCLIntf; CONST C_TEXTFILENAME='credits.txt'; C_VERSION='1.0.0.0'; type TScrollTextClass = class(TGraphicControl) private FActive: boolean; FActiveLine: integer; //the line over which the mouse hovers FBuffer: TBitmap; FEndLine: integer; FLineHeight: integer; FLines: TStrings; FNumLines: integer; FOffset: integer; FStartLine: integer; FStepSize: integer; FTimer: TTimer; FFont:TFont; FBackColor:TColor; FUseTextFile:Boolean; fTextFileName:String; fVersionString:String; function ActiveLineIsURL: boolean; procedure DoTimer(Sender: TObject); procedure SetActive(const AValue: boolean); procedure Init; procedure DrawScrollingText(Sender: TObject); Procedure SetLines(AValue:TStrings); Procedure SetFont(AValue:TFont); protected procedure DoOnChangeBounds; override; procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override; procedure MouseMove(Shift: TShiftState; X,Y: Integer); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; // Can be set in design mode. Note URL links are inactive in design mode property Active: boolean read FActive write SetActive; // Inherited property property Align; // Inherited property property Borderspacing; // Can be set in design or runtime mode. UseTextFile property overrides. property Lines: TStrings read FLines write SetLines; // Sets the background color of the window property BackColor:TColor read fBackColor write fBackColor default clWindow; // Sets the font properties of the scrolling text property Font:TFont read fFont Write SetFont; // If TRUE then the file 'scrolling.txt' sould be in the application folder property UseTextFile:Boolean read fUseTextFile write fUseTextFile default FALSE; // Read-only property to remind you of the correct file name property TextFileName:String read fTextFileName; // Version number of this component property Version:String read fVersionString; end; implementation Procedure TScrollTextClass.SetFont(AValue:TFont); begin fFont.Assign(AValue); end; Procedure TScrollTextClass.SetLines(AValue:TStrings); begin fLines.Assign(AValue); end; procedure TScrollTextClass.SetActive(const AValue: boolean); begin FActive := AValue; if FActive then Init; FTimer.Enabled:=Active; end; procedure TScrollTextClass.Init; begin FBuffer.Width := Width; FBuffer.Height := Height; FLineHeight := FBuffer.Canvas.TextHeight('X'); FNumLines := FBuffer.Height div FLineHeight; if FOffset = -1 then FOffset := FBuffer.Height; with FBuffer.Canvas do begin Brush.Color := fBackColor; Brush.Style := bsSolid; FillRect(0, 0, Width, Height); end; If (fLines.Count = 0) then begin fLines.Add('This is the Credits scrolling window.'); fLines.Add(' '); fLines.Add('This default text is showing because you either:'); fLines.Add(' '); fLines.Add('1) Haven''t set any text in the CreditLines property. or'); fLines.Add('2) the file specified in the '); fLines.Add('CreditsTextFileName property is absent or empty.'); fLines.Add(' '); fLines.Add('Note that URL links such as'); fLines.Add('http://http://wiki.lazarus.freepascal.org/Main_Page'); fLines.Add('are clickable by the user'); fLines.Add(' '); fLines.Add(' '); fLines.Add('The standalone visual component TScrollTextClass is available at:'); fLines.Add('http://www.charcodelvalle.com/scrollingtext/scrollingtext_component.zip'); fLines.Add(' '); fLines.Add('June 2014'); end; end; procedure TScrollTextClass.DrawScrollingText(Sender: TObject); begin if Active then Canvas.Draw(0,0,FBuffer); end; procedure TScrollTextClass.DoTimer(Sender: TObject); var w: integer; s: string; i: integer; begin if not Active then Exit; Dec(FOffset, FStepSize); if FOffSet < 0 then FStartLine := -FOffset div FLineHeight else FStartLine := 0; FEndLine := FStartLine + FNumLines + 1; if FEndLine > FLines.Count - 1 then FEndLine := FLines.Count - 1; FBuffer.Canvas.FillRect(Rect(0, 0, FBuffer.Width, FBuffer.Height)); for i := FEndLine downto FStartLine do begin s := Trim(FLines[i]); //reset buffer font FBuffer.Canvas.Font:=fFont; FBuffer.Canvas.Font.Style := []; FBuffer.Canvas.Font.Color := clBlack; //skip empty lines if Length(s) > 0 then begin //check for bold format token if s[1] = '#' then begin s := copy(s, 2, Length(s) - 1); FBuffer.Canvas.Font.Style := [fsBold]; end else begin //check for url if Pos('http://', s) = 1 then begin if i = FActiveLine then begin FBuffer.Canvas.Font.Style := [fsUnderline]; FBuffer.Canvas.Font.Color := clRed; end else FBuffer.Canvas.Font.Color := clBlue; end; end; w := FBuffer.Canvas.TextWidth(s); FBuffer.Canvas.TextOut((FBuffer.Width - w) div 2, FOffset + i * FLineHeight, s); end; end; //start showing the list from the start if FStartLine > FLines.Count - 1 then FOffset := FBuffer.Height; Invalidate; end; function TScrollTextClass.ActiveLineIsURL: boolean; begin if (FActiveLine > 0) and (FActiveLine < FLines.Count) then Result := Pos('http://', FLines[FActiveLine]) = 1 else Result := False; end; procedure TScrollTextClass.DoOnChangeBounds; begin inherited DoOnChangeBounds; Init; end; procedure TScrollTextClass.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin inherited MouseDown(Button, Shift, X, Y); if ActiveLineIsURL then OpenURL(FLines[FActiveLine]); end; procedure TScrollTextClass.MouseMove(Shift: TShiftState; X, Y: Integer); begin inherited MouseMove(Shift, X, Y); //calculate what line is clicked from the mouse position FActiveLine := (Y - FOffset) div FLineHeight; Cursor := crDefault; if (FActiveLine >= 0) and (FActiveLine < FLines.Count) and ActiveLineIsURL then Cursor := crHandPoint; end; constructor TScrollTextClass.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := ControlStyle + [csOpaque]; OnPaint := @DrawScrollingText; FLines := TStringList.Create; FTimer := TTimer.Create(nil); FTimer.OnTimer:=@DoTimer; FTimer.Interval:=30; FBuffer := TBitmap.Create; FFont:=TFont.Create; FFont.Size:=10; fBackColor:=clWindow; FStepSize := 1; FStartLine := 0; FOffset := -1; Width:=100; Height:=100; fTextFileName:=C_TEXTFILENAME; fVersionString:=C_VERSION; SendToBack; end; destructor TScrollTextClass.Destroy; begin FLines.Free; FTimer.Free; FBuffer.Free; FFont.Free; inherited Destroy; end; end.