From 3d619ce25b67f94662a5c391eacc42ab73531dfd Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 15 Jun 2022 10:19:47 +0000 Subject: [PATCH] Industrial: Add new component TLCDDisplay (ported by Boban Spasic). git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8302 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../Example/LCDDisplay/project1.lpi | 163 ++++ .../Example/LCDDisplay/project1.lpr | 24 + .../Example/LCDDisplay/untmain.lfm | 337 +++++++ .../Example/LCDDisplay/untmain.pas | 229 +++++ components/industrialstuff/industrial.lpk | 83 +- components/industrialstuff/industrial.pas | 2 +- .../resources/industrial_icons.txt | 3 + .../industrialstuff/resources/tlcddisplay.png | Bin 0 -> 596 bytes .../resources/tlcddisplay_150.png | Bin 0 -> 1070 bytes .../resources/tlcddisplay_200.png | Bin 0 -> 1225 bytes .../source/AllIndustrialRegister.pas | 6 +- .../industrialstuff/source/indlcddisplay.pas | 898 ++++++++++++++++++ .../source/industrial_icons.res | Bin 32427 -> 35493 bytes 13 files changed, 1702 insertions(+), 43 deletions(-) create mode 100644 components/industrialstuff/Example/LCDDisplay/project1.lpi create mode 100644 components/industrialstuff/Example/LCDDisplay/project1.lpr create mode 100644 components/industrialstuff/Example/LCDDisplay/untmain.lfm create mode 100644 components/industrialstuff/Example/LCDDisplay/untmain.pas create mode 100644 components/industrialstuff/resources/tlcddisplay.png create mode 100644 components/industrialstuff/resources/tlcddisplay_150.png create mode 100644 components/industrialstuff/resources/tlcddisplay_200.png create mode 100644 components/industrialstuff/source/indlcddisplay.pas diff --git a/components/industrialstuff/Example/LCDDisplay/project1.lpi b/components/industrialstuff/Example/LCDDisplay/project1.lpi new file mode 100644 index 000000000..e6a8b385b --- /dev/null +++ b/components/industrialstuff/Example/LCDDisplay/project1.lpi @@ -0,0 +1,163 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + </General> + <LazDoc Paths="..\docs"/> + <BuildModes> + <Item Name="Default" Default="True"/> + <Item Name="Debug"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="project1"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value=".."/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <Checks> + <IOChecks Value="True"/> + <RangeChecks Value="True"/> + <OverflowChecks Value="True"/> + <StackChecks Value="True"/> + </Checks> + <VerifyObjMethodCallValidity Value="True"/> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + <UseHeaptrc Value="True"/> + <TrashVariables Value="True"/> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + </Item> + <Item Name="Release"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="project1"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value=".."/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + <LinkSmart Value="True"/> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="LCL"/> + </Item> + <Item> + <PackageName Value="industrial"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="project1.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="untmain.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="frmMain"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="untMain"/> + </Unit> + <Unit> + <Filename Value="..\..\..\..\..\svn\lazarus-ccr\components\industrialstuff\source\indlcldisplay.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="indLCLDisplay"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="project1"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value=".."/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/industrialstuff/Example/LCDDisplay/project1.lpr b/components/industrialstuff/Example/LCDDisplay/project1.lpr new file mode 100644 index 000000000..a1d376a69 --- /dev/null +++ b/components/industrialstuff/Example/LCDDisplay/project1.lpr @@ -0,0 +1,24 @@ +program project1; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, untMain, TLCDLines_unit; + +{$R *.res} + +begin + RequireDerivedFormResource:=True; + Application.Scaled:=True; + Application.Initialize; + Application.CreateForm(TfrmMain, frmMain); + Application.Run; +end. + diff --git a/components/industrialstuff/Example/LCDDisplay/untmain.lfm b/components/industrialstuff/Example/LCDDisplay/untmain.lfm new file mode 100644 index 000000000..d87280ae2 --- /dev/null +++ b/components/industrialstuff/Example/LCDDisplay/untmain.lfm @@ -0,0 +1,337 @@ +object frmMain: TfrmMain + Left = 510 + Height = 531 + Top = 217 + Width = 921 + Caption = 'LCDLines Demo' + ClientHeight = 531 + ClientWidth = 921 + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '2.3.0.0' + object rgFrameStyle: TRadioGroup + Left = 24 + Height = 105 + Top = 336 + Width = 108 + AutoFill = True + Caption = 'Frame style' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 85 + ClientWidth = 104 + Items.Strings = ( + 'fsRelief' + 'fsNone' + 'fsLowered' + 'fsRaised' + ) + OnClick = rgFrameStyleClick + TabOrder = 0 + end + object rgFrameColorStyle: TRadioGroup + Left = 149 + Height = 65 + Top = 336 + Width = 123 + AutoFill = True + Caption = 'Frame color style' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 45 + ClientWidth = 119 + Items.Strings = ( + 'stWindows' + 'stColor' + ) + OnClick = rgFrameColorStyleClick + TabOrder = 1 + end + object cbtFrameColor: TColorButton + Left = 288 + Height = 25 + Top = 410 + Width = 123 + BorderWidth = 2 + ButtonColorAutoSize = False + ButtonColorSize = 16 + ButtonColor = clBlack + Caption = 'Frame color' + Margin = 8 + OnColorChanged = cbtFrameColorColorChanged + end + object rgDotShape: TRadioGroup + Left = 427 + Height = 65 + Top = 336 + Width = 120 + AutoFill = True + Caption = 'Dot shape' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 45 + ClientWidth = 116 + Items.Strings = ( + 'stSquare' + 'stRound' + ) + OnClick = rgDotShapeClick + TabOrder = 2 + end + object mmText: TMemo + Left = 704 + Height = 65 + Top = 336 + Width = 168 + OnChange = mmTextChange + TabOrder = 3 + end + object rgFrameHeight: TRadioGroup + Left = 563 + Height = 65 + Top = 336 + Width = 120 + AutoFill = True + Caption = 'Frame height' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 45 + ClientWidth = 116 + Items.Strings = ( + 'double' + 'single' + ) + OnClick = rgFrameHeightClick + TabOrder = 4 + end + object Label1: TLabel + Left = 427 + Height = 15 + Top = 413 + Width = 44 + Caption = 'Dot size:' + Color = clDefault + ParentColor = False + end + object seDotSize: TSpinEdit + Left = 491 + Height = 23 + Top = 410 + Width = 58 + OnChange = seDotSizeChange + TabOrder = 5 + end + object Label2: TLabel + Left = 427 + Height = 15 + Top = 441 + Width = 60 + Caption = 'Dots space:' + Color = clDefault + ParentColor = False + end + object seDotsSpace: TSpinEdit + Left = 491 + Height = 23 + Top = 438 + Width = 58 + OnChange = seDotsSpaceChange + TabOrder = 6 + end + object Label3: TLabel + Left = 563 + Height = 15 + Top = 413 + Width = 58 + Caption = 'Frame size:' + Color = clDefault + ParentColor = False + end + object seFrameSize: TSpinEdit + Left = 625 + Height = 23 + Top = 410 + Width = 58 + OnChange = seFrameSizeChange + TabOrder = 7 + end + object cbAutoSize: TCheckBox + Left = 149 + Height = 19 + Top = 413 + Width = 64 + Caption = 'AutoSize' + OnChange = cbAutoSizeChange + TabOrder = 8 + end + object cbCharSpace: TCheckBox + Left = 704 + Height = 19 + Top = 470 + Width = 76 + Caption = 'Char space' + OnChange = cbCharSpaceChange + TabOrder = 9 + end + object cbtBoardColor: TColorButton + Left = 288 + Height = 25 + Top = 436 + Width = 123 + BorderWidth = 2 + ButtonColorAutoSize = False + ButtonColorSize = 16 + ButtonColor = clBlack + Caption = 'Board color' + Margin = 8 + OnColorChanged = cbtBoardColorColorChanged + end + object cbtDotONColor: TColorButton + Left = 288 + Height = 25 + Top = 464 + Width = 123 + BorderWidth = 2 + ButtonColorAutoSize = False + ButtonColorSize = 16 + ButtonColor = clBlack + Caption = 'Dot color ON' + Margin = 8 + OnColorChanged = cbtDotONColorColorChanged + end + object cbtDotOFFColor: TColorButton + Left = 288 + Height = 25 + Top = 492 + Width = 123 + BorderWidth = 2 + ButtonColorAutoSize = False + ButtonColorSize = 16 + ButtonColor = clBlack + Caption = 'Dot color OFF' + Margin = 8 + OnColorChanged = cbtDotOFFColorColorChanged + end + object seDisplayLineCount: TSpinEdit + Left = 814 + Height = 23 + Top = 410 + Width = 58 + OnChange = seDisplayLineCountChange + TabOrder = 10 + end + object Label4: TLabel + Left = 704 + Height = 15 + Top = 413 + Width = 95 + Caption = 'Screen row count:' + Color = clDefault + ParentColor = False + end + object seWidth: TSpinEdit + Left = 625 + Height = 23 + Top = 438 + Width = 58 + OnChange = seWidthChange + TabOrder = 11 + end + object Label5: TLabel + Left = 563 + Height = 15 + Top = 441 + Width = 35 + Caption = 'Width:' + Color = clDefault + ParentColor = False + end + object seHeigth: TSpinEdit + Left = 625 + Height = 23 + Top = 466 + Width = 58 + OnChange = seHeigthChange + TabOrder = 12 + end + object Label6: TLabel + Left = 563 + Height = 15 + Top = 469 + Width = 39 + Caption = 'Heigth:' + Color = clDefault + ParentColor = False + end + object Label7: TLabel + Left = 704 + Height = 15 + Top = 441 + Width = 91 + Caption = 'Screen col count:' + Color = clDefault + ParentColor = False + end + object seDisplayCharCount: TSpinEdit + Left = 814 + Height = 23 + Top = 438 + Width = 58 + OnChange = seDisplayCharCountChange + TabOrder = 13 + end + object cbColorSchemes: TComboBox + Left = 288 + Height = 23 + Top = 354 + Width = 100 + ItemHeight = 15 + Items.Strings = ( + 'csCustom' + 'csBlue' + 'csGreen' + 'csInvGreen' + ) + OnChange = cbColorSchemesChange + TabOrder = 14 + Text = 'cbColorSchemes' + end + object Label8: TLabel + Left = 288 + Height = 15 + Top = 336 + Width = 76 + Caption = 'Color scheme:' + Color = clDefault + ParentColor = False + end + object Label9: TLabel + Left = 288 + Height = 15 + Top = 392 + Width = 119 + Caption = 'Custom color scheme:' + Color = clDefault + ParentColor = False + end +end diff --git a/components/industrialstuff/Example/LCDDisplay/untmain.pas b/components/industrialstuff/Example/LCDDisplay/untmain.pas new file mode 100644 index 000000000..78809c583 --- /dev/null +++ b/components/industrialstuff/Example/LCDDisplay/untmain.pas @@ -0,0 +1,229 @@ +unit untMain; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, + Spin, indLCDDisplay; + +type + + { TfrmMain } + + TfrmMain = class(TForm) + cbAutoSize: TCheckBox; + cbCharSpace: TCheckBox; + cbtFrameColor: TColorButton; + cbtBoardColor: TColorButton; + cbtDotONColor: TColorButton; + cbtDotOFFColor: TColorButton; + cbColorSchemes: TComboBox; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + Label4: TLabel; + Label5: TLabel; + Label6: TLabel; + Label7: TLabel; + Label8: TLabel; + Label9: TLabel; + mmText: TMemo; + rgFrameStyle: TRadioGroup; + rgFrameColorStyle: TRadioGroup; + rgDotShape: TRadioGroup; + rgFrameHeight: TRadioGroup; + seDotSize: TSpinEdit; + seFrameSize: TSpinEdit; + seDotsSpace: TSpinEdit; + seDisplayCharCount: TSpinEdit; + seWidth: TSpinEdit; + seHeigth: TSpinEdit; + seDisplayLineCount: TSpinEdit; + procedure cbAutoSizeChange(Sender: TObject); + procedure cbCharSpaceChange(Sender: TObject); + procedure cbColorSchemesChange(Sender: TObject); + procedure cbtFrameColorColorChanged(Sender: TObject); + procedure cbtBoardColorColorChanged(Sender: TObject); + procedure cbtDotONColorColorChanged(Sender: TObject); + procedure cbtDotOFFColorColorChanged(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure mmTextChange(Sender: TObject); + procedure rgFrameStyleClick(Sender: TObject); + procedure rgFrameColorStyleClick(Sender: TObject); + procedure rgDotShapeClick(Sender: TObject); + procedure rgFrameHeightClick(Sender: TObject); + procedure seDisplayCharCountChange(Sender: TObject); + procedure seDotSizeChange(Sender: TObject); + procedure seDotsSpaceChange(Sender: TObject); + procedure seFrameSizeChange(Sender: TObject); + procedure seHeigthChange(Sender: TObject); + procedure seDisplayLineCountChange(Sender: TObject); + procedure seWidthChange(Sender: TObject); + private + LCDLines1: TLCDLines; + + public + + end; + +var + frmMain: TfrmMain; + +implementation + +{$R *.lfm} + +{ TfrmMain } + +procedure TfrmMain.cbtFrameColorColorChanged(Sender: TObject); +begin + LCDLines1.FrameColor := cbtFrameColor.ButtonColor; +end; + +procedure TfrmMain.cbtBoardColorColorChanged(Sender: TObject); +begin + LCDLines1.BoardColor := cbtBoardColor.ButtonColor; +end; + +procedure TfrmMain.cbtDotONColorColorChanged(Sender: TObject); +begin + LCDLines1.DotColorON := cbtDotONColor.ButtonColor; +end; + +procedure TfrmMain.cbtDotOFFColorColorChanged(Sender: TObject); +begin + LCDLines1.DotColorOFF := cbtDotOFFColor.ButtonColor; +end; + +procedure TfrmMain.FormCreate(Sender: TObject); +begin + LCDLines1 := TLCDLines.Create(self); + with LCDLines1 do + begin + Left := 24; + Height := 101; + Top := 16; + Width := 290; + AutoSize := True; + DotColorOn := 5162664; + DotColorOff := 2900284; + DisplayCharCount := 0; + Lines.Add('TLCDLines'); + ColorScheme := csInvGreen; + Parent := self; + end +end; + +procedure TfrmMain.FormShow(Sender: TObject); +begin + mmText.Lines := LCDLines1.Lines; + seDisplayLineCount.Value := LCDLines1.DisplayLineCount; + seDisplayCharCount.Value := LCDLines1.DisplayCharCount; + seFrameSize.Value := LCDLines1.FrameSize; + seDotSize.Value := LCDLines1.DotSize; + seDotsSpace.Value := LCDLines1.DotsSpace; + seWidth.Value := LCDLines1.Width; + seHeigth.Value := LCDLines1.Height; + cbAutoSize.Checked := LCDLines1.AutoSize; + cbCharSpace.Checked := LCDLines1.CharSpace; + cbtFrameColor.ButtonColor := LCDLines1.FrameColor; + cbtBoardColor.ButtonColor := LCDLines1.BoardColor; + cbtDotONColor.ButtonColor := LCDLines1.DotColorOn; + cbtDotOFFColor.ButtonColor := LCDLines1.DotColorOff; + rgFrameStyle.ItemIndex := integer(LCDLines1.FrameStyle); + rgFrameColorStyle.ItemIndex := integer(LCDLines1.FrameColorStyle); + rgDotShape.ItemIndex := integer(LCDLines1.DotShape); + rgFrameHeight.ItemIndex := integer(LCDLines1.FrameHeight); + cbColorSchemes.ItemIndex:= integer(LCDLines1.ColorScheme); +end; + +procedure TfrmMain.cbAutoSizeChange(Sender: TObject); +begin + LCDLines1.AutoSize := cbAutoSize.Checked; + if not cbAutoSize.Checked then + begin + LCDLines1.Width := seWidth.Value; + LCDLines1.Height := seHeigth.Value; + end; +end; + +procedure TfrmMain.cbCharSpaceChange(Sender: TObject); +begin + LCDLines1.CharSpace := cbCharSpace.Checked; +end; + +procedure TfrmMain.cbColorSchemesChange(Sender: TObject); +begin + LCDLines1.ColorScheme := TColorScheme(cbColorSchemes.ItemIndex); +end; + +procedure TfrmMain.mmTextChange(Sender: TObject); +begin + LCDLines1.Lines.Assign(mmText.Lines); + if LCDLines1.AutoSize then + begin + LCDLines1.InvalidatePreferredSize; + LCDLines1.AdjustSize; + end; + LCDLines1.Invalidate; +end; + +procedure TfrmMain.rgFrameStyleClick(Sender: TObject); +begin + LCDLines1.FrameStyle := TFrameStyle(rgFrameStyle.ItemIndex); +end; + +procedure TfrmMain.rgFrameColorStyleClick(Sender: TObject); +begin + LCDLines1.FrameColorStyle := TFrameColorStyle(rgFrameColorStyle.ItemIndex); +end; + +procedure TfrmMain.rgDotShapeClick(Sender: TObject); +begin + LCDLines1.DotShape := TDotShape(rgDotShape.ItemIndex); +end; + +procedure TfrmMain.rgFrameHeightClick(Sender: TObject); +begin + LCDLines1.FrameHeight := TFrameHeight(rgFrameHeight.ItemIndex); +end; + +procedure TfrmMain.seDisplayCharCountChange(Sender: TObject); +begin + LCDLines1.DisplayCharCount := seDisplayCharCount.Value; +end; + +procedure TfrmMain.seDotSizeChange(Sender: TObject); +begin + LCDLines1.DotSize := seDotSize.Value; +end; + +procedure TfrmMain.seDotsSpaceChange(Sender: TObject); +begin + LCDLines1.DotsSpace := seDotsSpace.Value; +end; + +procedure TfrmMain.seFrameSizeChange(Sender: TObject); +begin + LCDLines1.FrameSize := seFrameSize.Value; +end; + +procedure TfrmMain.seHeigthChange(Sender: TObject); +begin + LCDLines1.Height := seHeigth.Value; +end; + +procedure TfrmMain.seDisplayLineCountChange(Sender: TObject); +begin + LCDLines1.DisplayLineCount := seDisplayLineCount.Value; +end; + +procedure TfrmMain.seWidthChange(Sender: TObject); +begin + LCDLines1.Width := seWidth.Value; +end; + +end. diff --git a/components/industrialstuff/industrial.lpk b/components/industrialstuff/industrial.lpk index 17f88239a..7604d5f16 100644 --- a/components/industrialstuff/industrial.lpk +++ b/components/industrialstuff/industrial.lpk @@ -28,79 +28,84 @@ <Description Value="Industrial-themed components and gauges: - LED indicators - LED seven-sigment display +- Multi-line LCD display - Gauges -- stop-light lamps -- analog gauges -- thermometer-like gauge -- knob -- on/off switch -- multislider"/> +- Stop-light lamps +- Analog gauges +- Thermometer-like gauge +- Knob +- On/off switch +- Multislider"/> <License Value="MPL + GPL + modified LGPL (see unit headers)."/> <Version Minor="5"/> - <Files Count="14"> - <Item1> + <Files> + <Item> <Filename Value="source\indled.pas"/> <UnitName Value="IndLed"/> - </Item1> - <Item2> + </Item> + <Item> <Filename Value="source\sensors.pas"/> <UnitName Value="Sensors"/> - </Item2> - <Item3> + </Item> + <Item> <Filename Value="source\AllIndustrialRegister.pas"/> <HasRegisterProc Value="True"/> <UnitName Value="AllIndustrialRegister"/> - </Item3> - <Item4> + </Item> + <Item> <Filename Value="source\lednumber.pas"/> <UnitName Value="LedNumber"/> - </Item4> - <Item5> + </Item> + <Item> <Filename Value="source\indgnoumeter.pas"/> <UnitName Value="indGnouMeter"/> - </Item5> - <Item6> + </Item> + <Item> <Filename Value="source\AdvLed.pas"/> <UnitName Value="AdvLed"/> - </Item6> - <Item7> + </Item> + <Item> <Filename Value="source\indcyBaseLed.pas"/> <UnitName Value="indcyBaseLed"/> - </Item7> - <Item8> + </Item> + <Item> <Filename Value="source\indcyClasses.pas"/> <UnitName Value="indcyClasses"/> - </Item8> - <Item9> + </Item> + <Item> <Filename Value="source\indcyGraphics.pas"/> <UnitName Value="indcyGraphics"/> - </Item9> - <Item10> + </Item> + <Item> <Filename Value="source\indcyTypes.pas"/> <UnitName Value="indcyTypes"/> - </Item10> - <Item11> + </Item> + <Item> <Filename Value="source\a3naloggauge.pas"/> <UnitName Value="A3nalogGauge"/> - </Item11> - <Item12> + </Item> + <Item> <Filename Value="source\mknob.pas"/> <UnitName Value="MKnob"/> - </Item12> - <Item13> + </Item> + <Item> <Filename Value="source\switches.pas"/> <UnitName Value="switches"/> - </Item13> - <Item14> + </Item> + <Item> <Filename Value="source\indsliders.pas"/> - <UnitName Value="indsliders"/> - </Item14> + <UnitName Value="indSliders"/> + </Item> + <Item> + <Filename Value="source\indlcddisplay.pas"/> + <UnitName Value="indLCDDisplay"/> + </Item> </Files> <LazDoc Paths="D:\Prog_Lazarus\svn\lazarus-ccr\components\industrialstuff\fpdoc"/> - <RequiredPkgs Count="1"> - <Item1> + <RequiredPkgs> + <Item> <PackageName Value="IDEIntf"/> - </Item1> + </Item> </RequiredPkgs> <UsageOptions> <UnitPath Value="$(PkgOutDir)"/> diff --git a/components/industrialstuff/industrial.pas b/components/industrialstuff/industrial.pas index 88a6adec5..1e3c74088 100644 --- a/components/industrialstuff/industrial.pas +++ b/components/industrialstuff/industrial.pas @@ -10,7 +10,7 @@ interface uses IndLed, Sensors, AllIndustrialRegister, LedNumber, indGnouMeter, AdvLed, indcyBaseLed, indcyClasses, indcyGraphics, indcyTypes, A3nalogGauge, MKnob, - switches, indSliders, LazarusPackageIntf; + switches, indSliders, indLCDDisplay, LazarusPackageIntf; implementation diff --git a/components/industrialstuff/resources/industrial_icons.txt b/components/industrialstuff/resources/industrial_icons.txt index 667541f2f..c49e62dd7 100644 --- a/components/industrialstuff/resources/industrial_icons.txt +++ b/components/industrialstuff/resources/industrial_icons.txt @@ -28,3 +28,6 @@ tonoffswitch_200.png tmultislider.png tmultislider_150.png tmultislider_200.png +tlcddisplay.png +tlcddisplay_150.png +tlcddisplay_200.png diff --git a/components/industrialstuff/resources/tlcddisplay.png b/components/industrialstuff/resources/tlcddisplay.png new file mode 100644 index 0000000000000000000000000000000000000000..e0b0e31f827d6d81ec8cf2885441d4de65926563 GIT binary patch literal 596 zcmV-a0;~OrP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00009a7bBm000MJ z000MJ0hPnJwg3PC8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10pUqR zK~zYI?N!ZA!axxIrY*El6K{ae;8Um(^%YF?pfLz);G$=J1dT?(pF~Z31!52qo<$S+ z@z_HtbjL%xWi2&w;bNT2&hG5|ecx<L%#3M@Hr43=2__MP&d%NeXdnVq!sT9Ffp|S` z4PqEz=FmX~md?>2s>Io&#Q-p()!t_FX=&W6mpjZ1Fr%`XO9KR5^HI&cRy&^X0A?7Z zQ8}ASNxwq9(shN$egYb$ds;ur<m;6#h(JVm$R1?2UoP7KFrz26eB-7g3%Od_N$)pq zIskCFyqhXD?|ZVV^X1)Cv3b{ZS+Eb00*&pt0?Z(7oPT@Z2-)py!U_wUO;{A#035d- zdjl3>2a{p^n<z2tfg|LZp)w8t&l|-BKQ6;#!K&l!S|Q}8@LKKuI#F>QY}U>{!0dCd zc9>C%EH&<WQoml!rM7Ap?Qb1Kg?YS#F-VlX?YZJ7SYn|h3LaRTlRS^|6O8Rx<;uPC z%3eCD>Ew3+Ou(Qo>Kh3;2z1qU(t7-Kg~uQQ;q>$kfF6C~QRwCjQ&S0y!ZoKSLp1DR zU&y<o4t|;lb@bxCH$f5hu>YN(AdUgcT7=^e=I4Qa-}iDHf@v~LlfpBpOPdsR?>Gd@ i8tDM&|Cjmq6MO;sA|a29gd89M0000<MNUMnLSTZMtP2(Z literal 0 HcmV?d00001 diff --git a/components/industrialstuff/resources/tlcddisplay_150.png b/components/industrialstuff/resources/tlcddisplay_150.png new file mode 100644 index 0000000000000000000000000000000000000000..74e815ae2c216d5623464e231a78f6ea2643c247 GIT binary patch literal 1070 zcmV+}1kwA6P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ00009a7bBm000XT z000XT0n*)m`~Uy|8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11G`B? zK~z|U?N`l@Q&klIo%b=X^V+c>1kjjaf`r6L7$GJQP0WxCR9qOt!jNb*vOy)VcL_@u zM#BbzF8v1vqZphJg_VegkYN-V9O?`VEg#e3bEfTU-*M4-?Rodz*SCa4&!+F*dp>^W zch9*eC1%FcB*v2lph_Q5n)Css$x{c&q7x^MfQZ0MAnLvW>Y9iU1nBIA=e_KD`Dn-F z&i?AR1>jRKTOb0M0U`+Jp(7v&x_hCHe8W`R&`$1$K0<wsy%jT*N;0tgP6MU-kcmkk z>UxzSC9Sq%Ve`wb4DffQ<j+1X`O?we;W5__n(UZ1$-q<d)5}57ihwZ<6BEPRT^XiW zE&Deri@r?A0>F{XR)0Sn-IJHbled2LW~=vn8RUb}@n>#UN{yGEecq9}KP_BeX#lcz zU<0K3JXgHx-B`NoOFc`a{;e&qWZ&MpD|h((sghKDb7ZG`YT}~}pIkUo?yv-4cImGF z#g)m51p3+Q@2{UKUR(a|_V51zz=0Qc<qDg}vWI^>U6R*5F}!{7>o<;UJUVrzTnk#< zW=P&A0Gmv5%>lz}HM$kZ48t&J&>k@4l>tDDz+ST+$o=($LuS^_bV^~sFv+zu<TdMo zte0EWlK=Dk_2s6hqZmUHgan$pudYK~B7JiJn0`3ln11k2L;A2{6|V+SJ4a0*U~RC7 zeNwV&BFwO~KmZ)rx;rPqtji3UF=qhQX0m2sWQQxyE-uWh%vDQ%45XT%CQ%E_8m@tN zw!Jze*MB~`6QMSAw8>p#jlVD&Y3KKTIJwB}7diROQbCCtVjV;8e*fj7M1FAFYeQSs zY_ioLe^nM6pZ|7tN$!2M@8gY=H-GWIoojbl;zOwc*JUV)UKTYX^};R-0#>`nH3tma zuqam4I>wY5wv@q$$hUN$It|6pjD{pOdX1;hT?b_nLpre1QJ?^pqOz;l?;qLeo*X~4 z!6AdXHKdzmNuV@YuFYi4!thw6s4p(eEEoU1?}s4g9+&+~cm7x@jO>WaN82=M=Fvi( zMMCXamNdE3K%qyMiTb#FZ?<-&JXiZ>|FP$!-nrsc@AS3vRT+bD{P;WoGsa57>nbzM z*%>3I!wj!k4`TMr$XSjdgZtd#daKEuxT_4sndntN0-Wd90<EpI5ohXr)akdcOb1E{ z-Z9cSQXe=SC|zROw$JCsP_K72Yc)b9!*Cpm?CZ{IH9|g*j-KNXs#U;o^!A~Twl3>p oQUAYviu3`cNgq&}^Z}*G|I9*a4zk<3od5s;07*qoM6N<$f}5%c*Z=?k literal 0 HcmV?d00001 diff --git a/components/industrialstuff/resources/tlcddisplay_200.png b/components/industrialstuff/resources/tlcddisplay_200.png new file mode 100644 index 0000000000000000000000000000000000000000..bc036ff084edf66eba5777ac94003ada09f710a2 GIT binary patch literal 1225 zcmV;)1UCDLP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11Xf8z zK~!jg?O9K2BvlZvdhgAjovaDClLRmO4g3Hu=!&p{UqD6iu!76_2UZpoJgCVYye&u$ zDkP``79!p~DD0BORX>C$FD8>jjLvMPXQp3y=<b=C>U!NHduSHAE<LZ`tNQ(_-g{Nm z2@(-J&SI)2@TgKdP_@(!R4ugwRZHza)#7k-^A7-UfC#{=ayI5q0R6Z2<TkiXO)q;V zv5R=5Iu3|v?xi#+NipR@C%8zPg2Z&Jty4&IajKUZF#jEjT*!tb6dG$-Ax`PM0hHlN z7fHnssSv0}p4;X@lX#kKxeMw0<Op#vv29zIudd}B1b`d+-}I(1Oy~A<Z>(D5pg%hE z&X`<qK6$WrGV<{}W-4v#aO2V|7c{($2YV+&@HEGfD80M|XS~~4wwl3Q#L{v1+={h` z_+)#D9NL@%nCS{VKm-H>7oS*dsBp#sOrl(XU2coh$uC}bYpv-VUi;~*!yFJIY+t#) z9*xKJ?!BE}?p^@E2m8B6Xe<DE&H_Gr_Vunc4&J}_^$`!o*5#{fk)P1b`@6k_hX+72 zecrnCa<^p~_|eaIjs}y6GOi8~QM+gz*ECJ*us?~syiAA)9osY(kT?l0hYwHV+<PKe z?W|Y>DP|ThNOn4!jOn2NS3GAkn?JW~Teg9i@TKg1{tjqqOQtg|t%cHO=!;KFsa!{3 zzIS)0hXgS2<GFykTox)ygB+O8hvtfELz#oZ&R{a~8ip&^RwP8aD4N>ZP?6-K1&`_G z9Vn}$Ma6Cr652a$ceLap*Ag)Y0+HHz@$GeKJN7KI1oXC^e^ad=AKu?R0<?M+miFXW zNj9@qBH(4mHgg?oY<Ox^sx5@;$Klz(F?pfSrKs;xWR``vGJEyf51;=jNg@E;dFjSe zQ{&1Jxc1|hhZ^AamFw%H$%NjyyWJ}!7dlqL!SXDm%^6d=zCVe)MxtYz#(|;S(I_C9 z!(!_VWbJgB5|>aT$BFRW)S9$KMA}s{QnCYO86=dIIMJd!|9?_t*$Lq5=hA54GO7S_ zu4tFa>@M;S0B$|=>V>AWxcTe%Cui}P^+EvoOUy;<!=;4kLnxQ?c@0m&xVYSHG_6Ae zvKvi1+=ZhrBNXVNLf;Xe{_@?i2eCVdaC86Lo}sYb$G`0zk7G{{{Ve*)5h9{#Rw;@| z=&T0{S*Q;DetIw_8596G82lYu>w<d6{eR-Kcr^QdPx&BhY$Sh`V8$dF^)hPh1tKgp zS_VDA`Swz}v-95r({?#<T+e5PQ(zAK*pv4;+~f|(^Qe_>0i;Hr2nM5}2Sn)iBi&I= zpV^q!4=rFyD`6nJ19H)#tuEIKIahWBLlSV3+cG&LkCHOAwVI7kVUyTJJC?3@&~85s ztrkKQ&9sL@gjOpVXLG|LLc2YC^0j=-b>x`aSXlu$J<aB6ZcT=*iQtCyKlv(_+JUO2 ncA#ph9jIDr2db9G-huxB_&*DsuA@>J00000NkvXXu0mjfPT@v2 literal 0 HcmV?d00001 diff --git a/components/industrialstuff/source/AllIndustrialRegister.pas b/components/industrialstuff/source/AllIndustrialRegister.pas index 5982d8f93..c85842067 100644 --- a/components/industrialstuff/source/AllIndustrialRegister.pas +++ b/components/industrialstuff/source/AllIndustrialRegister.pas @@ -11,8 +11,8 @@ interface uses - Classes, LResources, AdvLed, IndLed, LedNumber, Sensors, IndGnouMeter, - A3nalogGauge, MKnob, Switches, indSliders; + Classes, LResources, AdvLed, IndLed, LedNumber, Sensors, indGnouMeter, + A3nalogGauge, MKnob, Switches, indSliders, indLCDDisplay; procedure Register; @@ -26,7 +26,7 @@ begin RegisterComponents ('Industrial',[ TAdvLed, TIndLed, TLedNumber, TStopLightSensor, TAnalogSensor, TA3nalogGauge, TindGnouMeter, - TmKnob, TOnOffSwitch, TMultiSlider + TmKnob, TOnOffSwitch, TMultiSlider, TLCDDisplay ]); end; diff --git a/components/industrialstuff/source/indlcddisplay.pas b/components/industrialstuff/source/indlcddisplay.pas new file mode 100644 index 000000000..48e4a7d45 --- /dev/null +++ b/components/industrialstuff/source/indlcddisplay.pas @@ -0,0 +1,898 @@ +{ + ***************************************************************************** + See the file COPYING.modifiedLGPL.txt, included in your Lazarus installation + for details about the license. + ***************************************************************************** + Based on LCDLine by Yuriy Tereshchenko + Initial Lazarus port and multi-line extension: Boban Spasic (spasic@gmail.com) + Further optimizations and extensions: Werner Pamler +} +unit indLCDDisplay; + +interface + +uses + SysUtils, Classes, Controls, fgl, Graphics, LResources, LCLIntf; + +type + TFrameStyle = (fsRelief, fsNone, fsLowered, fsRaised); + TFrameColorStyle = (stWindows, stColor); + TFrameHeight = (fhDouble, fhSingle); + TDotShape = (stSquare, stRound); + TColorScheme = (csCustom, csBlue, csGreen, csInvGreen); + +type + TDotMatrix = array of integer; + TDotMatrixList = specialize TFPGMap<string, TDotMatrix>; + + TLCDDisplay = class(TGraphicControl) + private + BitMap: TBitMap; + { + one char consists of Col x Row of dots + dots have size and space between dots + } + FDotSize: integer; // dot size in pixels + FDotsSpace: integer; // inter-dots space in pixels + FDotColsCount: integer; // number of dot-cols in char matrix + FDotRowsCount: integer; // number of dot-rows in char matrix + FCharCount: integer; + FGlobalDotColsCount: integer; + FCharWidth: integer; + + FFrameSize: integer; + FBoardWidth: integer; + FBoardHeight: integer; + FLEDWidth: integer; + FLEDHeight: integer; + + FFrameColor: TColor; + FBoardColor: TColor; + FDotColorOn: TColor; + FDotColorOff: TColor; + + FLenText: integer; + FDisplayLineCount: integer; + FDisplayCharCount: integer; + FLines: TStringList; + FCharSpace: boolean; + FColorScheme: TColorScheme; + FCountOn: integer; + FFrameStyle: TFrameStyle; + FFrameHeight: TFrameHeight; + FFrameColorStyle: TFrameColorStyle; + FDotShape: TDotShape; + + FCharList: TDotMatrixList; + + procedure SetDotShape(const Value: TDotShape); + procedure SetFrameColorStyle(const Value: TFrameColorStyle); + procedure SetFrameHeight(const Value: TFrameHeight); + procedure SetFrameStyle(const Value: TFrameStyle); + procedure SetCharSpace(const Value: boolean); + procedure SetColorScheme(const Value: TColorScheme); + + function GetCharCount: longint; + function GetGlobalDotColsCount: longint; + procedure SetDisplayLineCount(const Value: integer); + procedure SetDisplayCharCount(const Value: integer); + procedure SetLines(const Value: TStringList); + procedure SetDotColorOff(const Value: TColor); + procedure SetDotColorOn(const Value: TColor); + procedure SetBoardColor(const Value: TColor); + procedure SetFrameColor(const Value: TColor); + procedure SetFrameSize(const Value: integer); + procedure SetDotSize(const Value: integer); + procedure SetDotsSpace(const Value: integer); + + function CalcCharCount: integer; + procedure InitCharList(AHorDots, AVertDots: integer); + //calculate widths and heigths of the char matrix, background border and frame + procedure DrawCalc(); + //draw frame + procedure DrawBorder(); + //background grid of dots that are off + procedure DrawGrid(); + //space between chars + procedure DrawSpace(); + //call DrawChar for every char + procedure DrawText(); + //call DrawDot for every dot that is on + procedure DrawChar(Row, Col, NChar: integer); + procedure DrawDot(Row, Col: integer; DotColor: TColor); + //draw frame shadow + procedure DrawShadow(StartP, EndP: TPoint; LineColor1, LineColor2: TColor); + procedure DrawBitmapToCanvas(); + + protected + procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; + {%H-}WithThemeSpace: boolean); override; + procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; + const AXProportion, AYProportion: double); override; + procedure Paint; override; + + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + procedure AddDotMatrix(AChar: string; const Dots: array of integer); + + property DotColsCount: integer read FDotColsCount; + property DotRowsCount: integer read FDotRowsCount; + + property CharCount: longint read GetCharCount; + property GlobalDotColsCount: longint read GetGlobalDotColsCount; + + + published + property AutoSize; + property BorderSpacing; + property ShowHint; + property Visible; + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + + property DotSize: integer read FDotSize write SetDotSize default 4; + property DotsSpace: integer read FDotsSpace write SetDotsSpace default 1; + property FrameSize: integer read FFrameSize write SetFrameSize default 8; + + property FrameColor: TColor read FFrameColor write SetFrameColor default clBtnFace; + // To use BoardColor, ColorScheme must be set to csCustom + property BoardColor: TColor read FBoardColor write SetBoardColor default clBlack; + // To use DotColorOn, ColorScheme must be set to csCustom + property DotColorOn: TColor read FDotColorOn write SetDotColorOn default clSkyBlue; + // To use DotColorOff, ColorScheme must be set to csCustom + property DotColorOff: TColor read FDotColorOff write SetDotColorOff default clTeal; + // Vertical screen size in chars + // Without AutoSize, if the frame is too small + // a part off the text will not be visible + // e.g. frame is big enough for one line + // and the text contains 3 lines + // - just the middle line will be visible + property DisplayLineCount: integer read FDisplayLineCount write SetDisplayLineCount default 2; + // Horizontal screen size in chars + // Set to <=0 (zero) to have a real AutoSize + // Has no effect without AutoSize + property DisplayCharCount: integer read FDisplayCharCount write SetDisplayCharCount default 10; + // The text to display + // It will be truncated according + // to ScreenRowCount and ScreenColCount + property Lines: TStringList read FLines write SetLines; + // Insert one-dot space between chars + property CharSpace: boolean read FCharSpace write SetCharSpace default False; + // Pre-defined color schemes + // Set to csCustom in order to use + // the BoardColor, DotColorOn and DotColorOff + property ColorScheme: TColorScheme + read FColorScheme write SetColorScheme default csCustom; + property FrameStyle: TFrameStyle + read FFrameStyle write SetFrameStyle default fsRelief; + property FrameHeight: TFrameHeight + read FFrameHeight write SetFrameHeight default fhDouble; + property FrameColorStyle: TFrameColorStyle + read FFrameColorStyle write SetFrameColorStyle default stWindows; + property DotShape: TDotShape read FDotShape write SetDotShape default stSquare; + end; + +implementation + +uses + Dialogs, LazUTF8, LazUnicode; + +constructor TLCDDisplay.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + ControlStyle := ControlStyle + [csOpaque]; + + Width := 156; + Height := 76; + + FDisplayLineCount := 2; + FDisplayCharCount := 10; + + FCharList := TDotMatrixList.Create; + FCharList.Sorted := True; + + FDotColsCount := 5; + FDotRowsCount := 7; + InitCharList(FDotColsCount, FDotRowsCount); + + FDotSize := 4; + FDotsSpace := 1; + FFrameSize := 8; + FBoardWidth := 4; + + FFrameColor := clBtnFace; + FBoardColor := clBlack; + FDotColorOn := clSkyBlue; + FDotColorOff := clTeal; + + BitMap := TBitMap.Create; + FCountOn := 255; + + FLines := TStringList.Create; +end; + +destructor TLCDDisplay.Destroy; +begin + BitMap.Free; + FCharList.Free; + FLines.Free; + inherited Destroy; +end; + +procedure TLCDDisplay.AddDotMatrix(AChar: string; const Dots: array of integer); +var + matrix: TDotMatrix = nil; + i: integer; +begin + if Length(Dots) <> FDotRowsCount then + raise Exception.Create('AddDotMatrix: Incorrect number of rows.'); + SetLength(matrix, FDotRowsCount); + for i := 0 to FDotRowsCount - 1 do + matrix[i] := Dots[i]; + FCharList.Add(AChar, matrix); +end; + +procedure TLCDDisplay.CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer; + WithThemeSpace: boolean); +begin + FCharWidth := (DotSize * FDotColsCount) + (DotsSpace * (FDotColsCount + 1)); //pixels + FCharCount := CalcCharCount; + FGlobalDotColsCount := (FCharCount * FDotColsCount) + (FCharCount - 1); //dots + + // total matrix width + FLEDWidth := (FGlobalDotColsCount * DotSize) + ((FGlobalDotColsCount - 1) * DotsSpace); + // total matrix height + FLEDHeight := (FDisplayLineCount * FDotRowsCount * (DotSize + DotsSpace)) + + ((FDisplayLineCount - 1) * (DotSize + DotsSpace)); + if FCharSpace then + FLEDHeight := FLEDHeight + ((FDisplayLineCount - 1) * DotsSpace); + + //background around text matrix - left/right pixels + FBoardWidth := DotSize + DotsSpace; + //background around text matrix - up/down pixels + FBoardHeight := DotSize + DotsSpace; + + //Total size incl. frame + PreferredWidth := FLEDWidth + (2 * FrameSize) + (2 * FBoardWidth); + PreferredHeight := FLEDHeight + (2 * FrameSize) + (2 * FBoardWidth); +end; + +procedure TLCDDisplay.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; + const AXProportion, AYProportion: double); +begin + inherited; + if AMode in [lapAutoAdjustWithoutHorizontalScrolling, lapAutoAdjustForDPI] then + begin + FDotSize := round(FDotSize * AXProportion); + FDotsSpace := round(FDotsSpace * AXProportion); + FFrameSize := round(FFrameSize * AXProportion); + end; +end; + +procedure TLCDDisplay.DrawCalc(); +begin + FCharWidth := (DotSize * FDotColsCount) + (DotsSpace * (FDotColsCount + 1)); //pixels + FCharCount := ((Width - (2 * FrameSize)) + DotSize) div (FCharWidth + DotSize); + FGlobalDotColsCount := (FCharCount * FDotColsCount) + (FCharCount - 1); //dots + + // total matrix width + FLEDWidth := (FGlobalDotColsCount * DotSize) + ((FGlobalDotColsCount - 1) * DotsSpace); + // total matrix height + FLEDHeight := (FDisplayLineCount * FDotRowsCount * (DotSize + DotsSpace)) + + ((FDisplayLineCount - 1) * (DotSize + DotsSpace)); + if FCharSpace then + FLEDHeight := FLEDHeight + ((FDisplayLineCount - 1) * DotsSpace); + + FBoardWidth := (Width - 2 * FrameSize - FLEDWidth) div 2; + FBoardHeight := (Height - 2 * FrameSize - FLEDHeight) div 2; + + BitMap.Width := Width; + BitMap.Height := Height; +end; + +procedure TLCDDisplay.DrawBorder(); +var + FStart, FEnd: TPoint; + BStart, BEnd: TPoint; + Color1, Color2, Color3, Color4: TColor; + C: longint; + R, G, B: integer; +const + K1 = 4.637; + K2 = 1.364; + K3 = 1.372093; + K4 = 2.088495; +begin + + BStart.X := FrameSize; + BStart.Y := FrameSize; + BEnd.X := Width - FrameSize; + BEnd.Y := Height - FrameSize; + + with BitMap.Canvas do + begin + Brush.Color := FrameColor; + Pen.Color := FrameColor; + Rectangle(0, 0, BitMap.Width, BitMap.Height); + Brush.Color := FBoardColor; + Pen.Color := FBoardColor; + Rectangle(BStart.X, BStart.Y, BEnd.X, BEnd.Y); + end; + + if FrameStyle = fsNone then + Exit; + + if FrameColorStyle = stWindows then + C := ColorToRGB(clBtnFace) + else + C := ColorToRGB(FrameColor); + + R := RED(C); + G := GREEN(C); + B := BLUE(C); + + if FrameColorStyle = stWindows then + Color1 := clWhite + else + Color1 := RGBToColor(Round(R / K1 + 200), Round(G / K1 + 200), Round(B / K1 + 200)); + + Color2 := RGBToColor(Round(R / K2 + 68), Round(G / K2 + 68), Round(B / K2 + 68)); + Color3 := RGBToColor(Round(R / K3), Round(G / K3), Round(B / K3)); + + if FrameHeight = fhDouble then + Color4 := RGBToColor(Round(R / K4), Round(G / K4), Round(B / K4)) + else + Color4 := Color3; + + FStart.X := 0; + FStart.Y := 0; + FEnd.X := Width - 1; + FEnd.Y := Height - 1; + + BStart.X := FrameSize; + BStart.Y := FrameSize; + BEnd.X := Width - FrameSize - 1; + BEnd.Y := Height - FrameSize - 1; + + if (FrameStyle = fsRaised) or (FrameStyle = fsRelief) then + begin + DrawShadow(FStart, FEnd, Color1, Color4); + + if FrameHeight = fhDouble then + begin + FStart.X := FStart.X + 1; + FStart.Y := FStart.Y + 1; + FEnd.X := FEnd.X - 1; + FEnd.Y := FEnd.Y - 1; + DrawShadow(FStart, FEnd, Color2, Color3); + end; + end; + + if (FrameStyle = fsLowered) or (FrameStyle = fsRelief) then + begin + DrawShadow(BStart, BEnd, Color3, Color1); + if FrameHeight = fhDouble then + begin + BStart.X := BStart.X + 1; + BStart.Y := BStart.Y + 1; + BEnd.X := BEnd.X - 1; + BEnd.Y := BEnd.Y - 1; + DrawShadow(BStart, BEnd, Color4, Color2); + end; + end; +end; + +procedure TLCDDisplay.DrawShadow(StartP, EndP: TPoint; LineColor1, LineColor2: TColor); +begin + with BitMap.Canvas do + begin + Pen.Color := LineColor1; + MoveTo(EndP.X, StartP.Y); + LineTo(StartP.X, StartP.Y); + LineTo(StartP.X, EndP.Y); + + Pen.Color := LineColor2; + MoveTo(EndP.X, StartP.Y); + LineTo(EndP.X, EndP.Y); + LineTo(StartP.X - 1, EndP.Y); + end; +end; + +procedure TLCDDisplay.DrawGrid(); +var + y, x: integer; + NRow, NCol: integer; +begin + + NRow := (FDotRowsCount + 1) * FDisplayLineCount - 1; + NCol := (FDotColsCount + 1) * FCharCount - 1; + + for y := 0 to NRow - 1 do + for x := 0 to NCol - 1 do + DrawDot(y, x, FDotColorOff); + +end; + +procedure TLCDDisplay.DrawSpace(); +var + y, x: integer; + NRow, NCol: integer; + i, j, lc: integer; +begin + //i - vertical spaces + //j - horizontal spaces + for lc := 0 to FDisplayLineCount - 1 do + begin + NRow := FDotRowsCount + 1; + NCol := (FDotColsCount + 1) * FCharCount - 1; + + j := 0; + for y := 0 to (NRow * (lc + 1)) do + begin + i := 0; + for x := 0 to NCol - 1 do + begin + if ((i = 5) or (j = 7)) and (y < (NRow * (lc + 1))) then + begin + DrawDot(y, x, FBoardColor); + i := 0; + end + else + i := i + 1; + end; + if j = 7 then + begin + j := 0; + end + else + j := j + 1; + end; + end; +end; + +procedure TLCDDisplay.DrawText(); +var + x, y, c: integer; + DotRow: integer; + DotOn: boolean; + i, j: integer; + line: string; + ch: string; + matrix: TDotMatrix; +begin + for i := 0 to FDisplayLineCount - 1 do + begin + if i < FLines.Count then + begin + line := FLines[i]; + FLenText := UTF8Length(line); + + c := 0; + for ch in line do + begin + Inc(c); + if not FCharList.Find(ch, j) then + exit; + matrix := FCharList[ch]; + for y := 0 to FDotRowsCount - 1 do + begin + DotRow := matrix[y]; + for x := 0 to 4 do + begin + DotOn := DotRow and (1 shl (5 - x - 1)) > 0; + if DotOn then + DrawChar(y + 8 * i, x, c); + end; // for x + end; // for y + end; // for ch + end; + + if CharSpace then + DrawSpace(); + end; +end; + + +procedure TLCDDisplay.DrawChar(Row, Col, NChar: integer); +begin + + Col := Col + ((FDotColsCount + 1) * (NChar - 1)); + if Col > FGlobalDotColsCount - 1 then + Exit; + if Col < 0 then + Exit; + DrawDot(Row, Col, FDotColorOn); + +end; + +procedure TLCDDisplay.DrawDot(Row, Col: integer; DotColor: TColor); +var + DotR: TRect; +begin + DotR.Left := FrameSize + FBoardWidth + (DotSize + DotsSpace) * Col; + DotR.Top := FrameSize + FBoardHeight + (DotSize + DotsSpace) * Row; + DotR.Right := DotR.Left + DotSize; + DotR.Bottom := DotR.Top + DotSize; + + if FFrameHeight = fhSingle then + begin + if (DotR.Top <= FFrameSize) or (DotR.Bottom >= Height - FFrameSize) then + exit; + if (DotR.Left <= FFrameSize) or (DotR.Right >= Width - FFrameSize) then + exit; + end + else + begin + if (DotR.Top <= FFrameSize + 1) or (DotR.Bottom >= Height - FFrameSize - 1) then + exit; + if (DotR.Left <= FFrameSize + 1) or (DotR.Right >= Width - FFrameSize - 1) then + exit; + end; + + with BitMap.Canvas do + begin + Pen.Color := DotColor; + Brush.Color := DotColor; + + if DotShape = stSquare then + FillRect(DotR) + else + Ellipse(DotR.Left, DotR.Top, DotR.Right, DotR.Bottom); + end; +end; + +procedure TLCDDisplay.DrawBitmapToCanvas(); +begin + Canvas.Draw(0, 0, BitMap); +end; + +// Find the longest's line length +function TLCDDisplay.CalcCharCount: integer; +var + len: integer; + i, tmp: integer; +begin + len := 1; + if FDisplayCharCount > 0 then + Result := FDisplayCharCount + else + begin + for i := 0 to FDisplayLineCount - 1 do + begin + if i < Lines.Count then + begin + tmp := UTF8Length(Lines[i]); + if tmp > Len then Len := tmp; + end; + end; + Result := Len; + end; +end; + +procedure TLCDDisplay.InitCharList(AHorDots, AVertDots: integer); +var + i: integer; +begin + FCharList.Clear; + if (AHorDots = 5) and (AVertDots = 7) then + begin + for i := 0 to 32 do + AddDotMatrix(char(i), [0, 0, 0, 0, 0, 0, 0]); + AddDotMatrix('!', [4, 4, 4, 4, 4, 0, 4]); // #33 + AddDotMatrix('"', [10, 10, 0, 0, 0, 0, 0]); // #34 + AddDotMatrix('#', [0, 10, 31, 10, 31, 10, 0]); // #35 + AddDotMatrix('$', [4, 15, 20, 14, 5, 30, 4]); // #36 + AddDotMatrix('%', [25, 26, 2, 4, 8, 11, 19]); // #37 + AddDotMatrix('&', [12, 18, 20, 8, 21, 18, 13]); // #38 + AddDotMatrix('''', [4, 4, 0, 0, 0, 0, 0]); // #39 + AddDotMatrix('(', [2, 4, 8, 8, 8, 4, 2]); // #40 + AddDotMatrix(')', [8, 4, 2, 2, 2, 4, 8]); // #41 + AddDotMatrix('*', [0, 4, 21, 14, 21, 4, 0]); // #42 + AddDotMatrix('+', [0, 4, 4, 31, 4, 4, 0]); // #43 + AddDotMatrix(',', [0, 0, 0, 0, 12, 4, 8]); // #44 + AddDotMatrix('-', [0, 0, 0, 14, 0, 0, 0]); // #45 + AddDotMatrix('.', [0, 0, 0, 0, 0, 12, 12]); // #46 + AddDotMatrix('/', [1, 1, 2, 4, 8, 16, 16]); // #47 + AddDotMatrix('0', [14, 17, 19, 21, 25, 17, 14]); // #48 + AddDotMatrix('1', [4, 12, 4, 4, 4, 4, 14]); // #49 + AddDotMatrix('2', [14, 17, 1, 2, 4, 8, 31]); // #50 + AddDotMatrix('3', [14, 17, 1, 6, 1, 17, 14]); // #51 + AddDotMatrix('4', [2, 6, 10, 18, 31, 2, 2]); // #52 + AddDotMatrix('5', [31, 16, 30, 1, 1, 17, 14]); // #53 + AddDotMatrix('6', [14, 17, 16, 30, 17, 17, 14]); // #54 + AddDotMatrix('7', [31, 1, 1, 2, 4, 4, 4]); // #55 + AddDotMatrix('8', [14, 17, 17, 14, 17, 17, 14]); // #56 + AddDotMatrix('9', [14, 17, 17, 15, 1, 17, 14]); // #57 + AddDotMatrix(':', [0, 12, 12, 0, 12, 12, 0]); // #58 + AddDotMatrix(';', [0, 12, 12, 0, 12, 4, 8]); // #59 + AddDotMatrix('<', [2, 4, 8, 16, 8, 4, 2]); // #60 + AddDotMatrix('=', [0, 0, 31, 0, 31, 0, 0]); // #61 + AddDotMatrix('>', [8, 4, 2, 1, 2, 4, 8]); // #62 + AddDotMatrix('?', [14, 17, 1, 2, 4, 0, 4]); // #63 + AddDotMatrix('@', [14, 17, 19, 21, 23, 16, 15]); // #64 + AddDotMatrix('A', [14, 17, 17, 31, 17, 17, 17]); // #65 + AddDotMatrix('B', [30, 17, 17, 30, 17, 17, 30]); // #66 + AddDotMatrix('C', [14, 17, 16, 16, 16, 17, 14]); // #67 + AddDotMatrix('D', [30, 17, 17, 17, 17, 17, 30]); // #68 + AddDotMatrix('E', [31, 16, 16, 30, 16, 16, 31]); // #69 + AddDotMatrix('F', [31, 16, 16, 30, 16, 16, 16]); // #70 + AddDotMatrix('G', [14, 17, 16, 19, 17, 17, 14]); // #71 + AddDotMatrix('H', [17, 17, 17, 31, 17, 17, 17]); // #72 + AddDotMatrix('I', [14, 4, 4, 4, 4, 4, 14]); // #73 + AddDotMatrix('J', [1, 1, 1, 1, 17, 17, 14]); // #74 + AddDotMatrix('K', [17, 18, 20, 24, 20, 18, 17]); // #75 + AddDotMatrix('L', [16, 16, 16, 16, 16, 16, 31]); // #76 + AddDotMatrix('M', [17, 27, 21, 21, 17, 17, 17]); // #77 + AddDotMatrix('N', [17, 25, 21, 19, 17, 17, 17]); // #78 + AddDotMatrix('O', [14, 17, 17, 17, 17, 17, 14]); // #79 + AddDotMatrix('P', [30, 17, 17, 30, 16, 16, 16]); // #80 + AddDotMatrix('Q', [14, 17, 17, 17, 17, 14, 1]); // #81 + AddDotMatrix('R', [30, 17, 17, 30, 17, 17, 17]); // #82 + AddDotMatrix('S', [14, 17, 16, 14, 1, 17, 14]); // #83 + AddDotMatrix('T', [31, 4, 4, 4, 4, 4, 4]); // #84 + AddDotMatrix('U', [17, 17, 17, 17, 17, 17, 14]); // #85 + AddDotMatrix('V', [17, 17, 17, 17, 17, 10, 4]); // #86 + AddDotMatrix('W', [17, 17, 17, 17, 21, 27, 17]); // #87 + AddDotMatrix('X', [17, 10, 4, 4, 4, 10, 17]); // #88 + AddDotMatrix('Y', [17, 17, 17, 10, 4, 4, 4]); // #89 + AddDotMatrix('Z', [31, 1, 2, 4, 8, 16, 31]); // #90 + AddDotMatrix('[', [12, 8, 8, 8, 8, 8, 12]); // #91 + AddDotMatrix('\', [0, 16, 8, 4, 2, 1, 0]); // #92 + AddDotMatrix(']', [6, 2, 2, 2, 2, 2, 6]); // #93 + AddDotMatrix('^', [4, 10, 17, 0, 0, 0, 0]); // #94 + AddDotMatrix('_', [0, 0, 0, 0, 0, 0, 31]); // #95 + AddDotMatrix('`', [6, 4, 2, 0, 0, 0, 0]); // #96 + AddDotMatrix('a', [0, 0, 14, 1, 15, 17, 15]); // #97 + AddDotMatrix('b', [16, 16, 30, 17, 17, 17, 30]); // #98 + AddDotMatrix('c', [0, 0, 15, 16, 16, 16, 15]); // #99 + AddDotMatrix('d', [1, 1, 15, 17, 17, 17, 15]); // #100 + AddDotMatrix('e', [0, 0, 14, 17, 31, 16, 14]); // #101 + AddDotMatrix('f', [3, 4, 31, 4, 4, 4, 4]); // #102 + AddDotMatrix('g', [0, 0, 15, 17, 15, 1, 14]); // #103 + AddDotMatrix('h', [16, 16, 22, 25, 17, 17, 17]);// #104 + AddDotMatrix('i', [4, 0, 12, 4, 4, 4, 14]); // #105 + AddDotMatrix('j', [2, 0, 6, 2, 2, 18, 12]); // #106 + AddDotMatrix('k', [16, 16, 18, 20, 24, 20, 18]);// #107 + AddDotMatrix('l', [12, 4, 4, 4, 4, 4, 14]); // #108 + AddDotMatrix('m', [0, 0, 26, 21, 21, 21, 21]); // #109 + AddDotMatrix('n', [0, 0, 22, 25, 17, 17, 17]); // #110 + AddDotMatrix('o', [0, 0, 14, 17, 17, 17, 14]); // #111 + AddDotMatrix('p', [0, 0, 30, 17, 30, 16, 16]); // #112 + AddDotMatrix('q', [0, 0, 15, 17, 15, 1, 1]); // #113 + AddDotMatrix('r', [0, 0, 11, 12, 8, 8, 8]); // #114 + AddDotMatrix('s', [0, 0, 14, 16, 14, 1, 30]); // #115 + AddDotMatrix('t', [4, 4, 31, 4, 4, 4, 3]); // #116 + AddDotMatrix('u', [0, 0, 17, 17, 17, 19, 13]); // #117 + AddDotMatrix('v', [0, 0, 17, 17, 17, 10, 4]); // #118 + AddDotMatrix('w', [0, 0, 17, 17, 21, 21, 10]); // #119 + AddDotMatrix('x', [0, 0, 17, 10, 4, 10, 17]); // #120 + AddDotMatrix('y', [0, 0, 17, 17, 15, 1, 14]); // #121 + AddDotMatrix('z', [0, 0, 31, 2, 4, 8, 31]); // #122 + AddDotMatrix('{', [3, 4, 4, 8, 4, 4, 3]); // #123 + AddDotMatrix('|', [4, 4, 4, 4, 4, 4, 4]); // #124 + AddDotMatrix('}', [24, 4, 4, 2, 4, 4, 24]); // #125 + AddDotMatrix('~', [8, 21, 2, 0, 0, 0, 0]); // #126 + AddDotMatrix(#127, [0, 0, 0, 0, 0, 0, 0]); // #127 + end; +end; + +procedure TLCDDisplay.Paint(); +begin + DrawCalc(); + DrawBorder(); + DrawGrid(); + DrawText(); + DrawBitmapToCanvas(); +end; + +procedure TLCDDisplay.SetBoardColor(const Value: TColor); +begin + if Value = FBoardColor then + Exit; + FBoardColor := Value; + SetColorScheme(csCustom); +end; + +procedure TLCDDisplay.SetDotColorOff(const Value: TColor); +begin + if Value = FDotColorOff then + Exit; + FDotColorOff := Value; + SetColorScheme(csCustom); +end; + +procedure TLCDDisplay.SetDotColorOn(const Value: TColor); +begin + if Value = FDotColorOn then + Exit; + FDotColorOn := Value; + SetColorScheme(csCustom); +end; + +procedure TLCDDisplay.SetDotSize(const Value: integer); +begin + if Value = DotSize then + Exit; + FDotSize := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetDotsSpace(const Value: integer); +begin + if Value = DotsSpace then + Exit; + FDotsSpace := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetDotShape(const Value: TDotShape); +begin + if Value = DotShape then + Exit; + FDotShape := Value; + Invalidate; +end; + +procedure TLCDDisplay.SetFrameColor(const Value: TColor); +begin + if Value = FrameColor then + Exit; + FFrameColor := Value; + Invalidate; +end; + +procedure TLCDDisplay.SetFrameColorStyle(const Value: TFrameColorStyle); +begin + if Value = FrameColorStyle then + Exit; + FFrameColorStyle := Value; + Invalidate; +end; + +procedure TLCDDisplay.SetFrameHeight(const Value: TFrameHeight); +begin + if Value = FrameHeight then + Exit; + FFrameHeight := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetFrameSize(const Value: integer); +begin + if Value = FrameSize then + Exit; + FFrameSize := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetFrameStyle(const Value: TFrameStyle); +begin + if Value = FrameStyle then + Exit; + FFrameStyle := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetCharSpace(const Value: boolean); +begin + if Value = CharSpace then + Exit; + FCharSpace := Value; + Invalidate; +end; + +procedure TLCDDisplay.SetColorScheme(const Value: TColorScheme); +begin + if Value = FColorScheme then Exit; + case Value of + csBlue: begin + FBoardColor := clBlack; + FDotColorOff := clTeal; + FDotColorOn := clSkyBlue; + end; + csGreen: begin + FBoardColor := 5162664; + FDotColorOff := 5162664; + FDotColorOn := 2900284; + end; + csInvGreen: begin + FBoardColor := clBlack; + FDotColorOff := 2900284; + FDotColorOn := 5162664; + end; + csCustom: begin + end; + end; + FColorScheme := Value; + Invalidate; +end; + +procedure TLCDDisplay.SetDisplayLineCount(const Value: integer); +begin + if Value = FDisplayLineCount then + Exit; + FDisplayLineCount := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetDisplayCharCount(const Value: integer); +begin + if Value = FDisplayCharCount then + Exit; + FDisplayCharCount := Value; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +procedure TLCDDisplay.SetLines(const Value: TStringList); +var + i: integer; +begin + FLines.Clear; + for i := 0 to FDisplayLineCount - 1 do + begin + if i < Value.Count then + FLines.Add(Value[i]) + else + FLines.Add(' '); + end; + if AutoSize then + begin + InvalidatePreferredSize; + AdjustSize; + end; + Invalidate; +end; + +function TLCDDisplay.GetCharCount: longint; +begin + DrawCalc(); + Result := FCharCount; +end; + +function TLCDDisplay.GetGlobalDotColsCount: longint; +begin + DrawCalc(); + Result := FGlobalDotColsCount; +end; + +end. diff --git a/components/industrialstuff/source/industrial_icons.res b/components/industrialstuff/source/industrial_icons.res index 7a1a338caee421dafccecb9094e54459ce16434c..99d45981072719c21d6a9d6a874e1500a888d7fc 100644 GIT binary patch delta 2833 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 delta 9 QcmZ2Fm1*@~#tp0M02gNjzW@LL