├── .gitignore
├── CFX Development Group.groupproj
├── CodFluentUX.dpk
├── CodFluentUX.dproj
├── CodFluentUX.res
├── Demo
├── Backup
│ ├── CFXTest.dfm
│ └── CFXTest.pas
├── CFXDemo.dfm
└── CFXDemo.pas
├── FluentUXDemo.dpr
├── FluentUXDemo.dproj
├── FluentUXDemo.res
├── Icons.dcr
├── README.md
├── Source
├── CFX.AnimColection.pas
├── CFX.Animation.Component.pas
├── CFX.Animation.Main.pas
├── CFX.Animation.Utils.pas
├── CFX.Animations.pas
├── CFX.AppIntegration.pas
├── CFX.AppManager.pas
├── CFX.ArrayHelpers.pas
├── CFX.BlurFunctions.pas
├── CFX.BlurMaterial.pas
├── CFX.Button.pas
├── CFX.ButtonDesign.pas
├── CFX.Checkbox.pas
├── CFX.Classes.pas
├── CFX.Colors.pas
├── CFX.Constants.pas
├── CFX.Controls.pas
├── CFX.DesignEditors.pas
├── CFX.Dialogs.pas
├── CFX.Edit.pas
├── CFX.Effects.pas
├── CFX.Files.pas
├── CFX.FontIcons.pas
├── CFX.FormClasses.pas
├── CFX.FormTemplates.pas
├── CFX.Forms.pas
├── CFX.GDI.pas
├── CFX.Graphics.pas
├── CFX.Hint.pas
├── CFX.IconView.pas
├── CFX.ImageList.pas
├── CFX.Imported.pas
├── CFX.Instances.pas
├── CFX.Internet.pas
├── CFX.Layouts.pas
├── CFX.Linker.pas
├── CFX.Lists.pas
├── CFX.Math.pas
├── CFX.Messages.pas
├── CFX.PaintBox.pas
├── CFX.Panels.pas
├── CFX.PopupConnector.pas
├── CFX.PopupMenu.pas
├── CFX.Progress.pas
├── CFX.PropertyEditors.pas
├── CFX.QuickDialogs.pas
├── CFX.RadioButton.pas
├── CFX.RatingControl.pas
├── CFX.RegisterClass.pas
├── CFX.Registry.pas
├── CFX.ScrollBox.pas
├── CFX.ScrollText.pas
├── CFX.Scrollbar.pas
├── CFX.Selector.pas
├── CFX.Shapes.pas
├── CFX.Slider.pas
├── CFX.StandardIcons.pas
├── CFX.StringUtils.pas
├── CFX.TabStrip.pas
├── CFX.Template.pas
├── CFX.Test.pas
├── CFX.TextBox.pas
├── CFX.ThemeManager.pas
├── CFX.Threading.pas
├── CFX.TitlebarPanel.pas
├── CFX.ToolTip.pas
├── CFX.TypeInfo.pas
├── CFX.Types.pas
├── CFX.UXTheme.pas
├── CFX.Utilities.pas
├── CFX.VarHelpers.pas
└── CFX.Version.pas
└── Test
├── Backup
├── CFXTest.dfm
└── CFXTest.pas
├── CFXTest.dfm
├── CFXTest.pas
├── FluentUXTest.dpr
└── FluentUXTest.dproj
/.gitignore:
--------------------------------------------------------------------------------
1 | __history/
2 | __recovery/
3 | DCU/
4 | Win32/
5 | Win64/
6 | /*.identcache
7 | /*.local
8 | *.dcu
9 | *.local
10 | *.res
11 | *.identcache
12 | *.exe
--------------------------------------------------------------------------------
/CFX Development Group.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {54EBF4A5-D10E-4E74-8905-F51DC4399505}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Default.Personality.12
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/CodFluentUX.dpk:
--------------------------------------------------------------------------------
1 | {*============================================*}
2 | { Codrut Fluent UX Library }
3 | { }
4 | { Petculescu Codrut }
5 | { Copyright 2022 }
6 | { }
7 | { }
8 | { }
9 | { v0.1 }
10 | {*============================================*}
11 |
12 | {$IFDEF WIN32}
13 | {$DEFINE COMPILEDESIGN}
14 | {$ENDIF}
15 |
16 | package CodFluentUX;
17 |
18 | {$R *.res}
19 | {$R 'Icons.dcr'}
20 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
21 | {$ALIGN 8}
22 | {$ASSERTIONS ON}
23 | {$BOOLEVAL OFF}
24 | {$DEBUGINFO OFF}
25 | {$EXTENDEDSYNTAX ON}
26 | {$IMPORTEDDATA ON}
27 | {$IOCHECKS ON}
28 | {$LOCALSYMBOLS ON}
29 | {$LONGSTRINGS ON}
30 | {$OPENSTRINGS ON}
31 | {$OPTIMIZATION OFF}
32 | {$OVERFLOWCHECKS OFF}
33 | {$RANGECHECKS OFF}
34 | {$REFERENCEINFO ON}
35 | {$SAFEDIVIDE OFF}
36 | {$STACKFRAMES ON}
37 | {$TYPEDADDRESS OFF}
38 | {$VARSTRINGCHECKS ON}
39 | {$WRITEABLECONST OFF}
40 | {$MINENUMSIZE 1}
41 | {$IMAGEBASE $400000}
42 | {$DEFINE DEBUG}
43 | {$ENDIF IMPLICITBUILDING}
44 | {$IMPLICITBUILD ON}
45 |
46 | requires
47 | rtl,
48 | vcl,
49 | vclimg,
50 | vclwinx,
51 | {$IFDEF COMPILEDESIGN}
52 | DesignIDE,
53 | {$ENDIF}
54 | IndySystem,
55 | IndyProtocols,
56 | IndyCore;
57 |
58 | contains
59 | {$IFDEF COMPILEDESIGN}
60 | CFX.PropertyEditors in 'Source\CFX.PropertyEditors.pas',
61 | CFX.DesignEditors in 'Source\CFX.DesignEditors.pas',
62 | {$ENDIF}
63 | CFX.RegisterClass in 'Source\CFX.RegisterClass.pas',
64 | CFX.FormTemplates,
65 | CFX.Colors in 'Source\CFX.Colors.pas',
66 | CFX.Classes in 'Source\CFX.Classes.pas',
67 | CFX.VarHelpers in 'Source\CFX.VarHelpers.pas',
68 | CFX.AnimColection in 'Source\CFX.AnimColection.pas',
69 | CFX.Animations in 'Source\CFX.Animations.pas',
70 | CFX.Graphics in 'Source\CFX.Graphics.pas',
71 | CFX.Constants in 'Source\CFX.Constants.pas',
72 | CFX.Utilities in 'Source\CFX.Utilities.pas',
73 | CFX.Dialogs in 'Source\CFX.Dialogs.pas',
74 | CFX.ThemeManager in 'Source\CFX.ThemeManager.pas',
75 | CFX.ToolTip in 'Source\CFX.ToolTip.pas',
76 | CFX.Forms in 'Source\CFX.Forms.pas',
77 | CFX.ButtonDesign in 'Source\CFX.ButtonDesign.pas',
78 | CFX.Checkbox in 'Source\CFX.Checkbox.pas',
79 | CFX.Panels in 'Source\CFX.Panels.pas',
80 | CFX.StandardIcons in 'Source\CFX.StandardIcons.pas',
81 | CFX.Math in 'Source\CFX.Math.pas',
82 | CFX.BlurMaterial in 'Source\CFX.BlurMaterial.pas',
83 | CFX.Registry in 'Source\CFX.Registry.pas',
84 | CFX.BlurFunctions in 'Source\CFX.BlurFunctions.pas',
85 | CFX.GDI in 'Source\CFX.GDI.pas',
86 | CFX.Types in 'Source\CFX.Types.pas',
87 | CFX.PopupMenu in 'Source\CFX.PopupMenu.pas',
88 | CFX.Controls in 'Source\CFX.Controls.pas',
89 | CFX.FontIcons in 'Source\CFX.FontIcons.pas',
90 | CFX.ImageList in 'Source\CFX.ImageList.pas',
91 | CFX.Slider in 'Source\CFX.Slider.pas',
92 | CFX.Hint in 'Source\CFX.Hint.pas',
93 | CFX.Test in 'Source\CFX.Test.pas',
94 | CFX.TypeInfo in 'Source\CFX.TypeInfo.pas',
95 | CFX.Linker in 'Source\CFX.Linker.pas',
96 | CFX.TextBox in 'Source\CFX.TextBox.pas',
97 | CFX.StringUtils in 'Source\CFX.StringUtils.pas',
98 | CFX.RadioButton in 'Source\CFX.RadioButton.pas',
99 | CFX.ScrollBox in 'Source\CFX.ScrollBox.pas',
100 | CFX.Scrollbar in 'Source\CFX.Scrollbar.pas',
101 | CFX.Selector in 'Source\CFX.Selector.pas',
102 | CFX.Edit in 'Source\CFX.Edit.pas',
103 | CFX.PopupConnector in 'Source\CFX.PopupConnector.pas',
104 | CFX.Button in 'Source\CFX.Button.pas',
105 | CFX.IconView in 'Source\CFX.IconView.pas',
106 | CFX.ScrollText in 'Source\CFX.ScrollText.pas',
107 | CFX.ArrayHelpers in 'Source\CFX.ArrayHelpers.pas',
108 | CFX.FormClasses in 'Source\CFX.FormClasses.pas',
109 | CFX.Imported in 'Source\CFX.Imported.pas',
110 | CFX.Progress in 'Source\CFX.Progress.pas',
111 | CFX.Threading in 'Source\CFX.Threading.pas',
112 | CFX.Internet in 'Source\CFX.Internet.pas',
113 | CFX.Messages in 'Source\CFX.Messages.pas',
114 | CFX.RatingControl in 'Source\CFX.RatingControl.pas',
115 | CFX.Lists in 'Source\CFX.Lists.pas',
116 | CFX.Effects in 'Source\CFX.Effects.pas',
117 | CFX.AppManager in 'Source\CFX.AppManager.pas',
118 | CFX.QuickDialogs in 'Source\CFX.QuickDialogs.pas',
119 | CFX.Files in 'Source\CFX.Files.pas',
120 | CFX.Version in 'Source\CFX.Version.pas',
121 | CFX.AppIntegration in 'Source\CFX.AppIntegration.pas',
122 | CFX.Instances in 'Source\CFX.Instances.pas',
123 | CFX.PaintBox in 'Source\CFX.PaintBox.pas',
124 | CFX.TabStrip in 'Source\CFX.TabStrip.pas',
125 | CFX.UXTheme in 'Source\CFX.UXTheme.pas',
126 | CFX.TitlebarPanel in 'Source\CFX.TitlebarPanel.pas',
127 | CFX.Animation.Component in 'Source\CFX.Animation.Component.pas',
128 | CFX.Animation.Main in 'Source\CFX.Animation.Main.pas',
129 | CFX.Animation.Utils in 'Source\CFX.Animation.Utils.pas',
130 | CFX.Shapes in 'Source\CFX.Shapes.pas',
131 | CFX.Layouts in 'Source\CFX.Layouts.pas';
132 |
133 | end.
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/CodFluentUX.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codrax/Codrut-Fluent-Design-System/3ec621e0972527fca3f780b9d83f5325e3ce08bd/CodFluentUX.res
--------------------------------------------------------------------------------
/Demo/Backup/CFXTest.pas:
--------------------------------------------------------------------------------
1 | unit CFXTest;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UCL.Form,
8 |
9 | // CFX LIBRARY
10 | CFX.Forms, CFX.Colors, CFX.ThemeManager, Vcl.StdCtrls, Vcl.TitleBarCtrls,
11 | Vcl.ExtCtrls, Cod.Panels, Vcl.Imaging.jpeg, Cod.Button, CFX.Button,
12 | Vcl.Imaging.pngimage, Cod.Image, UCL.CheckBox, CFX.Checkbox, CFX.Panels;
13 |
14 | type
15 | TForm1 = class(FXForm)
16 | Label1: TLabel;
17 | Button2: TButton;
18 | Timer1: TTimer;
19 | FXButton1: FXButton;
20 | CImage1: CImage;
21 | FXButton2: FXButton;
22 | FXButton4: FXButton;
23 | FXButton5: FXButton;
24 | FXButton6: FXButton;
25 | FXButton3: FXButton;
26 | FXButton8: FXButton;
27 | procedure Button2Click(Sender: TObject);
28 | procedure Timer1Timer(Sender: TObject);
29 | private
30 | { Private declarations }
31 | public
32 | { Public declarations }
33 | end;
34 |
35 | var
36 | Form1: FXForm;
37 |
38 | implementation
39 |
40 | {$R *.dfm}
41 |
42 | procedure TForm1.Button2Click(Sender: TObject);
43 | begin
44 | Self.SmokeEffect := NOT Self.SmokeEffect;
45 | end;
46 |
47 | procedure TForm1.Timer1Timer(Sender: TObject);
48 | begin
49 | Self.SmokeEffect := false;
50 | end;
51 |
52 | end.
53 |
--------------------------------------------------------------------------------
/FluentUXDemo.dpr:
--------------------------------------------------------------------------------
1 | program FluentUXDemo;
2 |
3 | uses
4 | Vcl.Forms,
5 | CFX.ThemeManager,
6 | CFXDemo in 'Demo\CFXDemo.pas' {Form1},
7 | CFX.Template in 'Source\CFX.Template.pas';
8 |
9 | {$R *.res}
10 | begin
11 | Application.Initialize;
12 |
13 | Application.MainFormOnTaskbar := True;
14 | Application.CreateForm(TForm1, Form1);
15 | Application.Run;
16 | end.
17 |
--------------------------------------------------------------------------------
/FluentUXDemo.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codrax/Codrut-Fluent-Design-System/3ec621e0972527fca3f780b9d83f5325e3ce08bd/FluentUXDemo.res
--------------------------------------------------------------------------------
/Icons.dcr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codrax/Codrut-Fluent-Design-System/3ec621e0972527fca3f780b9d83f5325e3ce08bd/Icons.dcr
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Codrut-Fluent-Design-System
2 | Codrut Fluent Design System is a suite of components made to mimic the Interface of Windows 11, the Fluent Design System, This is not to be confused with CodrutsVisualLibrary, as that is ajust a suite of independent components
3 |
4 | ## Notice: Under Construction!!
5 | The component package is not at a state where it can be considered finished without encountering bugs. This package has advanced to Its **Beta** Stage.
6 |
7 | ## Components
8 | - Minimise Panel, a Panel that is able to minimise itself with a optional animation, works best with DoubleBuffered and for more panels, use Align.alTop
9 | - Panel, a TPanel component with inproved features and the ability to sync to the System Color Theme
10 | - Button, a powerfull button in the Fluent Design style, customizable with custom colors, shapes, button types, long presses, 2-states, checkable, dropdown, and more. It can also be aligned Vertically and Horizontalle, and the Icon as well
11 | - ButtonDesign, a very customizable and advanced button from CodrutsVisualLibrary with inproved features, can be styled multiple ways, icon support, gradient, accent color sync, align, subtext, automatic font sizing and more
12 | - Radio Button, a radio button component with multiple aligmnets
13 | - Scrollbar, a simple scrollbar that minimised itself to a line when not in use
14 | - Scrollbox, a modern scrollbox that uses the modern scrollbars
15 | - Selector, a component which allows to select between multiple options with a animation when switching
16 | - Checkbox, a animated checkbox that supports 3 states
17 | - Edit Box, a flue edit box with vertical alignment support
18 | - Standard icon, a drawable TGraphicControl icon component that has multiple icons
19 | - IconV iew, a simple icon view control that relies on the FXIcon class for drawing & storing. Very lightweight
20 | - Slider, a slider with tick support, hint previews and more features
21 | - Blur Material, a acrilic blur box that can be drawn from the wallaper or a screenshot of the screen. Great for Windows Fluent Design System like apps
22 | - Popup Menu, it supports (FXIconSelect) icons and can have multiple sub-menus, It used a acrylic effect for the background with a accent colored border. It also has Checkable items, Radio Items, separators and as mentioned before, It can go infinite layers deep
23 | - Text Box, a simple Label-Like component with more features. It also has a few components dependent on the base class
24 | - Animated Text Box, a label box with the ability to animate from a TStringList of values
25 | - Scroll Text, a box with scrolling text. The fade size, fade width and animation speed can be adjusted
26 | - Progress Bar, a simple animated progress bar with 4 different styles
27 | - ImageList, a work-in-progress component that can hold images
28 | - Simple shapes, such as Square, Circle, Triangle and more planned in the future
29 | - Linear Draw List, a list with a number of elements that are all drawn in a Notify Event given, the layouts are calculated automatically and you can provide a custom Content Justification and orientation.
30 | - Linear Control List, a linear draw list that accepts CFX controls, similar to a TControlList but more customizable in terms of layout and custom drawing.
31 | - Effects, you can overlay effects onto controls. Effects can be Blur, Monocrome, Invert, Deepfry, Color, Zoom and more!
32 | - Layout, which is a component container for storing other controls inside
33 | - Scrollable Layout, is another layout-based control but with two scrollbars for scrolling the control.
34 |
35 | ## Apps made with CodrutFluentDesignSystem
36 | - Codrut Printing - https://github.com/Codrax/Codrut-Printing
37 | - File Sync Manager - (work in progress)
38 |
39 | ## Creating a CFX Visual Application
40 | 1) Create a new VCL Application in Delphi
41 |
42 |
43 | 2) Include all required Unit Files
44 | The required unit files are:
45 | `CFX.Forms`, `CFX.Types`, `CFX.ThemeManager`, `CFX.Colors` and `CFX.Classes`
46 |
47 | 3) Change Main Form class to FXForm
48 |
49 |
50 | 4) Place some components
51 | You can add any components from the Palette. They are grouped under `CFX Main`, `CFX.Shapes`, `CFX Animations` and `CFX Utils`.
52 |
53 | 5) Adding the Application Manager (`FXAppManager`) from `CFX Utils`
54 | The App Manager is an optional feature for your application that automatically creates a AppData directory for your application and saves the location on screen where the form was closed, and re-loads that on startup. It can also start an automatic update check for you sending a POST request to the APIEndpoint provided provided under the following format:
55 | ```
56 | {
57 | "mode":"getversion",
58 | "app":"app-api-name"
59 | }
60 | ```
61 | And It expects a result in the format of
62 | ```
63 | {
64 | "version":"1.0.0",
65 | "updateurl":"https://server.com/download-file.exe" // optional
66 | {
67 | ```
68 |
69 | 7) Include additional units (optional)
70 | Some of the most usefull units to use are:
71 | - `CFX.Dialogs`, For dialogs and the classes for each type
72 | - `CFX.QuickDialogs`, For executing a quick dialog, with procedures as `OpenMessage()` or `OpenDialog()` or `OpenInput()`
73 | - `CFX.FormClasses`, This unit contains all classes for Full-Screen dialogs. Such as confirmations, status
74 |
75 | ## Image Gallery
76 | > The following images are ALPHA versions of the component suite, the components are expected to change in the future.
77 |
78 | 
79 | 
80 | 
81 | 
82 | 
83 | 
84 | 
85 | 
86 | 
87 | 
88 |
89 |
--------------------------------------------------------------------------------
/Source/CFX.AnimColection.pas:
--------------------------------------------------------------------------------
1 | unit CFX.AnimColection;
2 |
3 | interface
4 | type
5 | TIntAniCollection = class
6 | // Linear
7 | class function Linear(P: Single): Single; inline;
8 | // Quadratic
9 | class function Quadratic_In(P: Single): Single; inline;
10 | class function Quadratic_Out(P: Single): Single; inline;
11 | class function Quadratic_InOut(P: Single): Single; inline;
12 | // Cubic
13 | class function Cubic_In(P: Single): Single; inline;
14 | class function Cubic_Out(P: Single): Single; inline;
15 | class function Cubic_InOut(P: Single): Single; inline;
16 | // Quartic
17 | class function Quartic_In(P: Single): Single; inline;
18 | class function Quartic_Out(P: Single): Single; inline;
19 | class function Quartic_InOut(P: Single): Single; inline;
20 | // Quintic
21 | class function Quintic_In(P: Single): Single; inline;
22 | class function Quintic_Out(P: Single): Single; inline;
23 | class function Quintic_InOut(P: Single): Single; inline;
24 | // Back
25 | class function Back_In(P: Single): Single; inline;
26 | class function Back_Out(P: Single): Single; inline;
27 | class function Back_InOut(P: Single): Single; inline;
28 | // Bounce
29 | class function Bounce_In(P: Single): Single; inline;
30 | class function Bounce_Out(P: Single): Single; inline;
31 | class function Bounce_InOut(P: Single): Single; inline;
32 | // Expo
33 | class function Expo_In(P: Single): Single; inline;
34 | class function Expo_Out(P: Single): Single; inline;
35 | class function Expo_InOut(P: Single): Single; inline;
36 | // Sine
37 | class function Sine_In(P: Single): Single; inline;
38 | class function Sine_Out(P: Single): Single; inline;
39 | class function Sine_InOut(P: Single): Single; inline;
40 | // Circle
41 | class function Circle_In(P: Single): Single; inline;
42 | class function Circle_Out(P: Single): Single; inline;
43 | class function Circle_InOut(P: Single): Single; inline;
44 | end;
45 | implementation
46 | uses
47 | Math;
48 | // LINEAR
49 | class function TIntAniCollection.Linear(P: Single): Single;
50 | begin
51 | Result := P;
52 | end;
53 | // QUADRATIC
54 | class function TIntAniCollection.Quadratic_In(P: Single): Single;
55 | begin
56 | Result := P * P;
57 | end;
58 | class function TIntAniCollection.Quadratic_Out(P: Single): Single;
59 | begin
60 | Result := 1 - Quadratic_In(1 - P);
61 | end;
62 | class function TIntAniCollection.Quadratic_InOut(P: Single): Single;
63 | begin
64 | if P < 0.5 then
65 | Result := 2 * Quadratic_In(P)
66 | else
67 | Result := 1 - 2 * Quadratic_In(P - 1);
68 | end;
69 | // CUBIC
70 | class function TIntAniCollection.Cubic_In(P: Single): Single;
71 | begin
72 | Result := P * P * P;
73 | end;
74 | class function TIntAniCollection.Cubic_Out(P: Single): Single;
75 | begin
76 | Result := 1 - Cubic_In(1 - P);
77 | end;
78 | class function TIntAniCollection.Cubic_InOut(P: Single): Single;
79 | begin
80 | if P < 0.5 then
81 | Result := 4 * Cubic_In(P)
82 | else
83 | Result := 1 + 4 * Cubic_In(P - 1);
84 | end;
85 | // QUARTIC
86 | class function TIntAniCollection.Quartic_In(P: Single): Single;
87 | begin
88 | Result := P * P * P * P;
89 | end;
90 | class function TIntAniCollection.Quartic_Out(P: Single): Single;
91 | begin
92 | Result := 1 - Quartic_In(1 - P);
93 | end;
94 | class function TIntAniCollection.Quartic_InOut(P: Single): Single;
95 | begin
96 | if P < 0.5 then
97 | Result := 8 * Quintic_In(P)
98 | else
99 | Result := 1 - 8 * Quartic_In(P - 1);
100 | end;
101 | // QUINTIC
102 | class function TIntAniCollection.Quintic_In(P: Single): Single;
103 | begin
104 | Result := P * P * P * P * P;
105 | end;
106 | class function TIntAniCollection.Quintic_Out(P: Single): Single;
107 | begin
108 | Result := 1 - Quintic_In(1 - P);
109 | end;
110 | class function TIntAniCollection.Quintic_InOut(P: Single): Single;
111 | begin
112 | if P < 0.5 then
113 | Result := 16 * Quintic_In(P)
114 | else
115 | Result := 1 + 16 * Quintic_In(P - 1);
116 | end;
117 | // BACK
118 | class function TIntAniCollection.Back_In(P: Single): Single;
119 | var
120 | S: Single;
121 | begin
122 | S := 1.70158;
123 | Result := P * P * (P * (S + 1) - S);
124 | end;
125 | class function TIntAniCollection.Back_Out(P: Single): Single;
126 | var
127 | S: Single;
128 | begin
129 | P := P - 1;
130 | S := 1.70158;
131 | Result := 1 + P * P * (P * (S + 1) + S);
132 | end;
133 | class function TIntAniCollection.Back_InOut(P: Single): Single;
134 | var
135 | S: Single;
136 | begin
137 | S := 1.70158;
138 | P := 2 * P;
139 | if P / 2 < 0.5 then begin
140 | S := S * 1.525;
141 | Result := 0.5 * P * P * (P * (S + 1) - S);
142 | end
143 | else begin
144 | P := P - 2;
145 | S := S * 1.525;
146 | Result := 1 + 0.5 * P * P * (P * (S + 1) + S);
147 | end;
148 | end;
149 | // BOUNCE
150 | class function TIntAniCollection.Bounce_In(P: Single): Single;
151 | begin
152 | P := 1 - P;
153 | Result := 1 - Bounce_Out(P);
154 | end;
155 | class function TIntAniCollection.Bounce_Out(P: Single): Single;
156 | begin
157 | if P < 1 / 2.75 then
158 | Result := 7.5625 * P * P
159 | else if P < 2 / 2.72 then begin
160 | P := P - (1.5 / 2.75);
161 | Result := 0.75 + 7.5625 * P * P;
162 | end
163 | else if P < 2.5 / 2.75 then begin
164 | P := P - (2.25 / 2.75);
165 | Result := 0.9375 + 7.5625 * P * P;
166 | end
167 | else begin
168 | P := P - (2.625 / 2.75);
169 | Result := 0.984375 + 7.5625 * P * P;
170 | end;
171 | end;
172 | class function TIntAniCollection.Bounce_InOut(P: Single): Single;
173 | begin
174 | if P < 0.5 then
175 | Result := 0.5 * Bounce_In(P * 2)
176 | else
177 | Result := 0.5 * (1 + Bounce_Out(2 * P - 1));
178 | end;
179 | // EXPO
180 | class function TIntAniCollection.Expo_In(P: Single): Single;
181 | begin
182 | Result := Power(2, (10 * (P - 1)));
183 | end;
184 | class function TIntAniCollection.Expo_Out(P: Single): Single;
185 | begin
186 | Result := 1 - Power(2, (-10 * P));
187 | end;
188 | class function TIntAniCollection.Expo_InOut(P: Single): Single;
189 | begin
190 | P := 2 * P;
191 | if P / 2 < 0.5 then
192 | Result := 0.5 * Power(2, (10 * (P - 1)))
193 | else
194 | Result := 0.5 * (2 - Power(2, (-10 * P)));
195 | end;
196 | // SINE
197 | class function TIntAniCollection.Sine_In(P: Single): Single;
198 | begin
199 | Result := 1 - Cos(P * Pi / 2);
200 | end;
201 | class function TIntAniCollection.Sine_Out(P: Single): Single;
202 | begin
203 | Result := Sin(P * Pi / 2);
204 | end;
205 | class function TIntAniCollection.Sine_InOut(P: Single): Single;
206 | begin
207 | Result := 0.5 * (1 - Cos(P * Pi));
208 | end;
209 | // CIRCLE
210 | class function TIntAniCollection.Circle_In(P: Single): Single;
211 | begin
212 | Result := 1 - Sqrt(1 - P * P);
213 | end;
214 | class function TIntAniCollection.Circle_Out(P: Single): Single;
215 | begin
216 | P := P - 1;
217 | Result := Sqrt(1 - P * P);
218 | end;
219 | class function TIntAniCollection.Circle_InOut(P: Single): Single;
220 | begin
221 | P := 2 * P;
222 | if P / 2 < 0.5 then
223 | Result := 0.5 * (1 - Sqrt(1 - P * P))
224 | else begin
225 | P := P - 2;
226 | Result := 0.5 * (1 + Sqrt(1 - P * P));
227 | end;
228 | end;
229 | end.
230 |
--------------------------------------------------------------------------------
/Source/CFX.Animation.Utils.pas:
--------------------------------------------------------------------------------
1 | (**************************************************************)
2 | (* Codrut's Animation Library *)
3 | (* *)
4 | (* *)
5 | (* Copyright (c) 2024 *)
6 | (* Petculescu Codrut. Codrut Software *)
7 | (* *)
8 | (* https://www.codrutsoft.com/ *)
9 | (* https://github.com/Codrax/Codrut-Animation-Lib/ *)
10 | (* *)
11 | (**************************************************************)
12 |
13 | unit CFX.Animation.Utils;
14 |
15 | {$SCOPEDENUMS ON}
16 |
17 | interface
18 | uses
19 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, System.Types, TypInfo;
20 |
21 | function PropertyExists(Instance: TObject; PropName: string): boolean; overload;
22 |
23 | function GetPropertyType(Instance: TObject; PropName: string): TTypeKind; overload;
24 |
25 | // Root
26 | function GetRootInstance(Instance: TObject; var PropName: string): TObject;
27 |
28 | // Get
29 | function GetPropertyValue(Instance: TObject; PropName: string): Variant;
30 |
31 | // Set
32 | procedure SetPropertyValue(Instance: TObject; PropName: string; Value: Variant); overload;
33 |
34 | implementation
35 |
36 | function GetRootInstance(Instance: TObject; var PropName: string): TObject;
37 | var
38 | Tree: TArray;
39 | begin
40 | Tree := PropName.Split(['.']);
41 |
42 | // Check root
43 | if Length(Tree) <= 1 then
44 | Exit(Instance);
45 |
46 | // Parse
47 | PropName := PropName.Remove(0, Length(Tree[0])+1);
48 |
49 | // Get upper level object
50 | var V: Variant;
51 | var EObject: TObject;
52 |
53 | V := GetPropValue(Instance, Tree[0]);
54 | EObject := TObject(int64(V));
55 |
56 | Result := GetRootInstance(EObject, PropName);
57 | end;
58 |
59 | function PropertyExists(Instance: TObject; PropName: string): boolean; overload;
60 | var
61 | AProp: PPropInfo;
62 | begin
63 | AProp := GetPropInfo(PTypeInfo(Instance.ClassInfo), PropName);
64 |
65 | Result := AProp <> nil;
66 | end;
67 |
68 | function GetPropertyType(Instance: TObject; PropName: string): TTypeKind; overload;
69 | var
70 | AProp: PPropInfo;
71 | Info: PTypeInfo;
72 | begin
73 | // Root
74 | Instance := GetRootInstance(Instance, PropName);
75 |
76 | // Work
77 | AProp := GetPropInfo(PTypeInfo(Instance.ClassInfo), PropName);
78 |
79 | Info := AProp^.PropType^;
80 | Result := Info.Kind;
81 | end;
82 |
83 | function GetPropertyValue(Instance: TObject; PropName: string): Variant;
84 | begin
85 | // Root
86 | Instance := GetRootInstance(Instance, PropName);
87 |
88 | // Work
89 | Result := GetPropValue(Instance, PropName, false);
90 | end;
91 |
92 | procedure SetPropertyValue(Instance: TObject; PropName: string; Value: Variant); overload;
93 | var
94 | AProp: PPropInfo;
95 | begin
96 | // Root
97 | Instance := GetRootInstance(Instance, PropName);
98 |
99 | // Work
100 | AProp := GetPropInfo(PTypeInfo(Instance.ClassInfo), PropName);
101 |
102 | SetPropValue(Instance, AProp, Value);
103 | end;
104 |
105 | end.
106 |
--------------------------------------------------------------------------------
/Source/CFX.AppIntegration.pas:
--------------------------------------------------------------------------------
1 | unit CFX.AppIntegration;
2 |
3 | {$TYPEINFO ON}
4 |
5 | interface
6 | uses
7 | Winapi.Windows,
8 | Winapi.Messages,
9 | Classes,
10 | Vcl.Forms,
11 | CFX.Instances,
12 | System.SysUtils,
13 | System.UITypes,
14 | Types,
15 | Math,
16 | DateUtils,
17 | CFX.Types,
18 | Vcl.Graphics,
19 | CFX.ThemeManager,
20 | CFX.Colors,
21 | CFX.Files,
22 | CFX.Version,
23 | CFX.StringUtils,
24 | CFX.Registry,
25 | CFX.FormTemplates,
26 | ShellAPI,
27 | CFX.QuickDialogs,
28 | CFX.Utilities;
29 |
30 |
31 | // UI Utilities
32 | procedure PromptUpdateUser(MainForm: TForm; var Form: TForm);
33 | procedure PromptUpdateUserClose(var Form: TForm);
34 | procedure PromptUpdate(MainForm: TForm; Required: boolean = false);
35 |
36 | implementation
37 |
38 | uses
39 | CFX.AppManager;
40 |
41 | procedure PromptUpdateUser(MainForm: TForm; var Form: TForm);
42 | begin
43 | Form := FXTaskExecutingTemplate.CreateNew(MainForm);
44 | with FXTaskExecutingTemplate(Form) do
45 | try
46 | FillMode := FXFormFill.TitleBar;
47 | CloseAction := FXFormCloseAction.Free;
48 |
49 | Title := 'Checking for updates';
50 | if AppManager.ApplicationName <> '' then
51 | Text := Format('Checking the update server for a new version of "%S". Please stand by...', [AppManager.ApplicationName])
52 | else
53 | Text := Format('Checking the update server for a new version of this software. Please stand by...', [AppManager.ApplicationName]);
54 | ProgressText := 'Now contacting the update server';
55 | ShowCancel := false;
56 |
57 | Show;
58 |
59 | // User check timeout
60 | for var I := 1 to AppManagerInstance.UserUpdateWaitDelay div 5 do begin
61 | Application.ProcessMessages;
62 | Sleep(5);
63 | end;
64 | finally
65 | //Free;
66 | end;
67 | end;
68 |
69 | procedure PromptUpdateUserClose(var Form: TForm);
70 | begin
71 | // End UI
72 | if Form <> nil then begin
73 | Form.Hide;
74 |
75 | // Free
76 | Application.ProcessMessages;
77 | Form.Free;
78 |
79 | // Set to nil
80 | Form := nil;
81 | end;
82 | end;
83 |
84 | procedure PromptUpdate(MainForm: TForm; Required: boolean);
85 | var
86 | URL: string;
87 | begin
88 | // Err
89 | if not AppManager.UpdateCheckSuccess then
90 | begin
91 | OpenMessage('An error occured', 'We could not check for updates');
92 | Exit;
93 | end;
94 |
95 | // New
96 | if not AppManager.NewVersion then
97 | Exit;
98 |
99 | // Download link
100 | URL := AppManager.ServerVersion.GetDownloadLink;
101 | if URL = '' then
102 | begin
103 | OpenMessage('An error occured', 'The update link was not found. You will need to update manually.');
104 | Exit;
105 | end;
106 |
107 | with FXFormUpdateTemplate.CreateNew(MainForm) do
108 | try
109 | FillMode := FXFormFill.TitleBar;
110 | CloseAction := FXFormCloseAction.Free;
111 |
112 | AllowSnooze := not Required;
113 |
114 | AppName := AppManager.ApplicationName;
115 |
116 | DownloadURL := URL;
117 | InstallParameters := '-auto-delete -start';
118 |
119 | Show;
120 | finally
121 | //Free;
122 | end;
123 | end;
124 | end.
125 |
--------------------------------------------------------------------------------
/Source/CFX.ArrayHelpers.pas:
--------------------------------------------------------------------------------
1 | {***********************************************************}
2 | { Codruts Variabile Helpers }
3 | { }
4 | { version 1.0 }
5 | { ALPHA }
6 | { }
7 | { https://www.codrutsoft.com/ }
8 | { Copyright 2024 Codrut Software }
9 | { This unit is licensed for usage under a MIT license }
10 | { }
11 | {***********************************************************}
12 |
13 | {$SCOPEDENUMS ON}
14 |
15 | unit CFX.ArrayHelpers;
16 |
17 | interface
18 | uses
19 | System.SysUtils, System.Classes,
20 | System.Generics.Collections, System.Generics.Defaults;
21 |
22 | type
23 | TMultiSwitch = class
24 | type
25 | TCase = record
26 | Values: TArray;
27 | CallBack: TProc;
28 |
29 | procedure Execute;
30 | end;
31 |
32 | // Make
33 | class function Option(Value: T; Call: TProc): TCase; overload;
34 | class function Option(Values: TArray; Call: TProc): TCase; overload;
35 |
36 | // Switch
37 | class procedure Switch(Value: T; Cases: TArray); overload;
38 | class procedure Switch(Value: T; Cases: TArray; Default: TProc); overload;
39 | end;
40 |
41 | /// Note about internal errors
42 | /// This class uses lComparer to compare values because some value types,
43 | /// such as record cannot be directly compared and would give the
44 | /// "Invalid operand type" error, but since this class is type based,
45 | /// a internal error would appear instead.
46 |
47 | // TArray colection
48 | TArrayUtils = class
49 | public
50 | // Callback types
51 | type
52 | TArrayEachCallback = reference to procedure(var Element: T);
53 | TArrayEachCallbackConst = reference to procedure(Element: T);
54 | TArrayDualCallback = reference to function(A, B: T): boolean;
55 | TArrayIndexCallback = reference to function(Index: integer): T;
56 |
57 | /// Verify if the array contains element x.
58 | class function Build(const Length: integer; Callback: TArrayIndexCallback): TArray;
59 |
60 | /// Verify if the array contains element x.
61 | class function Contains(const x: T; const Values: TArray): boolean;
62 | /// Compares is two arrays are equal.
63 | class function CheckEquality(const First, Second: TArray) : boolean;
64 |
65 | /// Get the index if element x.
66 | class function GetIndex(const x: T; const Values: TArray): integer;
67 | /// Go trough all elements of an array and get their value.
68 | class procedure ForEach(const Values: TArray; Callback: TArrayEachCallbackConst); overload;
69 | /// Go trough all elements of an array and modify their value.
70 | class procedure ForEach(var Values: TArray; Callback: TArrayEachCallback); overload;
71 | /// Sort the elements of an array using the provided callback for comparison.
72 | class procedure Sort(var Values: TArray; Callback: TArrayDualCallback); overload;
73 |
74 | /// Move one item from It's index to another item's index and moving that one uppwards.
75 | class procedure Move(var Values: TArray; const Source, Destination: integer); overload;
76 | /// Switch places for two items.
77 | class procedure Switch(var Values: TArray; const Source, Destination: integer); overload;
78 |
79 | /// Add blank value to the end of the array.
80 | class function AddValue(var Values: TArray) : integer; overload;
81 | /// Add value to the end of the array.
82 | class function AddValue(const x: T; var Values: TArray) : integer; overload;
83 | /// Add value to the end of the array.
84 | class procedure AddValues(const Values: TArray; var Destination: TArray);
85 | /// Concat secondary array to primary array
86 | class function Concat(const Primary, Secondary: TArray) : TArray;
87 | /// Insert empty value at the specified index into the array.
88 | class procedure Insert(const Index: integer; var Values: TArray); overload;
89 | /// Insert value at the specified index into the array.
90 | class procedure Insert(const Index: integer; const x: T; var Values: TArray); overload;
91 |
92 | /// Delete element by index from array.
93 | class procedure Delete(const Index: integer; var Values: TArray);
94 | /// Delete element by type T from array.
95 | class procedure DeleteElement(const Element: T; var Values: TArray);
96 | /// Set length to specifieed value.
97 | ///
98 | class procedure SetLength(const Length: integer; var Values: TArray);
99 | /// Get array length.
100 | class function Count(const Values: TArray) : integer;
101 | end;
102 |
103 |
104 | implementation
105 |
106 | { TArrayUtils }
107 |
108 | class function TArrayUtils.AddValue(const x: T;
109 | var Values: TArray): integer;
110 | begin
111 | Result := AddValue(Values);
112 | Values[Result] := x;
113 | end;
114 |
115 | class function TArrayUtils.AddValue(var Values: TArray): integer;
116 | begin
117 | System.SetLength(Values, length(Values)+1);
118 |
119 | Result := High(Values);
120 | end;
121 |
122 | class procedure TArrayUtils.AddValues(const Values: TArray;
123 | var Destination: TArray);
124 | begin
125 | const StartIndex = High(Destination)+1;
126 | System.SetLength(Destination, length(Destination)+length(Values));
127 |
128 | const LowPoint = Low(Values);
129 | for var I := LowPoint to High(Values) do
130 | Destination[StartIndex+I-LowPoint] := Values[I];
131 | end;
132 |
133 | class function TArrayUtils.Build(const Length: integer;
134 | Callback: TArrayIndexCallback): TArray;
135 | begin
136 | System.SetLength(Result, Length);
137 | for var I := 0 to Length-1 do
138 | Result[I] := Callback(I);
139 | end;
140 |
141 | class function TArrayUtils.Concat(const Primary,
142 | Secondary: TArray): TArray;
143 | begin
144 | Result := Primary;
145 |
146 | AddValues(Secondary, Result);
147 | end;
148 |
149 | class function TArrayUtils.Contains(const x: T; const Values: TArray): boolean;
150 | var
151 | y : T;
152 | lComparer: IEqualityComparer;
153 | begin
154 | lComparer := TEqualityComparer.Default;
155 | for y in Values do
156 | begin
157 | if lComparer.Equals(x, y) then
158 | Exit(True);
159 | end;
160 | Exit(False);
161 | end;
162 |
163 | class function TArrayUtils.Count(const Values: TArray): integer;
164 | begin
165 | Result := Length(Values);
166 | end;
167 |
168 | class procedure TArrayUtils.Delete(const Index: integer;
169 | var Values: TArray);
170 | begin
171 | if Index = -1 then
172 | Exit;
173 |
174 | for var I := Index to High(Values)-1 do
175 | Values[I] := Values[I+1];
176 |
177 | System.SetLength(Values, Length(Values)-1);
178 | end;
179 |
180 | class procedure TArrayUtils.DeleteElement(const Element: T;
181 | var Values: TArray);
182 | begin
183 | const Index = GetIndex(Element, Values);
184 | if Index <> -1 then
185 | Delete(Index, Values);
186 | end;
187 |
188 | class function TArrayUtils.CheckEquality(const First, Second: TArray): boolean;
189 | var
190 | lComparer: IEqualityComparer;
191 | begin
192 | Result := true;
193 | lComparer := TEqualityComparer.Default;
194 |
195 | if Length(First) <> Length(Second) then
196 | Exit(false);
197 | const Count = Length(First);
198 | for var I := 0 to Count-1 do
199 | if not lComparer.Equals(First[I], Second[I]) then
200 | Exit(false);
201 | end;
202 |
203 | class procedure TArrayUtils.ForEach(var Values: TArray;
204 | Callback: TArrayEachCallback);
205 | begin
206 | for var I := Low(Values) to High(Values) do
207 | Callback( Values[I] );
208 | end;
209 |
210 | class procedure TArrayUtils.ForEach(const Values: TArray;
211 | Callback: TArrayEachCallbackConst);
212 | var
213 | y : T;
214 | begin
215 | for y in Values do
216 | Callback(y);
217 | end;
218 |
219 | class function TArrayUtils.GetIndex(const x: T; const Values: TArray): integer;
220 | var
221 | I: Integer;
222 | y: T;
223 | lComparer: IEqualityComparer;
224 | begin
225 | lComparer := TEqualityComparer.Default;
226 | for I := Low(Values) to High(Values) do
227 | begin
228 | y := Values[I];
229 |
230 | if lComparer.Equals(x, y) then
231 | Exit(I);
232 | end;
233 | Exit(-1);
234 | end;
235 |
236 | class procedure TArrayUtils.Insert(const Index: integer;
237 | var Values: TArray);
238 | var
239 | Size: integer;
240 | I: Integer;
241 | begin
242 | System.SetLength(Values, Length(Values)+1);
243 | Size := High(Values);
244 |
245 | for I := Size downto Index+1 do
246 | Values[I] := Values[I-1];
247 | end;
248 |
249 | class procedure TArrayUtils.Insert(const Index: integer; const x: T;
250 | var Values: TArray);
251 | begin
252 | Insert(Index, Values);
253 |
254 | // Set
255 | Values[Index] := x;
256 | end;
257 |
258 | class procedure TArrayUtils.Move(var Values: TArray; const Source,
259 | Destination: integer);
260 | var
261 | I: integer;
262 | begin
263 | const OriginalItem = Values[Source];
264 |
265 | // Move all items
266 | if Source < Destination then begin
267 | for I := Source to Destination-1 do
268 | Values[I] := Values[I+1];
269 | end else begin
270 | for I := Source downto Destination+1 do
271 | Values[I] := Values[I-1];
272 | end;
273 |
274 | // Item
275 | Values[Destination] := OriginalItem;
276 | end;
277 |
278 | class procedure TArrayUtils.SetLength(const Length: integer;
279 | var Values: TArray);
280 | begin
281 | System.SetLength(Values, Length);
282 | end;
283 |
284 | class procedure TArrayUtils.Sort(var Values: TArray;
285 | Callback: TArrayDualCallback);
286 | var
287 | Stack: TArray;
288 | ALow, AHigh, i, j, PivotIndex: Integer;
289 | Pivot, Temp: T;
290 | begin
291 | if Length(Values) <= 1 then
292 | Exit;
293 |
294 | // Initialize the stack for iterative QuickSort
295 | System.SetLength(Stack, Length(Values) * 2);
296 | ALow := 0;
297 | AHigh := High(Values);
298 |
299 | Stack[0] := ALow;
300 | Stack[1] := AHigh;
301 | PivotIndex := 2;
302 |
303 | while PivotIndex > 0 do
304 | begin
305 | // Pop Low and High from stack
306 | Dec(PivotIndex);
307 | AHigh := Stack[PivotIndex];
308 | Dec(PivotIndex);
309 | ALow := Stack[PivotIndex];
310 |
311 | // Partition the array
312 | Pivot := Values[(ALow + AHigh) div 2];
313 | i := ALow;
314 | j := AHigh;
315 | while i <= j do
316 | begin
317 | while Callback(Pivot, Values[i]) do
318 | Inc(i);
319 | while Callback(Values[j], Pivot) do
320 | Dec(j);
321 | if i <= j then
322 | begin
323 | Temp := Values[i];
324 | Values[i] := Values[j];
325 | Values[j] := Temp;
326 | Inc(i);
327 | Dec(j);
328 | end;
329 | end;
330 |
331 | // Push sub-arrays onto stack
332 | if ALow < j then
333 | begin
334 | Stack[PivotIndex] := ALow;
335 | Inc(PivotIndex);
336 | Stack[PivotIndex] := j;
337 | Inc(PivotIndex);
338 | end;
339 | if i < AHigh then
340 | begin
341 | Stack[PivotIndex] := i;
342 | Inc(PivotIndex);
343 | Stack[PivotIndex] := AHigh;
344 | Inc(PivotIndex);
345 | end;
346 | end;
347 | end;
348 |
349 | class procedure TArrayUtils.Switch(var Values: TArray; const Source,
350 | Destination: integer);
351 | begin
352 | const OriginalItem = Values[Source];
353 | Values[Source] := Values[Destination];
354 | Values[Destination] := OriginalItem;
355 | end;
356 |
357 | { TMultiSwitch }
358 |
359 | class function TMultiSwitch.Option(Value: T; Call: TProc): TCase;
360 | begin
361 | Result := Option([Value], Call);
362 | end;
363 |
364 | class function TMultiSwitch.Option(Values: TArray; Call: TProc): TCase;
365 | begin
366 | Result.Values := Values;
367 | Result.CallBack := Call;
368 | end;
369 |
370 | class procedure TMultiSwitch.Switch(Value: T; Cases: TArray; Default: TProc);
371 | begin
372 | for var I := 0 to High(Cases) do
373 | if TArrayUtils.Contains(Value, Cases[I].Values) then begin
374 | Cases[I].Execute;
375 | Exit;
376 | end;
377 |
378 | // Default
379 | if Assigned(Default) then
380 | Default;
381 | end;
382 |
383 | class procedure TMultiSwitch.Switch(Value: T; Cases: TArray);
384 | begin
385 | Switch(Value, Cases, nil);
386 | end;
387 |
388 | { TMultiSwitch.TCase }
389 |
390 | procedure TMultiSwitch.TCase.Execute;
391 | begin
392 | Callback;
393 | end;
394 |
395 | end.
396 |
--------------------------------------------------------------------------------
/Source/CFX.BlurFunctions.pas:
--------------------------------------------------------------------------------
1 | unit CFX.BlurFunctions;
2 |
3 | interface
4 | uses
5 | UITypes, Types, CFX.Constants, VCl.GraphUtil, Winapi.Windows,
6 | Classes, Vcl.Themes, Vcl.Controls, Vcl.Graphics,
7 | SysUtils, CFX.VarHelpers;
8 |
9 | type
10 | // Blur Function Dependencies
11 | TKernelSize = 1..50;
12 | TKernel = record
13 | Size: TKernelSize;
14 | Weights: array[-50..50] of Single;
15 | end;
16 | TRGBTriple = packed record
17 | b: Byte; {easier to type than rgbtBlue}
18 | g: Byte;
19 | r: Byte;
20 | end;
21 | PRow = ^TRow;
22 | TRow = array[Word] of TRGBTriple;
23 | PPRows = ^TPRows;
24 | TPRows = array[Word] of PRow;
25 |
26 |
27 | // Declarations
28 | procedure MakeGaussianKernel(var K: TKernel; radius: Real; MaxData, DataGranularity: Real);
29 | procedure BlurRow(var theRow: array of TRGBTriple; K: TKernel; P: PRow);
30 |
31 | procedure GaussianBlur(Bitmap: TBitmap; Radius: Real);
32 | procedure FastBlur(Bitmap: TBitmap; Radius: Real; BlurScale: Integer; HighQuality: Boolean = True);
33 |
34 | implementation
35 |
36 | function TrimInt(Lower, Upper, theInteger: Integer): integer;
37 | begin
38 | if (theInteger <= Upper) and (theInteger >= Lower) then
39 | result := theInteger
40 | else if theInteger > Upper then
41 | result := Upper
42 | else
43 | result := Lower;
44 | end;
45 |
46 | function TrimReal(Lower, Upper: Integer; x: Real): integer;
47 | begin
48 | if (x < upper) and (x >= lower) then
49 | result := trunc(x)
50 | else if x > Upper then
51 | result := Upper
52 | else
53 | result := Lower;
54 | end;
55 |
56 | procedure BlurRow(var theRow: array of TRGBTriple; K: TKernel; P: PRow);
57 | var
58 | j, n: Integer;
59 | tr, tg, tb: Real; {tempRed, etc}
60 | w: Real;
61 | begin
62 | for j := 0 to High(theRow) do
63 | begin
64 | tb := 0;
65 | tg := 0;
66 | tr := 0;
67 | for n := -K.Size to K.Size do
68 | begin
69 | w := K.Weights[n];
70 | {the TrimInt keeps us from running off the edge of the row...}
71 | with theRow[TrimInt(0, High(theRow), j - n)] do
72 | begin
73 | tb := tb + w * b;
74 | tg := tg + w * g;
75 | tr := tr + w * r;
76 | end;
77 | end;
78 | with P[j] do
79 | begin
80 | b := TrimReal(0, 255, tb);
81 | g := TrimReal(0, 255, tg);
82 | r := TrimReal(0, 255, tr);
83 | end;
84 | end;
85 | Move(P[0], theRow[0], (High(theRow) + 1) * Sizeof(TRGBTriple));
86 | end;
87 |
88 |
89 | procedure MakeGaussianKernel(var K: TKernel; radius: Real; MaxData, DataGranularity: Real);
90 | {makes K into a gaussian kernel with standard deviation = radius. For the current application
91 | you set MaxData = 255 and DataGranularity = 1. Now the procedure sets the value of K.Size so
92 | that when we use K we will ignore the Weights that are so small they can't possibly matter. (Small
93 | Size is good because the execution time is going to be propertional to K.Size.)}
94 | var
95 | j: Integer;
96 | temp, delta: Real;
97 | KernelSize: TKernelSize;
98 | begin
99 | for j := Low(K.Weights) to High(K.Weights) do
100 | begin
101 | temp := j / radius;
102 | K.Weights[j] := exp(-temp * temp / 2);
103 | end;
104 | {now divide by constant so sum(Weights) = 1:}
105 | temp := 0;
106 | for j := Low(K.Weights) to High(K.Weights) do
107 | temp := temp + K.Weights[j];
108 | for j := Low(K.Weights) to High(K.Weights) do
109 | K.Weights[j] := K.Weights[j] / temp;
110 | {now discard (or rather mark as ignorable by setting Size) the entries that are too small to matter.
111 | This is important, otherwise a blur with a small radius will take as long as with a large radius...}
112 | KernelSize := 50;
113 | delta := DataGranularity / (2 * MaxData);
114 | temp := 0;
115 | while (temp < delta) and (KernelSize > 1) do
116 | begin
117 | temp := temp + 2 * K.Weights[KernelSize];
118 | dec(KernelSize);
119 | end;
120 | K.Size := KernelSize;
121 | {now just to be correct go back and jiggle again so the sum of the entries we'll be using is exactly 1}
122 | temp := 0;
123 | for j := -K.Size to K.Size do
124 | temp := temp + K.Weights[j];
125 | for j := -K.Size to K.Size do
126 | K.Weights[j] := K.Weights[j] / temp;
127 | // finally correct
128 | K.Weights[0] := K.Weights[0] + (0.000001);// HACK
129 | end;
130 |
131 | procedure GaussianBlur(Bitmap: TBitmap; Radius: Real);
132 | var
133 | Row, Col: Integer;
134 | theRows: PPRows;
135 | K: TKernel;
136 | ACol: PRow;
137 | P: PRow;
138 | begin
139 | if (Bitmap.HandleType <> bmDIB) or (Bitmap.PixelFormat <> pf24Bit) then
140 | raise Exception.Create('GaussianBlur only works for 24-bit bitmaps');
141 | MakeGaussianKernel(K, radius, 255, 1);
142 | GetMem(theRows, Bitmap.Height * SizeOf(PRow));
143 | GetMem(ACol, Bitmap.Height * SizeOf(TRGBTriple));
144 | {record the location of the bitmap data:}
145 | for Row := 0 to Bitmap.Height - 1 do
146 | theRows[Row] := Bitmap.Scanline[Row];
147 | {blur each row:}
148 | P := AllocMem(Bitmap.Width * SizeOf(TRGBTriple));
149 | for Row := 0 to Bitmap.Height - 1 do
150 | BlurRow(Slice(theRows[Row]^, Bitmap.Width), K, P);
151 | {now blur each column}
152 | ReAllocMem(P, Bitmap.Height * SizeOf(TRGBTriple));
153 | for Col := 0 to Bitmap.Width - 1 do
154 | begin
155 | {first read the column into a TRow:}
156 | for Row := 0 to Bitmap.Height - 1 do
157 | ACol[Row] := theRows[Row][Col];
158 | BlurRow(Slice(ACol^, Bitmap.Height), K, P);
159 | {now put that row, um, column back into the data:}
160 | for Row := 0 to Bitmap.Height - 1 do
161 | theRows[Row][Col] := ACol[Row];
162 | end;
163 | FreeMem(theRows);
164 | FreeMem(ACol);
165 | ReAllocMem(P, 0);
166 | end;
167 |
168 | procedure FastBlur(Bitmap: TBitmap; Radius: Real; BlurScale: Integer; HighQuality: Boolean = True);
169 | function Max(A, B: Integer): Integer;
170 | begin
171 | if A > B then
172 | Result := A
173 | else
174 | Result := B;
175 | end;
176 | var
177 | Mipmap: TBitmap;
178 | begin
179 | BlurScale := Max(BlurScale, 1);
180 | Mipmap := TBitmap.Create;
181 | try
182 | Mipmap.PixelFormat := pf24bit;
183 | Mipmap.SetSize(Max(Bitmap.Width div BlurScale, 4), Max(Bitmap.Height div BlurScale, 4));
184 | // create mipmap
185 | if HighQuality then
186 | DrawBitmapHighQuality(Mipmap.Canvas.Handle, Rect(0, 0, Mipmap.Width, Mipmap.Height), Bitmap, 255, False, True)
187 | else
188 | Mipmap.Canvas.StretchDraw(Rect(0, 0, Mipmap.Width, Mipmap.Height), Bitmap);
189 | // gaussian blur
190 | GaussianBlur(Mipmap, Radius);
191 | // stretch to source bitmap
192 | DrawBitmapHighQuality(Bitmap.Canvas.Handle, Rect(0, 0, Bitmap.Width, Bitmap.Height), Mipmap, 255, False, True);
193 | finally
194 | Mipmap.Free;
195 | end;
196 | end;
197 |
198 |
199 | end.
200 |
--------------------------------------------------------------------------------
/Source/CFX.Constants.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Constants;
2 |
3 | interface
4 |
5 | const
6 | // CLASSES
7 | REGISTER_CLASS_NAME = 'CFX Main';
8 | REGISTER_CLASS_UTILS_NAME = 'CFX Utils';
9 | REGISTER_CLASS_LAYOUTS = 'CFX Layouts';
10 | REGISTER_CLASS_SHAPES = 'CFX Shapes';
11 | REGISTER_CLASS_EFFECTS_NAME = 'CFX Effects';
12 | REGISTER_CLASS_ANIM_NAME = 'CFX Animations';
13 | REGISTER_CLASS_LEGACY = 'CFX Legacy';
14 |
15 | // Strings
16 | STRING_NONE = 'none';
17 |
18 | // THEME MANAGER
19 | ACCENT_DIFFERENTIATE_CONST = 25;
20 |
21 | // API
22 | DEFAULT_API = 'https://api.codrutsoft.com/';
23 | DEFAULT_UPDATE_NAME = 'updateurl';
24 | DEFAULT_COMPANY = 'Codrut Software';
25 |
26 | // System interaction
27 | DEFAULT_SCROLL_LINES = 3;
28 | DEFAULT_LINE_SIZE = 25;
29 |
30 | // TIME
31 | ONE_MS = 1;
32 | FIFTH_SECOND = 200;
33 | ONE_SECOND = 1000;
34 | FIVE_SECOND = ONE_SECOND * 5;
35 |
36 | // COMPONENTS STYLE
37 | DEFAULT_OPACITY = 100;
38 | FORM_FONT_NAME = 'Segoe UI';
39 | FORM_FONT_HEIGHT = 22;
40 | FORM_SMOKE_BLEND_VALUE = 150;
41 | FORM_MICA_EFFECT_BLEND_VALUE = 251;
42 |
43 | LARGE_FONT_HEIGHT = -20;
44 |
45 | DARK_TINT_OPACITY = 75;
46 | LIGHT_TINT_OPACITY = 200;
47 |
48 | (* Functionality *)
49 | REPEAT_START_DELAY = 500;
50 | HOLD_REPEAT_INTERVAL = 50;
51 |
52 | SCROLL_DURATION = 1;
53 | SCROLL_SPEED_VALUE = 20;
54 |
55 | (* Composite the form with Parital Transparency *)
56 | FORM_COMPOSITE_COLOR = $00FF0083;
57 |
58 | (* Legacy, replaced by height *)
59 | FORM_FONT_SIZE_1 = 12;
60 |
61 | (* Use the ThemeManager.IconFont function to get the optimal font *)
62 | FORM_ICON_FONT_NAME_NEW = 'Segoe Fluent Icons';
63 | FORM_ICON_FONT_NAME_LEGACY = 'Segoe MDL2 Assets';
64 |
65 | TEXT_SIZE_COMPARER = 'ABC...';
66 |
67 | GENERAL_ROUND = 5;
68 | DEFAULT_GLASSTEXT_GLOWSIZE = 0;
69 |
70 | FOCUS_LINE_ROUND = 8;
71 | FOCUS_LINE_SIZE = 2;
72 |
73 | BUTTON_DEFAULT_HEIGHT = 35;
74 | BUTTON_DEFAULT_WIDTH = 140;
75 | BUTTON_COLOR_OFFSET = 10;
76 | BUTTON_COLOR_SMALL_OFFSET = 5;
77 | BUTTON_BLEND_FADE = 100;
78 | BUTTON_MARGIN = 5;
79 | BUTTON_ICON_SPACE = 30;
80 | BUTTON_IMAGE_SCALE = 1.25;
81 | BUTTON_ROUNDNESS = 10;
82 | BUTTON_STATE_DURATION = 1000;
83 | BUTTON_LINE_WIDTH = 3;
84 | BUTTON_STATE_TEXT = 'Success';
85 |
86 | LABEL_FONT_HEIGHT = 24;
87 | LABEL_FONT_NAME = FORM_FONT_NAME;
88 |
89 | SCROLLBAR_DEFAULT_SIZE = 40;
90 | SCROLLBAR_MIN_SIZE = 20;
91 |
92 | TOOLTIP_WIDTH = 2;
93 | TOOLTIP_FONT_NAME = FORM_FONT_NAME;
94 | TOOLTIP_FONT_SIZE = 8;
95 | TOOLTIP_ROUND = 5;
96 |
97 | CHECKBOX_ICON_SIZE = 22;
98 | CHECKBOX_BOX_ROUND = 6;
99 | CHECKBOX_TEXT_SPACE = 6;
100 | CHECKBOX_HINT_DURATION = 1000;
101 |
102 | PROGRESS_ACTIVELINE_SIZE = 4;
103 | PROGRESS_LINE_SIZE = 2;
104 |
105 | GENERAL_IMAGE_SCALE = 1.5;
106 | NORMAL_IMAGE_SCALE = 1;
107 |
108 | LIST_ITEM_OPACITY_SELECTED = 75;
109 | LIST_ITEM_OPACITY_HOVER = 35;
110 |
111 | RADIO_TEXT_SPACE = 6;
112 |
113 | SELECTOR_ROUND = 20;
114 |
115 | SLIDER_TICK_ROUND = 2;
116 | SLIDER_TICK_SPACING = 3;
117 | SLIDER_TICK_SIZE = 2;
118 |
119 | SCROLL_TEXT_SPACE = 75;
120 | SCROLL_TEXT_DELAY = 150;
121 | SCROLL_TEXT_SPEED = 1;
122 | SCROLL_TEXT_FADE_SIZE = 30;
123 |
124 | DEFAULT_SCROLLBAR_SIZE = 12;
125 |
126 | ICON_GREEN = 6277996;
127 | ICON_ICEBLUE = 14075312;
128 | ICON_YELLOW = 57852;
129 | ICON_ROSE = 10787327;
130 |
131 | PANEL_LINE_ROUND = 8;
132 | PANEL_LINE_SPACING = 10;
133 | PANEL_LINE_WIDTH = 8;
134 |
135 | HANDLE_SEPARATOR = 1;
136 | MINIMISE_PANEL_ROUND = 10;
137 | MINIMISE_PANEL_SIZE = 60;
138 | MINIMISE_ICON_MARGIN = 10;
139 |
140 | MINIMISE_COLOR_CHANGE = 5;
141 |
142 | EDIT_DEFAULT_WIDTH = 150;
143 | EDIT_DEFAULT_HEIGHT = 35;
144 | EDIT_COLOR_CHANGE = 10;
145 | EDIT_BORDER_FADE = 15;
146 | EDIT_BORDER_ROUND = 10;
147 | EDIT_LINE_SIZE = 2;
148 | EDIT_EXTRA_SPACE = 5;
149 | EDIT_INDIC_WIDTH = 1;
150 | EDIT_TEXT_HINT_FADE = 100;
151 |
152 | // Hint Class
153 | MAX_HINT_SIZE = 200;
154 |
155 | // TEXT
156 | CHECKBOX_OUTLINE = #$E003;
157 | CHECKBOX_SMALL = #$E004;
158 | CHECKBOX_CHECKED = #$E005;
159 | CHECKBOX_GRAYED = #$E73C;
160 | CHECKBOX_FILL = #$E73B;
161 |
162 | RADIO_FILL = #$E91F;
163 | RADIO_OUTLINE = #$ECCA;
164 | RADIO_BULLET = #$ECCC;
165 |
166 | SEGOE_UI_STAR = #$E734;
167 |
168 | TEXT_LIST_EMPTY = 'No items';
169 |
170 | TEXT_DEFAULT_GENERIC = 'Hello World';
171 | TEXT_LONG_GENERIC = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
172 |
173 | // POPUP MENU
174 | POPUP_CAPTION_DEFAULT = 'Popup Menu';
175 |
176 | POPUP_SPACING_TOPBOTTOM = 5;
177 | POPUP_SEPARATOR_HEIGHT = 1;
178 | POPUP_ITEM_HEIGHT = 35;
179 | POPUP_DECOR_OPACITY = 15;
180 |
181 | POPUP_ANIMATE_SIZE = 400;
182 | POPUP_ANIMATE_X_SIZE = 50;
183 | POPUP_MINIMUM_WIDTH = 215;
184 | POPUP_FRACTION_SPACE = 2;
185 |
186 | POPUP_LINE_SPACING = 10;
187 | POPUP_ITEM_SPACINT = 20;
188 |
189 | POPUP_RADIO = #$E915;
190 | POPUP_CHECKMARK = #$E73E;
191 |
192 | POPUP_TEXT_DISABLED = $808080;
193 |
194 | POPUP_ITEMS_OVERLAY_DISTANCE = 10;
195 |
196 | POPUP_SELECTION_ROUND = 15;
197 | POPUP_MENU_ROUND = 30;
198 |
199 |
200 | implementation
201 |
202 | end.
203 |
--------------------------------------------------------------------------------
/Source/CFX.Effects.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Effects;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Messages,
8 | Windows,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | Types,
13 | CFX.Colors,
14 | CFX.ThemeManager,
15 | CFX.Graphics,
16 | CFX.Constants,
17 | SysUtils,
18 | CFX.Classes,
19 | CFX.Types,
20 | CFX.VarHelpers,
21 | CFX.BlurFunctions,
22 | CFX.Linker,
23 | Math,
24 | CFX.GDI,
25 | CFX.Controls;
26 |
27 | type
28 | FXEffect = class(FXWindowsControl)
29 | private
30 | FDrawColors: FXCompleteColorSet;
31 | FCustomColors: FXColorSets;
32 | FHitTest: boolean;
33 |
34 | protected
35 | procedure PaintBuffer; override;
36 |
37 | // Internal
38 | procedure UpdateColors; override;
39 | procedure UpdateRects; override;
40 |
41 | // Draw
42 | procedure DrawBackground(var Background: TBitMap; OnlyFill: boolean); override;
43 |
44 | procedure ApplyEffect(Background: TBitMap); virtual;
45 |
46 | procedure CreateParams(var Params: TCreateParams); override;
47 | procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
48 |
49 | // Scaler
50 | procedure ScaleChanged(Scaler: single); override;
51 |
52 | // State
53 | procedure InteractionStateChanged(AState: FXControlState); override;
54 |
55 | published
56 | // Custom Colors
57 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
58 |
59 | // Props
60 | property HitTest: boolean read FHitTest write FHitTest;
61 |
62 | // Events
63 | property OnPaintBuffer;
64 |
65 | // Default props
66 | property Align;
67 | property Constraints;
68 | property Anchors;
69 | property OnEnter;
70 | property OnExit;
71 | property OnClick;
72 | property OnMouseUp;
73 | property OnMouseDown;
74 | property OnMouseEnter;
75 | property OnMouseLeave;
76 | property OnMouseMove;
77 |
78 | public
79 | constructor Create(aOwner: TComponent); override;
80 | destructor Destroy; override;
81 |
82 | // Interface
83 | function Background: TColor; override;
84 | end;
85 |
86 | { Blur background }
87 | FXBlurEffect = class(FXEffect)
88 | private
89 | FBlurRadius: real;
90 | FBlurScale: integer;
91 |
92 | procedure SetRadius(const Value: real);
93 | procedure SetScale(const Value: integer);
94 |
95 | protected
96 | procedure ApplyEffect(Background: TBitMap); override;
97 |
98 | published
99 | property BlurRadius: real read FBlurRadius write SetRadius;
100 | property BlurScale: integer read FBlurScale write SetScale;
101 |
102 | public
103 | constructor Create(aOwner: TComponent); override;
104 | end;
105 |
106 | { Fill with color }
107 | FXColorEffect = class(FXEffect)
108 | private
109 | FColor: FXColor;
110 | procedure SetColor(const Value: FXColor);
111 |
112 | protected
113 | procedure ApplyEffect(Background: TBitMap); override;
114 |
115 | published
116 | property Color: FXColor read FColor write SetColor;
117 |
118 | public
119 | constructor Create(aOwner: TComponent); override;
120 | end;
121 |
122 | { Zoom }
123 | FXZoomEffect = class(FXEffect)
124 | private
125 | FZoom: real;
126 | procedure SetZoom(const Value: real);
127 |
128 | protected
129 | procedure ApplyEffect(Background: TBitMap); override;
130 |
131 | published
132 | property Zoom: real read FZoom write SetZoom;
133 |
134 | public
135 | constructor Create(aOwner: TComponent); override;
136 | end;
137 |
138 | { Grayscale }
139 | FXGrayscaleEffect = class(FXEffect)
140 | private
141 |
142 | protected
143 | procedure ApplyEffect(Background: TBitMap); override;
144 | end;
145 |
146 | { Invert }
147 | FXInvertEffect = class(FXEffect)
148 | private
149 |
150 | protected
151 | procedure ApplyEffect(Background: TBitMap); override;
152 | end;
153 |
154 | { Invert }
155 | FXDeepFryEffect = class(FXEffect)
156 | private
157 |
158 | protected
159 | procedure ApplyEffect(Background: TBitMap); override;
160 | end;
161 |
162 | { Glow }
163 | FXGlowEffect = class(FXEffect)
164 | private
165 |
166 | protected
167 | procedure ApplyEffect(Background: TBitMap); override;
168 | end;
169 |
170 | implementation
171 |
172 | procedure FXEffect.ApplyEffect;
173 | begin
174 | // none
175 | end;
176 |
177 | function FXEffect.Background: TColor;
178 | begin
179 | Result := FDrawColors.BackGround;
180 | end;
181 |
182 | constructor FXEffect.Create(aOwner: TComponent);
183 | begin
184 | inherited;
185 | // Props
186 | FHitTest := false;
187 | TabStop := false;
188 | AutoFocusLine := false;
189 |
190 | // Custom Color
191 | FCustomColors := FXColorSets.Create(Self);
192 |
193 | FDrawColors := FXCompleteColorSet.Create;
194 |
195 | // Sizing
196 | Height := 40;
197 | Width := 200;
198 | end;
199 |
200 | procedure FXEffect.CreateParams(var Params: TCreateParams);
201 | begin
202 | inherited;
203 | Params.ExStyle := Params.ExStyle;
204 | end;
205 |
206 | destructor FXEffect.Destroy;
207 | begin
208 | FreeAndNil( FCustomColors );
209 | FreeAndNil( FDrawColors );
210 | inherited;
211 | end;
212 |
213 | procedure FXEffect.DrawBackground(var Background: TBitMap; OnlyFill: boolean);
214 | begin
215 | inherited;
216 | if Enabled then
217 | ApplyEffect(Background);
218 | end;
219 |
220 | procedure FXEffect.InteractionStateChanged(AState: FXControlState);
221 | begin
222 | // do not update
223 | end;
224 |
225 | procedure FXEffect.PaintBuffer;
226 | begin
227 | // Background
228 | Color := FDrawColors.BackGround;
229 | PaintBackground;
230 |
231 | // Inherit
232 | inherited;
233 | end;
234 |
235 | procedure FXEffect.WMNCHitTest(var Message: TWMNCHitTest);
236 | begin
237 | if FHitTest then
238 | inherited
239 | else
240 | Message.Result := HTTRANSPARENT;
241 | end;
242 |
243 | procedure FXEffect.UpdateColors;
244 | begin
245 | FDrawColors.Assign( ThemeManager.SystemColor );
246 |
247 | if not Enabled then
248 | begin
249 | FDrawColors.Foreground := $808080;
250 | end
251 | else
252 | begin
253 | // Access theme manager
254 | if FCustomColors.Enabled then
255 | // Load custom
256 | FDrawColors.LoadFrom( FCustomColors, ThemeManager.DarkTheme )
257 | else
258 | // Build color palette
259 | FDrawColors.LoadFrom( ThemeManager.SystemColorSet, ThemeManager.DarkTheme );
260 | end;
261 | end;
262 |
263 | procedure FXEffect.UpdateRects;
264 | begin
265 | //
266 | end;
267 |
268 | procedure FXEffect.ScaleChanged(Scaler: single);
269 | begin
270 | inherited;
271 | // update scale
272 | end;
273 |
274 | { FXBlurEffect }
275 |
276 | procedure FXBlurEffect.ApplyEffect;
277 | begin
278 | FastBlur(Background, FBlurRadius, FBlurScale);
279 | end;
280 |
281 | constructor FXBlurEffect.Create(aOwner: TComponent);
282 | begin
283 | inherited;
284 | FBlurRadius := 1;
285 | FBlurScale := 1;
286 | end;
287 |
288 | procedure FXBlurEffect.SetRadius(const Value: real);
289 | begin
290 | if FBlurRadius = Value then
291 | Exit;
292 |
293 | FBlurRadius := Value;
294 | Redraw;
295 | end;
296 |
297 | procedure FXBlurEffect.SetScale(const Value: integer);
298 | begin
299 | if FBlurScale = Value then
300 | Exit;
301 |
302 | FBlurScale := Value;
303 | Redraw;
304 | end;
305 |
306 | { FXColorEffect }
307 |
308 | procedure FXColorEffect.ApplyEffect(Background: TBitMap);
309 | begin
310 | with Background.Canvas do
311 | begin
312 | GDITint(ClipRect, FColor);
313 | end;
314 | end;
315 |
316 | constructor FXColorEffect.Create(aOwner: TComponent);
317 | begin
318 | inherited;
319 | FColor := FXColors.Aquamarine;
320 | end;
321 |
322 | procedure FXColorEffect.SetColor(const Value: FXColor);
323 | begin
324 | if FColor = Value then
325 | Exit;
326 |
327 | FColor := Value;
328 | Redraw;
329 | end;
330 |
331 | { FXZoomEffect }
332 |
333 | procedure FXZoomEffect.ApplyEffect(Background: TBitMap);
334 | var
335 | R: TRect;
336 | begin
337 | inherited;
338 | if FZoom <> 1 then
339 | begin
340 | R := Background.Canvas.ClipRect;
341 |
342 | R.Width := Max(round(R.Width / Zoom), 1);
343 | R.Height := Max(round(R.Height / Zoom), 1);
344 |
345 | RectCenter(R, Background.Canvas.ClipRect);
346 |
347 | with Background.Canvas do
348 | begin
349 | CopyRect(ClipRect, Background.Canvas, R);
350 | end;
351 | end;
352 | end;
353 |
354 | constructor FXZoomEffect.Create(aOwner: TComponent);
355 | begin
356 | inherited;
357 | FZoom := 1.25;
358 | end;
359 |
360 | procedure FXZoomEffect.SetZoom(const Value: real);
361 | begin
362 | if (FZoom = Value) or (FZoom < 1) then
363 | Exit;
364 |
365 | FZoom := Value;
366 | Redraw;
367 | end;
368 |
369 | { FXGrayscaleEffect }
370 |
371 | procedure FXGrayscaleEffect.ApplyEffect(Background: TBitMap);
372 | begin
373 | Background.PixelFormat := pf32bit;
374 | GrayscaleBitmap(Background);
375 | end;
376 |
377 | { FXInvertEffect }
378 |
379 | procedure FXInvertEffect.ApplyEffect(Background: TBitMap);
380 | var
381 | B: TBitMap;
382 | R: TRect;
383 | begin
384 | B := TBitMap.Create(Background.Width, Background.Height);
385 | try
386 | with B.Canvas do
387 | begin
388 | FillRect(ClipRect);
389 | end;
390 |
391 | R := B.Canvas.ClipRect;
392 | BitBlt(Background.Canvas.Handle, R.Left, R.Top, R.Width, R.Height,
393 | B.Canvas.Handle, 0, 0, SRCINVERT);
394 | finally
395 | B.Free;
396 | end;
397 | end;
398 |
399 | { FXDeepFryEffect }
400 |
401 | procedure FXDeepFryEffect.ApplyEffect(Background: TBitMap);
402 | var
403 | B: TBitMap;
404 | R: TRect;
405 | begin
406 | B := TBitMap.Create(Background.Width, Background.Height);
407 | try
408 | with B.Canvas do
409 | begin
410 | FillRect(ClipRect);
411 | end;
412 |
413 | R := B.Canvas.ClipRect;
414 | BitBlt(Background.Canvas.Handle, R.Left, R.Top, R.Width, R.Height,
415 | B.Canvas.Handle, 0, 0, PATINVERT);
416 | finally
417 | B.Free;
418 | end;
419 | end;
420 |
421 | { FXGlowEffect }
422 |
423 | procedure FXGlowEffect.ApplyEffect(Background: TBitMap);
424 | begin
425 | ApplyGlowEffect(Background, FXColors.Blue, 0);
426 | end;
427 |
428 | end.
429 |
--------------------------------------------------------------------------------
/Source/CFX.FormClasses.pas:
--------------------------------------------------------------------------------
1 | unit CFX.FormClasses;
2 |
3 | interface
4 | uses
5 | Windows,
6 | Vcl.Graphics,
7 | Classes,
8 | Types,
9 | Vcl.Clipbrd,
10 | CFX.Types,
11 | CFX.Constants,
12 | SysUtils,
13 | CFX.Colors,
14 | Vcl.Forms,
15 | CFX.Graphics,
16 | CFX.VarHelpers,
17 | CFX.ThemeManager,
18 | Vcl.Controls,
19 | CFX.Files,
20 | Messages,
21 | TypInfo,
22 | CFX.Linker,
23 | CFX.Classes,
24 | CFX.Forms,
25 | CFX.ToolTip,
26 | CFX.TextBox,
27 | CFX.Panels,
28 | Vcl.StdCtrls,
29 | Vcl.ExtCtrls,
30 | Vcl.Imaging.pngimage,
31 | CFX.Imported,
32 | CFX.Button,
33 | CFX.Progress,
34 | CFX.StandardIcons,
35 | CFX.Utilities,
36 | CFX.StringUtils,
37 | CFX.ScrollBox,
38 | CFX.Internet;
39 |
40 | type
41 | FXFillForm = class(TForm)
42 | private
43 | FCustomColors: FXColorSets;
44 | FDrawColors: FXColorSet;
45 | FThemeChange: FXThemeChange;
46 | FParentForm: TForm;
47 | FFillMode: FXFormFill;
48 | FCloseAction: FXFormCloseAction;
49 | FTitlebarHeight: integer;
50 |
51 | // Setters
52 | procedure SetParentForm(const Value: TForm);
53 | procedure SetFillMode(const Value: FXFormFill);
54 |
55 | protected
56 | var Margin: integer;
57 | var Container: FXPanel;
58 |
59 | procedure InitializeNewForm; override;
60 |
61 | procedure BuildControls; virtual;
62 | procedure Resize; override;
63 |
64 | procedure DoClose(var Action: TCloseAction); override;
65 |
66 | procedure ApplyFillMode;
67 | procedure ApplyMargins;
68 |
69 | // Mouse
70 | procedure MouseDown(Button : TMouseButton; Shift: TShiftState; X, Y : integer); override;
71 |
72 | published
73 | property CustomColors: FXColorSets read FCustomColors write FCustomColors;
74 |
75 | // Parent
76 | property ParentForm: TForm read FParentForm write SetParentForm;
77 |
78 | // Fill Form
79 | property FillMode: FXFormFill read FFillMode write SetFillMode;
80 | property CloseAction: FXFormCloseAction read FCloseAction write FCloseAction;
81 |
82 | // Theming Engine
83 | property OnThemeChange: FXThemeChange read FThemeChange write FThemeChange;
84 |
85 | public
86 | { Create a FXFillForm based on a FXForm that exists in the project,
87 | loading It's settings and controls. }
88 | constructor Create(aOwner: TComponent); override;
89 |
90 | { Create a FXFillForm based on a custom class. Freed on close }
91 | constructor CreateNew(aOwner: TComponent; Dummy: Integer = 0); override;
92 | destructor Destroy; override;
93 |
94 | procedure InitForm;
95 |
96 | // Procedures
97 | procedure SetBoundsRect(Bounds: TRect);
98 |
99 | // Interface
100 | function IsContainer: Boolean;
101 | procedure UpdateTheme(const UpdateChildren: Boolean);
102 |
103 | function Background: TColor;
104 | end;
105 |
106 | implementation
107 |
108 | { FXFillForm }
109 |
110 | procedure FXFillForm.ApplyFillMode;
111 | begin
112 | if ParentForm = nil then
113 | Exit;
114 |
115 | FTitlebarHeight := FXCustomForm(ParentForm).GetTitlebarHeight;
116 |
117 | case FFillMode of
118 | FXFormFill.TitleBar: begin
119 | var ARect: TRect;
120 |
121 | ARect := ParentForm.ClientRect;
122 | ARect.Top := FTitlebarHeight;
123 |
124 | SetBoundsRect( ARect );
125 | end;
126 | FXFormFill.Complete: SetBoundsRect( ParentForm.ClientRect );
127 | end;
128 | end;
129 |
130 | procedure FXFillForm.ApplyMargins;
131 | begin
132 | with Container do
133 | begin
134 | LockDrawing;
135 |
136 | with Margins do
137 | begin
138 | Top := Margin;
139 | Left := Margin;
140 | Right := Margin;
141 | Bottom := Margin;
142 |
143 | case FFillMode of
144 | FXFormFill.Complete: Top := Top + FTitlebarHeight;
145 | //FXFormFill.TitleBar: ;
146 | end;
147 | end;
148 |
149 | UnlockDrawing;
150 | end;
151 | end;
152 |
153 | function FXFillForm.Background: TColor;
154 | begin
155 | Result := Color;
156 | end;
157 |
158 | procedure FXFillForm.BuildControls;
159 | begin
160 | // nothing
161 | end;
162 |
163 | constructor FXFillForm.Create(aOwner: TComponent);
164 | begin
165 | inherited;
166 |
167 | if aOwner is TForm then
168 | ParentForm := TForm(aOwner);
169 |
170 | FCloseAction := FXFormCloseAction.Hide;
171 |
172 | // Initialise
173 | InitForm;
174 | end;
175 |
176 | constructor FXFillForm.CreateNew(aOwner: TComponent; Dummy: Integer);
177 | begin
178 | inherited;
179 |
180 | if aOwner is TForm then
181 | ParentForm := TForm(aOwner);
182 |
183 | FCloseAction := FXFormCloseAction.Free;
184 |
185 | // Initialise
186 | InitForm;
187 | end;
188 |
189 | destructor FXFillForm.Destroy;
190 | begin
191 |
192 | inherited;
193 | end;
194 |
195 | procedure FXFillForm.DoClose(var Action: TCloseAction);
196 | begin
197 | case FCloseAction of
198 | FXFormCloseAction.Hide: Action := TCloseAction.caHide;
199 | else Action := TCloseAction.caFree;
200 | end;
201 |
202 | inherited;
203 | end;
204 |
205 | procedure FXFillForm.InitForm;
206 | begin
207 | // Default
208 | Margin := 20;
209 | DoubleBuffered := true;
210 |
211 | // Settings
212 | Position := poDesigned;
213 | BorderStyle := bsNone;
214 | Caption := '';
215 | BorderIcons := [];
216 | AlphaBlend := True;
217 | Anchors := [akTop, akLeft, akBottom, akRight];
218 |
219 | // Fill Mode
220 | ApplyFillMode;
221 |
222 | // Container
223 | if ControlCount = 0 then
224 | begin
225 | Container := FXPanel.Create(Self);
226 | with Container do
227 | begin
228 | Parent := Self;
229 |
230 | Align := alClient;
231 | AlignWithMargins := true;
232 | end;
233 | ApplyMargins;
234 | end;
235 |
236 | // Build
237 | BuildControls;
238 |
239 | // Update Theme
240 | UpdateTheme(true);
241 | end;
242 |
243 | procedure FXFillForm.InitializeNewForm;
244 | begin
245 | inherited;
246 | // Create Classes
247 | FCustomColors := FXColorSets.Create(Self);
248 | FDrawColors := FXColorSet.Create(ThemeManager.SystemColorSet, ThemeManager.DarkTheme);
249 | end;
250 |
251 | function FXFillForm.IsContainer: Boolean;
252 | begin
253 | Result := true;
254 | end;
255 |
256 | procedure FXFillForm.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
257 | Y: integer);
258 | begin
259 | inherited;
260 | ReleaseCapture;
261 | SendMessage(ParentForm.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
262 | end;
263 |
264 | procedure FXFillForm.Resize;
265 | begin
266 | inherited;
267 | // next
268 | end;
269 |
270 | procedure FXFillForm.SetBoundsRect(Bounds: TRect);
271 | begin
272 | SetBounds(Bounds.Left, Bounds.Top, Bounds.Width, Bounds.Height);
273 | end;
274 |
275 | procedure FXFillForm.SetFillMode(const Value: FXFormFill);
276 | begin
277 | if FFillMode <> Value then
278 | begin
279 | FFillMode := Value;
280 |
281 | ApplyFillMode;
282 | ApplyMargins;
283 | end;
284 | end;
285 |
286 | procedure FXFillForm.SetParentForm(const Value: TForm);
287 | begin
288 | FParentForm := Value;
289 | Parent := Value;
290 | end;
291 |
292 | procedure FXFillForm.UpdateTheme(const UpdateChildren: Boolean);
293 | var
294 | i: integer;
295 | begin
296 | // Update Colors
297 | if CustomColors.Enabled then
298 | begin
299 | FDrawColors.Background := ExtractColor( CustomColors, FXColorType.BackGround );
300 | FDrawColors.Foreground := ExtractColor( CustomColors, FXColorType.Foreground );
301 | end
302 | else
303 | begin
304 | FDrawColors.Background := ThemeManager.SystemColor.BackGround;
305 | FDrawColors.Foreground := ThemeManager.SystemColor.ForeGround;
306 | end;
307 |
308 | if Container <> nil then
309 | Container.CustomColors.Assign( CustomColors );
310 |
311 | // Color
312 | Color := FDrawColors.BackGround;
313 |
314 | // Update tooltip style
315 | if ThemeManager.DarkTheme then
316 | HintWindowClass := FXDarkTooltip
317 | else
318 | HintWindowClass := FXLightTooltip;
319 |
320 | // Font Color
321 | Font.Color := FDrawColors.Foreground;
322 |
323 | // Notify Theme Change
324 | if Assigned(FThemeChange) then
325 | FThemeChange(Self, FXThemeType.AppTheme, ThemeManager.DarkTheme, ThemeManager.AccentColor);
326 |
327 | // Update children
328 | if IsContainer and UpdateChildren then
329 | begin
330 | LockWindowUpdate(Handle);
331 | for i := 0 to ComponentCount -1 do
332 | if Supports(Components[i], IFXComponent) then
333 | (Components[i] as IFXComponent).UpdateTheme(UpdateChildren);
334 | LockWindowUpdate(0);
335 | end;
336 | end;
337 |
338 | end.
339 |
--------------------------------------------------------------------------------
/Source/CFX.Hint.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Hint;
2 |
3 | interface
4 | uses
5 | Classes, Types, Winapi.Windows, Winapi.Messages, Vcl.Controls, Vcl.Graphics,
6 | CFX.Constants, SysUtils, CFX.ThemeManager, CFX.Colors, CFX.Graphics,
7 | CFX.ToolTip, Vcl.ExtCtrls;
8 |
9 | type
10 | FXHintPopup = class
11 | private
12 | FHintClass: FXCustomTooltip;
13 | FAutoHideTimer: TTimer;
14 |
15 | FIsVisible: boolean;
16 | FCenterToPosition: boolean;
17 |
18 | FText: string;
19 | FPosition: TPoint;
20 | FDuration: integer;
21 | FAutoHide: boolean;
22 | FMaxWidth: integer;
23 |
24 | procedure HideProc(Sender: TObject);
25 | procedure ApplyColor;
26 | function MakeHintRect: TRect;
27 | procedure SetAutoHide(const Value: boolean);
28 | function GetFont: TFont;
29 |
30 | public
31 | constructor Create;
32 | destructor Destroy; override;
33 |
34 | property Font: TFont read GetFont;
35 |
36 | property Text: string read FText write FText;
37 | property Duration: integer read FDuration write FDuration;
38 | property Position: TPoint read FPosition write FPosition;
39 | property AutoHide: boolean read FAutoHide write SetAutoHide;
40 | property MaxWidth: integer read FMaxWidth write FMaxWidth default 200;
41 | property CenterToPosition: boolean read FCenterToPosition write FCenterToPosition;
42 |
43 | property IsVisible: boolean read FIsVisible;
44 |
45 | procedure Hide;
46 |
47 | procedure Show;
48 | procedure ShowAtPoint(APoint: TPoint);
49 | end;
50 |
51 | implementation
52 |
53 | { FXHintPopup }
54 |
55 | procedure FXHintPopup.ApplyColor;
56 | begin
57 | if ThemeManager.DarkTheme then
58 | FXDarkTooltip(FHintClass).ApplyColor
59 | else
60 | FXLightTooltip(FHintClass).ApplyColor;
61 | end;
62 |
63 | constructor FXHintPopup.Create;
64 | begin
65 | inherited;
66 | FDuration := 1000;
67 | FMaxWidth := 200;
68 | FAutoHide := true;
69 | FText := TEXT_DEFAULT_GENERIC;
70 | FCenterToPosition := false;
71 |
72 | // Classes
73 | FHintClass := FXCustomTooltip.Create(nil);
74 | FAutoHideTimer := TTimer.Create(nil);
75 | with FAutoHideTimer do
76 | begin
77 | Enabled := false;
78 |
79 | OnTimer := HideProc;
80 | end;
81 | end;
82 |
83 | destructor FXHintPopup.Destroy;
84 | begin
85 | FreeAndNil( FHintClass );
86 | FAutoHideTimer.Enabled := false;
87 | FreeAndNil( FAutoHideTimer );
88 | end;
89 |
90 | function FXHintPopup.GetFont: TFont;
91 | begin
92 | Result := FHintClass.Font;
93 | end;
94 |
95 | procedure FXHintPopup.Hide;
96 | begin
97 | FIsVisible := false;
98 | FHintClass.Hide;
99 | end;
100 |
101 | procedure FXHintPopup.HideProc(Sender: TObject);
102 | begin
103 | if FAutoHide then
104 | Hide;
105 |
106 | FAutoHideTimer.Enabled := false;
107 | end;
108 |
109 | function FXHintPopup.MakeHintRect: TRect;
110 | begin
111 | Result := FHintClass.CalcHintRect( FMaxWidth, FText, nil );
112 | Result.Offset(FPosition);
113 |
114 | if FCenterToPosition then
115 | Result.Offset(-Result.Width div 2, -Result.Height div 2);
116 | end;
117 |
118 | procedure FXHintPopup.SetAutoHide(const Value: boolean);
119 | begin
120 | FAutoHide := Value;
121 |
122 | if Value and IsVisible then
123 | FAutoHideTimer.Enabled := FAutoHide;
124 | end;
125 |
126 | procedure FXHintPopup.Show;
127 | begin
128 | // Reset Timer
129 | FAutoHideTimer.Enabled := false;
130 |
131 | // Auto Hide
132 | FAutoHideTimer.Interval := FDuration;
133 | FAutoHideTimer.Enabled := FAutoHide;
134 |
135 | // Theme
136 | ApplyColor;
137 |
138 | // Show
139 | FIsVisible := true;
140 | FHintClass.Visible := true;
141 | FHintClass.ActivateHint( MakeHintRect, FText )
142 | end;
143 |
144 | procedure FXHintPopup.ShowAtPoint(APoint: TPoint);
145 | begin
146 | FPosition := APoint;
147 | Show;
148 | end;
149 |
150 | end.
151 |
--------------------------------------------------------------------------------
/Source/CFX.IconView.pas:
--------------------------------------------------------------------------------
1 | unit CFX.IconView;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Winapi.Messages,
8 | Winapi.Windows,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | Types,
13 | CFX.Colors,
14 | CFX.ThemeManager,
15 | CFX.Graphics,
16 | CFX.Constants,
17 | SysUtils,
18 | CFX.Classes,
19 | CFX.Types,
20 | CFX.VarHelpers,
21 | CFX.Linker,
22 | CFX.Controls;
23 |
24 | type
25 | FXIconView = class(FXWindowsControl)
26 | private
27 | var DrawRect, IconRect: TRect;
28 | FDrawColors: FXCompleteColorSet;
29 | FCustomColors: FXColorSets;
30 | FUseAccentAsForeground: boolean;
31 | FScale: real;
32 | FImage: FXIconSelect;
33 | FVertLayout: FXLayout;
34 | FHorizLayout: FXLayout;
35 |
36 | // Internal
37 | procedure ImageUpdated(Sender: TObject);
38 |
39 | // Getters
40 |
41 | // Setters
42 | procedure SetHorizLayout(const Value: FXLayout);
43 | procedure SetImage(const Value: FXIconSelect);
44 | procedure SetScale(const Value: real);
45 | procedure SetVertLayout(const Value: FXLayout);
46 | procedure SetUseAccentAsForeground(const Value: boolean);
47 |
48 | protected
49 | procedure PaintBuffer; override;
50 |
51 | // Internal
52 | procedure UpdateColors; override;
53 | procedure UpdateRects; override;
54 |
55 | // Scaler
56 | procedure ScaleChanged(Scaler: single); override;
57 |
58 | // State
59 | procedure InteractionStateChanged(AState: FXControlState); override;
60 |
61 | published
62 | // Custom Colors
63 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
64 |
65 | // Style
66 | property UseAccentAsForeground: boolean read FUseAccentAsForeground write SetUseAccentAsForeground default false;
67 |
68 | // Props
69 | property Image: FXIconSelect read FImage write SetImage;
70 | property Scale: real read FScale write SetScale;
71 | property LayoutHorizontal: FXLayout read FHorizLayout write SetHorizLayout default FXLayout.Center;
72 | property LayoutVertical: FXLayout read FVertLayout write SetVertLayout default FXLayout.Center;
73 |
74 | // Default props
75 | property Align;
76 | property Font;
77 | property Transparent;
78 | property Opacity;
79 | property Constraints;
80 | property Anchors;
81 | property Hint;
82 | property ShowHint;
83 | property ParentShowHint;
84 | property TabStop;
85 | property TabOrder;
86 | property FocusFlags;
87 | property DragKind;
88 | property DragCursor;
89 | property DragMode;
90 | property OnDragDrop;
91 | property OnDragOver;
92 | property OnEndDrag;
93 | property OnStartDrag;
94 | property OnEnter;
95 | property OnExit;
96 | property OnClick;
97 | property OnKeyDown;
98 | property OnKeyUp;
99 | property OnKeyPress;
100 | property OnMouseUp;
101 | property OnMouseDown;
102 | property OnMouseEnter;
103 | property OnMouseLeave;
104 | property OnMouseMove;
105 |
106 | public
107 | constructor Create(aOwner: TComponent); override;
108 | destructor Destroy; override;
109 |
110 | // Interface
111 | function Background: TColor; override;
112 | end;
113 |
114 | implementation
115 |
116 | function FXIconView.Background: TColor;
117 | begin
118 | Result := FDrawColors.BackGround;
119 | end;
120 |
121 | constructor FXIconView.Create(aOwner: TComponent);
122 | begin
123 | inherited;
124 | // Props
125 | FScale := 1;
126 | FImage := FXIconSelect.Create(Self);
127 | FImage.Enabled := true;
128 | FImage.OnChange := ImageUpdated;
129 |
130 | FHorizLayout := FXLayout.Center;
131 | FVertLayout := FXLayout.Center;
132 |
133 | // Custom Color
134 | FCustomColors := FXColorSets.Create(Self);
135 |
136 | FDrawColors := FXCompleteColorSet.Create;
137 |
138 | // Sizing
139 | Height := 60;
140 | Width := 60;
141 | end;
142 |
143 | destructor FXIconView.Destroy;
144 | begin
145 | FreeAndNil( FImage );
146 | FreeAndNil( FCustomColors );
147 | FreeAndNil( FDrawColors );
148 | inherited;
149 | end;
150 |
151 | procedure FXIconView.InteractionStateChanged(AState: FXControlState);
152 | begin
153 | inherited;
154 | Redraw;
155 | end;
156 |
157 | procedure FXIconView.PaintBuffer;
158 | begin
159 | // Background
160 | Color := FDrawColors.BackGround;
161 | PaintBackground;
162 |
163 | // Draw
164 | with Buffer do
165 | begin
166 | // Write
167 | Brush.Style := bsClear;
168 | if UseAccentAsForeground then
169 | Font.Color := FDrawColors.Accent
170 | else
171 | Font.Color := FDrawColors.ForeGround;
172 | FImage.DrawIcon(Buffer, IconRect);
173 | end;
174 |
175 | // Inherit
176 | inherited;
177 | end;
178 |
179 | procedure FXIconView.UpdateColors;
180 | begin
181 | // Access theme manager
182 | FDrawColors.Assign( ThemeManager.SystemColor );
183 | if not Enabled then begin
184 | FDrawColors.Foreground := $808080;
185 | end
186 | else
187 | if FCustomColors.Enabled then
188 | // Custom Colors
189 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
190 | end;
191 |
192 | procedure FXIconView.ImageUpdated(Sender: TObject);
193 | begin
194 | StandardUpdateLayout;
195 | end;
196 |
197 | procedure FXIconView.UpdateRects;
198 | begin
199 | // Rect
200 | DrawRect := ClientRect;
201 |
202 | // Fill
203 | IconRect := DrawRect;
204 |
205 | // Scale
206 | IconRect.Width := round(DrawRect.Width * Scale);
207 | IconRect.Height := round(DrawRect.Height * Scale);
208 |
209 | if IconRect.Height < IconRect.Width then
210 | IconRect.Width := IconRect.Height
211 | else
212 | IconRect.Height := IconRect.Width;
213 |
214 | // Allign
215 | case FHorizLayout of
216 | FXLayout.Beginning: ;
217 | FXLayout.Center: IconRect.Offset((DrawRect.Width - IconRect.Width) div 2, 0);
218 | FXLayout.Ending: IconRect.Offset(DrawRect.Width - IconRect.Width, 0);
219 | end;
220 |
221 | case FVertLayout of
222 | FXLayout.Beginning: ;
223 | FXLayout.Center: IconRect.Offset(0, (ClientRect.Height - IconRect.Height) div 2);
224 | FXLayout.Ending: IconRect.Offset(0, DrawRect.Height - IconRect.Height);
225 | end;
226 | end;
227 |
228 | procedure FXIconView.ScaleChanged(Scaler: single);
229 | begin
230 | UpdateRects;
231 | inherited;
232 | end;
233 |
234 | procedure FXIconView.SetHorizLayout(const Value: FXLayout);
235 | begin
236 | if FHorizLayout = Value then
237 | Exit;
238 |
239 | FHorizLayout := Value;
240 | StandardUpdateLayout;
241 | end;
242 |
243 | procedure FXIconView.SetImage(const Value: FXIconSelect);
244 | begin
245 | if FImage = Value then
246 | Exit;
247 |
248 | FImage := Value;
249 | StandardUpdateDraw;
250 | end;
251 |
252 | procedure FXIconView.SetScale(const Value: real);
253 | begin
254 | if FScale = Value then
255 | Exit;
256 |
257 | FScale := Value;
258 | StandardUpdateLayout;
259 | end;
260 |
261 | procedure FXIconView.SetUseAccentAsForeground(const Value: boolean);
262 | begin
263 | if FUseAccentAsForeground = Value then
264 | Exit;
265 |
266 | FUseAccentAsForeground := Value;
267 |
268 | // Update
269 | StandardUpdateDraw;
270 | end;
271 |
272 | procedure FXIconView.SetVertLayout(const Value: FXLayout);
273 | begin
274 | if FVertLayout = Value then
275 | Exit;
276 |
277 | FVertLayout := Value;
278 | StandardUpdateLayout;
279 | end;
280 |
281 | end.
282 |
--------------------------------------------------------------------------------
/Source/CFX.ImageList.pas:
--------------------------------------------------------------------------------
1 | unit CFX.ImageList;
2 |
3 | interface
4 |
5 | uses
6 | SysUtils,
7 | Winapi.Windows,
8 | Classes,
9 | Types,
10 | UITypes,
11 | Vcl.Controls,
12 | Vcl.Graphics,
13 | Vcl.ExtCtrls,
14 | Vcl.Dialogs,
15 | Threading,
16 | System.Generics.Collections,
17 | Vcl.Menus,
18 | CFX.Graphics,
19 | CFX.VarHelpers,
20 | Vcl.Forms,
21 | DateUtils,
22 | IOUtils,
23 | CFX.Utilities,
24 | CFX.ThemeManager,
25 | CFX.BlurMaterial,
26 | CFX.Classes,
27 | CFX.Constants,
28 | CFX.Colors,
29 | CFX.Math,
30 | CFX.GDI,
31 | CFX.Animations,
32 | CFX.Types;
33 |
34 | type
35 |
36 | // Image Array
37 | FXPictureImages = class(FXPersistent)
38 | private
39 | FPictures: TArray;
40 |
41 | function CreateNewSpot: integer;
42 |
43 | function GetPicture(AIndex: Integer): TPicture;
44 | procedure SetPicture(AIndex: Integer; const Value: TPicture);
45 |
46 | protected
47 | // Serialization
48 | procedure DefineProperties(Filer: TFiler); override;
49 | procedure ReadData(Stream: TStream);
50 | procedure WriteData(Stream: TStream);
51 |
52 | public
53 | constructor Create(AOwner : TPersistent); override;
54 | destructor Destroy; override;
55 |
56 | // Images
57 | property Pictures[AIndex: Integer]: TPicture read GetPicture write SetPicture;
58 |
59 | function Count: integer;
60 |
61 | // Load and Delete
62 | procedure AddNew(Picture: TPicture);
63 | procedure Delete(AIndex: integer);
64 | procedure AddNewFromFile(FileName: string);
65 | end;
66 |
67 | // Image List
68 | FXImageList = class(FXComponent)
69 | private
70 | FInternalImages: FXPictureImages;
71 |
72 | procedure AssignPic(const Value: FXPictureImages);
73 |
74 | published
75 | property InternalImages: FXPictureImages read FInternalImages write AssignPic;
76 |
77 | public
78 | constructor Create(AOwner: TComponent); override;
79 | destructor Destroy; override;
80 | end;
81 |
82 | implementation
83 |
84 | { FXImageList }
85 |
86 | procedure FXImageList.AssignPic(const Value: FXPictureImages);
87 | begin
88 | FInternalImages.Assign(Value) ;
89 | end;
90 |
91 | constructor FXImageList.Create(AOwner: TComponent);
92 | begin
93 | inherited;
94 | FInternalImages := FXPictureImages.Create(Self);
95 | end;
96 |
97 | destructor FXImageList.Destroy;
98 | begin
99 | FreeAndNil(FInternalImages);
100 | inherited;
101 | end;
102 |
103 | { FXPictureImages }
104 |
105 | procedure FXPictureImages.AddNew(Picture: TPicture);
106 | var
107 | NewIndex: integer;
108 | begin
109 | NewIndex := CreateNewSpot;
110 |
111 | FPictures[NewIndex] := TPicture.Create;
112 | FPictures[NewIndex].Assign(Picture);
113 | end;
114 |
115 | procedure FXPictureImages.AddNewFromFile(FileName: string);
116 | var
117 | NewIndex: integer;
118 | begin
119 | NewIndex := CreateNewSpot;
120 |
121 | FPictures[NewIndex] := TPicture.Create;
122 | FPictures[NewIndex].LoadFromFile(FileName);
123 | end;
124 |
125 | function FXPictureImages.Count: integer;
126 | begin
127 | Result := Length(FPictures);
128 | end;
129 |
130 | constructor FXPictureImages.Create(AOwner: TPersistent);
131 | begin
132 | inherited;
133 | SetLength(FPictures, 0);
134 | end;
135 |
136 | function FXPictureImages.CreateNewSpot: integer;
137 | begin
138 | Result := Length(FPictures);
139 | SetLength(FPictures, Result + 1);
140 | end;
141 |
142 | procedure FXPictureImages.DefineProperties(Filer: TFiler);
143 | begin
144 | inherited;
145 | Filer.DefineBinaryProperty('Pictures', ReadData, WriteData, true);
146 | end;
147 |
148 | procedure FXPictureImages.Delete(AIndex: integer);
149 | var
150 | I: Integer;
151 | begin
152 | if FPictures[AIndex] <> nil then
153 | FPictures[AIndex].Free;
154 |
155 | for I := AIndex to High(FPictures) - 1 do
156 | FPictures[I] := FPictures[I + 1];
157 | end;
158 |
159 | destructor FXPictureImages.Destroy;
160 | var
161 | I: Integer;
162 | begin
163 | // Free Pictures
164 | for I := 0 to High(FPictures) do
165 | if FPictures[I] <> nil then
166 | FPictures[I].Free;
167 |
168 | SetLength(FPictures, 0);
169 | inherited;
170 | end;
171 |
172 | function FXPictureImages.GetPicture(AIndex: Integer): TPicture;
173 | begin
174 | Result := FPictures[AIndex];
175 | end;
176 |
177 | procedure FXPictureImages.ReadData(Stream: TStream);
178 | var
179 | Count: Integer;
180 | I: Integer;
181 | Picture: TPicture;
182 | begin
183 | Stream.ReadBuffer(Count, SizeOf(Count));
184 | SetLength(FPictures, Count);
185 | for I := 0 to Count - 1 do
186 | begin
187 | Picture := TPicture.Create;
188 | Picture.LoadFromStream(Stream);
189 | FPictures[I] := Picture;
190 | end;
191 | end;
192 |
193 | procedure FXPictureImages.SetPicture(AIndex: Integer; const Value: TPicture);
194 | begin
195 | Pictures[AIndex].Assign(Value);
196 | end;
197 |
198 | procedure FXPictureImages.WriteData(Stream: TStream);
199 | var
200 | Count: Integer;
201 | I: Integer;
202 | begin
203 | Count := Length(FPictures);
204 |
205 | Stream.WriteBuffer(Count, SizeOf(Count));
206 | for I := 0 to Count - 1 do
207 | FPictures[I].SaveToStream(Stream);
208 | end;
209 |
210 | end.
211 |
--------------------------------------------------------------------------------
/Source/CFX.Imported.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Imported;
2 |
3 | interface
4 |
5 | uses
6 | Windows, Classes, Types, Vcl.Graphics, Vcl.Imaging.pngimage;
7 |
8 |
9 | procedure ConvertToPNG(Source: TGraphic; Dest: TPngImage);
10 |
11 | implementation
12 |
13 | procedure ConvertToPNG(Source: TGraphic; Dest: TPngImage);
14 | type
15 | TRGBALine = array[Word] of TRGBQuad;
16 | PRGBALine = ^TRGBALine;
17 | var
18 | MaskLines: array of Vcl.Imaging.pngimage.PByteArray;
19 |
20 | function ColorToTriple(const Color: TColor): TRGBTriple;
21 | begin
22 | Result.rgbtBlue := Color shr 16 and $FF;
23 | Result.rgbtGreen := Color shr 8 and $FF;
24 | Result.rgbtRed := Color and $FF;
25 | end;
26 |
27 | procedure GetAlphaMask(SourceColor: TBitmap);
28 | type
29 | TBitmapInfoV4 = packed record
30 | bmiHeader: TBitmapV4Header; //Otherwise I may not get per-pixel alpha values.
31 | bmiColors: array[0..2] of TRGBQuad; // reserve space for color lookup table
32 | end;
33 | var
34 | Bits: PRGBALine;
35 | { The BitmapInfo parameter to GetDIBits is delared as var parameter. So instead of casting around, we simply use
36 | the absolute directive to refer to the same memory area. }
37 | BitmapInfo: TBitmapInfoV4;
38 | BitmapInfoFake: TBitmapInfo absolute BitmapInfo;
39 | I, X, Y: Integer;
40 | HasAlpha: Boolean;
41 | BitsSize: Integer;
42 | bmpDC: HDC;
43 | bmpHandle: HBITMAP;
44 | begin
45 | BitsSize := 4 * SourceColor.Width * SourceColor.Height;
46 | Bits := AllocMem(BitsSize);
47 | try
48 | FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);
49 | BitmapInfo.bmiHeader.bV4Size := SizeOf(BitmapInfo.bmiHeader);
50 | BitmapInfo.bmiHeader.bV4Width := SourceColor.Width;
51 | BitmapInfo.bmiHeader.bV4Height := -SourceColor.Height; //Otherwise the image is upside down.
52 | BitmapInfo.bmiHeader.bV4Planes := 1;
53 | BitmapInfo.bmiHeader.bV4BitCount := 32;
54 | BitmapInfo.bmiHeader.bV4V4Compression := BI_BITFIELDS;
55 | BitmapInfo.bmiHeader.bV4SizeImage := BitsSize;
56 | BitmapInfo.bmiColors[0].rgbRed := 255;
57 | BitmapInfo.bmiColors[1].rgbGreen := 255;
58 | BitmapInfo.bmiColors[2].rgbBlue := 255;
59 |
60 | { Getting the bitmap Handle will invalidate the Canvas.Handle, so it is important to retrieve them in the correct
61 | order. As parameter evaluation order is undefined and differs between Win32 and Win64, we get invalid values
62 | for Canvas.Handle when we use those properties directly in the call to GetDIBits. }
63 | bmpHandle := SourceColor.Handle;
64 | bmpDC := SourceColor.Canvas.Handle;
65 | if GetDIBits(bmpDC, bmpHandle, 0, SourceColor.Height, Bits, BitmapInfoFake, DIB_RGB_COLORS) > 0 then begin
66 | //Because Win32 API is a piece of crap when it comes to icons, I have to check
67 | //whether an has an alpha-channel the hard way.
68 | HasAlpha := False;
69 | for I := 0 to (SourceColor.Height * SourceColor.Width) - 1 do begin
70 | if Bits[I].rgbReserved <> 0 then begin
71 | HasAlpha := True;
72 | Break;
73 | end;
74 | end;
75 | if HasAlpha then begin
76 | //OK, so not all alpha-values are 0, which indicates the existence of an
77 | //alpha-channel.
78 | I := 0;
79 | for Y := 0 to SourceColor.Height - 1 do
80 | for X := 0 to SourceColor.Width - 1 do begin
81 | MaskLines[Y][X] := Bits[I].rgbReserved;
82 | Inc(I);
83 | end;
84 | end;
85 | end;
86 | finally
87 | FreeMem(Bits, BitsSize);
88 | end;
89 | end;
90 |
91 | function WinXPOrHigher: Boolean;
92 | var
93 | Info: TOSVersionInfo;
94 | begin
95 | Info.dwOSVersionInfoSize := SizeOf(Info);
96 | GetVersionEx(Info);
97 | Result := (Info.dwPlatformId = VER_PLATFORM_WIN32_NT) and
98 | ((Info.dwMajorVersion > 5) or
99 | ((Info.dwMajorVersion = 5) and (Info.dwMinorVersion >= 1)));
100 | end;
101 |
102 | var
103 | Temp, SourceColor, SourceMask: TBitmap;
104 | X, Y: Integer;
105 | Line: PRGBLine;
106 | MaskLine, AlphaLine: Vcl.Imaging.pngimage.PByteArray;
107 | TransparentColor, CurrentColor: TColor;
108 | IconInfo: TIconInfo;
109 | AlphaNeeded: Boolean;
110 | begin
111 | Assert(Dest <> nil, 'Dest is nil!');
112 | //A PNG does not have to be converted
113 | if Source is TPngImage then begin
114 | Dest.Assign(Source);
115 | Exit;
116 | end;
117 |
118 | AlphaNeeded := False;
119 | Temp := TBitmap.Create;
120 | SetLength(MaskLines, Source.Height);
121 | for Y := 0 to Source.Height - 1 do begin
122 | MaskLines[Y] := AllocMem(Source.Width);
123 | FillMemory(MaskLines[Y], Source.Width, 255);
124 | end;
125 | try
126 | //Initialize intermediate color bitmap
127 | Temp.Width := Source.Width;
128 | Temp.Height := Source.Height;
129 | Temp.PixelFormat := pf24bit;
130 |
131 | //Now figure out the transparency
132 | if Source is TBitmap then begin
133 | if Source.Transparent then begin
134 | //TBitmap is just about comparing the drawn colors against the TransparentColor
135 | if TBitmap(Source).TransparentMode = tmFixed then
136 | TransparentColor := TBitmap(Source).TransparentColor
137 | else
138 | TransparentColor := TBitmap(Source).Canvas.Pixels[0, Source.Height - 1];
139 |
140 | for Y := 0 to Temp.Height - 1 do begin
141 | Line := Temp.ScanLine[Y];
142 | MaskLine := MaskLines[Y];
143 | for X := 0 to Temp.Width - 1 do begin
144 | CurrentColor := GetPixel(TBitmap(Source).Canvas.Handle, X, Y);
145 | if CurrentColor = TransparentColor then begin
146 | MaskLine^[X] := 0;
147 | AlphaNeeded := True;
148 | end;
149 | Line[X] := ColorToTriple(CurrentColor);
150 | end;
151 | end;
152 | end
153 | else begin
154 | Temp.Canvas.Draw(0, 0, Source);
155 | end;
156 | end
157 | else if Source is TIcon then begin
158 | //TIcon is more complicated, because there are bitmasked (classic) icons and
159 | //alphablended (modern) icons. Not to forget about the "inverse" color.
160 | GetIconInfo(TIcon(Source).Handle, IconInfo);
161 | SourceColor := TBitmap.Create;
162 | SourceMask := TBitmap.Create;
163 | try
164 | SourceColor.Handle := IconInfo.hbmColor;
165 | SourceMask.Handle := IconInfo.hbmMask;
166 | Temp.Canvas.Draw(0, 0, SourceColor);
167 | for Y := 0 to Temp.Height - 1 do begin
168 | MaskLine := MaskLines[Y];
169 | for X := 0 to Temp.Width - 1 do begin
170 | if GetPixel(SourceMask.Canvas.Handle, X, Y) <> 0 then begin
171 | MaskLine^[X] := 0;
172 | AlphaNeeded := True;
173 | end;
174 | end;
175 | end;
176 | if (GetDeviceCaps(SourceColor.Canvas.Handle, BITSPIXEL) = 32) and WinXPOrHigher then begin
177 | //This doesn't neccesarily mean we actually have 32bpp in the icon, because the
178 | //bpp of an icon is always the same as the display settings, regardless of the
179 | //actual color depth of the icon :(
180 | AlphaNeeded := True;
181 | GetAlphaMask(SourceColor);
182 | end;
183 | //This still doesn't work for alphablended icons...
184 | finally
185 | SourceColor.Free;
186 | SourceMask.Free
187 | end;
188 | end;
189 |
190 | //And finally, assign the destination PNG image
191 | Dest.Assign(Temp);
192 | if AlphaNeeded then begin
193 | Dest.CreateAlpha;
194 | for Y := 0 to Dest.Height - 1 do begin
195 | AlphaLine := Dest.AlphaScanline[Y];
196 | CopyMemory(AlphaLine, MaskLines[Y], Temp.Width);
197 | end;
198 | end;
199 |
200 | finally
201 | for Y := 0 to Source.Height - 1 do
202 | FreeMem(MaskLines[Y], Source.Width);
203 | Temp.Free;
204 | end;
205 | end;
206 |
207 |
208 | end.
209 |
--------------------------------------------------------------------------------
/Source/CFX.Instances.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Instances;
2 |
3 | interface
4 | uses
5 | Windows,
6 | Messages,
7 | Vcl.Forms,
8 | SysUtils;
9 |
10 | // App Identifier
11 | function GetSemafor: string;
12 | procedure SetSemafor(Value: string);
13 |
14 | // Other instance
15 | function HasOtherInstances: boolean;
16 | procedure IPCSendMessage(target: HWND; const message: string);
17 |
18 | // Handle
19 | function GetOtherHandle: HWND;
20 | procedure FocusOtherWindow;
21 |
22 |
23 | implementation
24 |
25 | var
26 | APP_SEMAFOR: string = '';
27 |
28 | function GetSemafor: string;
29 | begin
30 | if APP_SEMAFOR = '' then
31 | begin
32 | APP_SEMAFOR := StringReplace( Application.ExeName, '.', '_', [rfReplaceAll]);
33 | APP_SEMAFOR := StringReplace( APP_SEMAFOR, '\', '_', [rfReplaceAll]);
34 | APP_SEMAFOR := StringReplace( APP_SEMAFOR, ':', '', [rfReplaceAll]);
35 |
36 | if Length( APP_SEMAFOR ) > 100 then
37 | APP_SEMAFOR := Copy( APP_SEMAFOR, Length(APP_SEMAFOR) - 100, 100 );
38 | end;
39 |
40 | Result := APP_SEMAFOR;
41 | end;
42 |
43 | procedure SetSemafor(Value: string);
44 | begin
45 | APP_SEMAFOR := Value;
46 | end;
47 |
48 | function HasOtherInstances: boolean;
49 | var
50 | Semafor: THandle;
51 | begin
52 | { Creates }
53 | Semafor := CreateSemaphore( nil, 0, 1, PChar(GetSemafor) );
54 | Result := ((Semafor <> 0) and { application is already running }
55 | (GetLastError = ERROR_ALREADY_EXISTS));
56 | end;
57 |
58 | function GetOtherHandle: HWND;
59 | begin
60 | Result := CreateSemaphore( nil, 0, 1, PChar(GetSemafor) );
61 | end;
62 |
63 | procedure FocusOtherWindow;
64 | var
65 | npadhandle: HWnd;
66 | begin
67 | npadhandle := GetOtherHandle;
68 |
69 | if npadhandle <> 0 then
70 | begin
71 | SetForegroundWindow(npadhandle);
72 | SendMessage(npadhandle, WM_SYSCOMMAND, SC_RESTORE, 0)
73 | end;
74 | end;
75 |
76 | procedure IPCSendMessage(target: HWND; const message: string);
77 | var
78 | cds: TCopyDataStruct;
79 | begin
80 | cds.dwData := 0;
81 | cds.cbData := Length(message) * SizeOf(Char);
82 | cds.lpData := Pointer(@message[1]);
83 |
84 | SendMessage(target, WM_COPYDATA, 0, LPARAM(@cds));
85 | end;
86 |
87 |
88 | end.
89 |
--------------------------------------------------------------------------------
/Source/CFX.Internet.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Internet;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, Classes, System.SysUtils, System.UITypes,
7 | Types, Vcl.Forms, Vcl.Graphics, CFX.Colors, CFX.Registry, ShellAPI,
8 | CFX.Types, IOUTils, IdHTTP, UrlMon;
9 |
10 | function DownloadFile(Source, Destination: string): Boolean;
11 |
12 | implementation
13 |
14 | function DownloadFile(Source, Destination: string): Boolean;
15 | var
16 | IdHTTP1: TIdHTTP;
17 | FileStream: TFileStream;
18 | begin
19 | try
20 | // Attempt 1 - IDHTTP
21 | IdHTTP1 := TIdHTTP.Create(nil);
22 | IdHTTP1.HandleRedirects := true;
23 |
24 | FileStream := TFileStream.Create(Destination, fmCreate);
25 | try
26 | IdHTTP1.Get(Source, FileStream);
27 |
28 | Result := TFile.Exists(Destination);
29 | finally
30 | IdHTTP1.Free;
31 | FileStream.Free;
32 | end;
33 | except
34 | // Attempt 2 - UrlMon
35 | try
36 | Result := UrlDownloadToFile( nil, PChar(source), PChar( Destination ) , 0, nil ) = 0;
37 | except
38 | // Failure
39 | Result := False;
40 | end;
41 | end;
42 | end;
43 |
44 | end.
45 |
--------------------------------------------------------------------------------
/Source/CFX.Linker.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Linker;
2 |
3 | interface
4 | uses
5 | Vcl.Graphics;
6 |
7 | type
8 | // Define Control type to identify on update
9 | IFXComponent = interface
10 | ['{A3FFB2B1-05D3-4758-80A6-8BC97C0D9392}']
11 | procedure UpdateTheme(const UpdateChidlren: Boolean);
12 | end;
13 | IFXControl = interface
14 | ['{5098EF5C-0451-490D-A0B2-24C414F21A24}']
15 | function IsContainer: Boolean;
16 | function Background: TColor;
17 |
18 | procedure Redraw;
19 | end;
20 |
21 | implementation
22 |
23 | end.
24 |
--------------------------------------------------------------------------------
/Source/CFX.Math.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Math;
2 |
3 | interface
4 |
5 | uses
6 | SysUtils;
7 |
8 | function PercOf(number: integer; percentage: integer): integer;
9 | function PercOfR(number: Real; percentage: integer): real;
10 |
11 | function EqualApprox(number1, number2: integer; span: real = 1): boolean; overload;
12 | function EqualApprox(number1, number2: real; span: real = 1): boolean; overload;
13 |
14 | function IntToStrIncludePrefixZeros(Value: integer; NumbersCount: integer): string;
15 |
16 | implementation
17 |
18 | function PercOf(number: integer; percentage: integer): integer;
19 | begin
20 | Result := trunc(percentage / 100 * number);
21 | end;
22 |
23 | function PercOfR(number: Real; percentage: integer): real;
24 | begin
25 | Result := percentage / 100 * number;
26 | end;
27 |
28 | function EqualApprox(number1, number2: integer; span: real): boolean;
29 | begin
30 | if (number1 <= number2 + span) and (number1 >= number2 - span) then
31 | Result := true
32 | else
33 | Result := false;
34 | end;
35 |
36 | function EqualApprox(number1, number2: real; span: real): boolean;
37 | begin
38 | if (number1 <= number2 + span) and (number1 >= number2 - span) then
39 | Result := true
40 | else
41 | Result := false;
42 | end;
43 |
44 | function IntToStrIncludePrefixZeros(Value: integer; NumbersCount: integer): string;
45 | var
46 | ResLength: integer;
47 | I: Integer;
48 | begin
49 | Result := IntToStr( abs(Value) );
50 |
51 | ResLength := Length( Result );
52 | if ResLength < NumbersCount then
53 | begin
54 | for I := 1 to NumbersCount - ResLength do
55 | Result := '0' + Result;
56 |
57 | if Value < 0 then
58 | Result := '-' + Result;
59 | end;
60 | end;
61 |
62 | end.
63 |
--------------------------------------------------------------------------------
/Source/CFX.Messages.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Messages;
2 |
3 | interface
4 | uses
5 | Winapi.Windows, System.Classes, System.Types, Winapi.Messages;
6 |
7 | const
8 | // Separetr from User Messages
9 | CFX_MESSAGE_OFFSET = $200; // these are sent in controls AND sub-controls
10 | WM_CFX_MESSAGES = WM_USER + CFX_MESSAGE_OFFSET;
11 | WM_CFX_MESSAGES_END = WM_CFX_MESSAGES+500;
12 |
13 | WM_WINDOW_MOVE = WM_CFX_MESSAGES + 1;
14 | WM_WINDOW_RESIZE = WM_CFX_MESSAGES + 2;
15 | WM_WINDOW_DEF = WM_CFX_MESSAGES + 3;
16 |
17 | implementation
18 |
19 | end.
20 |
--------------------------------------------------------------------------------
/Source/CFX.PaintBox.pas:
--------------------------------------------------------------------------------
1 | unit CFX.PaintBox;
2 |
3 | interface
4 |
5 | uses
6 | SysUtils,
7 | Classes,
8 | Types,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | CFX.VarHelpers,
13 | CFX.ThemeManager,
14 | CFX.Colors,
15 | CFX.Constants,
16 | CFX.Controls,
17 | CFX.Linker;
18 |
19 | type
20 | FXPaintBox = class(FXWindowsControl)
21 | private
22 | FDarkTintOpacity,
23 | FWhiteTintOpacity: integer;
24 |
25 | FCustomColors: FXColorSets;
26 | FDrawColors: FXColorSet;
27 |
28 | FEnableTinting: boolean;
29 |
30 | FOnDraw: TNotifyEvent;
31 |
32 | procedure SetTinting(const Value: boolean);
33 | procedure SetDarkTint(const Value: integer);
34 | procedure SetWhiteTint(const Value: integer);
35 | procedure SetCustomColor(const Value: FXColorSets);
36 |
37 | protected
38 | procedure PaintBuffer; override;
39 |
40 | // Internal
41 | procedure UpdateColors; override;
42 |
43 | published
44 | property Align;
45 | property Anchors;
46 | property AutoSize;
47 | property Constraints;
48 | property DragCursor;
49 | property DragKind;
50 | property DragMode;
51 | property Enabled;
52 | property ParentShowHint;
53 | property PopupMenu;
54 | property ShowHint;
55 | property Touch;
56 | property Visible;
57 | property OnClick;
58 |
59 | property OnDraw: TNotifyEvent read FOnDraw write FOnDraw;
60 |
61 | property EnableTinting: boolean read FEnableTinting write SetTinting default true;
62 | property DarkTintOpacity: integer read FDarkTintOpacity write SetDarkTint default 75;
63 | property WhiteTintOpacity: integer read FWhiteTintOpacity write SetWhiteTint default 200;
64 |
65 | property CustomColors: FXColorSets read FCustomColors write SetCustomColor;
66 | property OnContextPopup;
67 | property OnDblClick;
68 | property OnDragDrop;
69 | property OnDragOver;
70 | property OnEndDock;
71 | property OnEndDrag;
72 | property OnGesture;
73 | property OnMouseActivate;
74 | property OnMouseDown;
75 | property OnMouseEnter;
76 | property OnMouseLeave;
77 | property OnMouseUp;
78 | property OnStartDock;
79 | property OnStartDrag;
80 | property OnMouseMove;
81 |
82 | public
83 | constructor Create(AOwner: TComponent); override;
84 | destructor Destroy; override;
85 |
86 | procedure Inflate(up,right,down,lft: integer);
87 |
88 | // Interface
89 | function Background: TColor; override;
90 | end;
91 |
92 | implementation
93 |
94 | { FXPaintBox }
95 |
96 | function FXPaintBox.Background: TColor;
97 | begin
98 | Result := FDrawColors.Background;
99 | end;
100 |
101 | constructor FXPaintBox.Create(AOwner: TComponent);
102 | begin
103 | inherited;
104 | FDrawColors := FXColorSet.Create;
105 | FCustomColors := FXColorSets.Create(false);
106 | with FCustomColors do
107 | begin
108 | DarkBackground := clBlack;
109 | LightBackground := clWhite;
110 | Accent := ThemeManager.AccentColor;
111 | end;
112 |
113 | ControlStyle := ControlStyle + [csReplicatable, csPannable];
114 |
115 | // Size
116 | Width := 150;
117 | Height := 200;
118 |
119 | // Tintin
120 | FEnableTinting := false;
121 |
122 | FWhiteTintOpacity := LIGHT_TINT_OPACITY;
123 | FDarkTintOpacity := DARK_TINT_OPACITY;
124 |
125 | // Theme
126 | UpdateColors;
127 | end;
128 |
129 | procedure FXPaintBox.UpdateColors;
130 | begin
131 | // Access theme manager
132 | FDrawColors.Assign( ThemeManager.SystemColor );
133 | if FCustomColors.Enabled then
134 | // Custom Colors
135 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
136 | end;
137 |
138 | destructor FXPaintBox.Destroy;
139 | begin
140 | FreeAndNil(FCustomColors);
141 | FreeAndNil(FDrawColors);
142 | inherited;
143 | end;
144 |
145 | procedure FXPaintBox.Inflate(up, right, down, lft: integer);
146 | begin
147 | // UP
148 | Top := Top - Up;
149 | Height := Height + Up;
150 | // RIGHT
151 | Width := Width + right;
152 | // DOWN
153 | Height := Height + down;
154 | // LEFT
155 | Left := Left - lft;
156 | Width := Width + lft;
157 | end;
158 |
159 | procedure FXPaintBox.PaintBuffer;
160 | var
161 | //Pict: TBitMap;
162 | DrawRect{, ImageRect}: Trect;
163 | begin
164 | // Background
165 | Color := FDrawColors.BackGround;
166 | PaintBackground;
167 |
168 | // Draw
169 | if csDesigning in ComponentState then
170 | with Buffer do
171 | begin
172 | Pen.Color := clAqua;
173 | Pen.Style := psDash;
174 | Brush.Style := bsSolid;
175 | Rectangle(ClientRect);
176 |
177 | Exit;
178 | end;
179 |
180 | // Default color
181 | with Buffer do
182 | begin
183 | Brush.Color := FDrawColors.BackGround;
184 | FillRect(ClipRect);
185 | end;
186 |
187 | // On Paint
188 | if Assigned(OnDraw) then
189 | OnDraw(Self);
190 |
191 | // Tint
192 | with Buffer do
193 | if EnableTinting then
194 | begin
195 | DrawRect := ClipRect;
196 | DrawRect.Inflate(1, 1);
197 |
198 | if ThemeManager.DarkTheme then
199 | GDITint( DrawRect, FDrawColors.BackGround, FDarkTintOpacity )
200 | else
201 | GDITint( DrawRect, FDrawColors.BackGround, FWhiteTintOpacity );
202 | end;
203 |
204 | inherited;
205 | end;
206 |
207 | procedure FXPaintBox.SetCustomColor(const Value: FXColorSets);
208 | begin
209 | FCustomColors := Value;
210 |
211 | UpdateTheme(false);
212 | end;
213 |
214 | procedure FXPaintBox.SetDarkTint(const Value: integer);
215 | begin
216 | FDarkTintOpacity := Value;
217 |
218 | Invalidate;
219 | end;
220 |
221 | procedure FXPaintBox.SetTinting(const Value: boolean);
222 | begin
223 | FEnableTinting := Value;
224 |
225 | Invalidate;
226 | end;
227 |
228 | procedure FXPaintBox.SetWhiteTint(const Value: integer);
229 | begin
230 | FWhiteTintOpacity := Value;
231 |
232 | Invalidate;
233 | end;
234 |
235 | end.
236 |
--------------------------------------------------------------------------------
/Source/CFX.PopupConnector.pas:
--------------------------------------------------------------------------------
1 | unit CFX.PopupConnector;
2 |
3 | interface
4 |
5 | uses
6 | Vcl.Menus, CFX.PopupMenu;
7 |
8 | type
9 | FXPopupConnector = class(TPopupMenu)
10 | private
11 | FPopupMenu: FXPopupMenu;
12 |
13 | published
14 | property PopupMenu: FXPopupMenu read FPopupMenu write FPopupMenu;
15 |
16 | public
17 | procedure Popup(X, Y: Integer); override;
18 |
19 | end;
20 |
21 | implementation
22 |
23 | { FXPopupConnector }
24 |
25 | procedure FXPopupConnector.Popup(X, Y: Integer);
26 | begin
27 | //inherited;
28 | if Assigned(PopupMenu) then
29 | PopupMenu.Popup(X, Y);
30 | end;
31 |
32 | end.
33 |
--------------------------------------------------------------------------------
/Source/CFX.PropertyEditors.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Codrax/Codrut-Fluent-Design-System/3ec621e0972527fca3f780b9d83f5325e3ce08bd/Source/CFX.PropertyEditors.pas
--------------------------------------------------------------------------------
/Source/CFX.QuickDialogs.pas:
--------------------------------------------------------------------------------
1 | unit CFX.QuickDialogs;
2 |
3 | interface
4 | uses
5 | Winapi.Windows, SysUtils, CFX.Dialogs, Vcl.Forms, System.UITypes;
6 |
7 | // Dialogs
8 | procedure OpenMessage(AText: string); overload;
9 | procedure OpenMessage(ATitle, AText: string); overload;
10 | function OpenDialog(AText: string; AButtons: TMsgDlgButtons): TModalResult; overload;
11 | function OpenDialog(ATitle, AText: string; AButtons: TMsgDlgButtons): TModalResult; overload;
12 | function OpenDialog(AText: string; AKind: FXDialogKind; AButtons: TMsgDlgButtons): TModalResult; overload;
13 | function OpenDialog(ATitle, AText: string; AKind: FXDialogKind; AButtons: TMsgDlgButtons): TModalResult; overload;
14 | function OpenDialog(ATitle, AText: string; AButtons: TArray): integer; overload;
15 | function OpenDialog(ATitle, AText: string; AKind: FXDialogKind; AButtons: TArray): integer; overload;
16 | function OpenInput(ATitle, AText: string; var AValue: string): boolean; overload;
17 | function OpenInput(ATitle, AText: string; var AValue: integer; DefaultValue: integer=0): boolean; overload;
18 |
19 | implementation
20 |
21 | function GetActiveForm: TForm;
22 | var
23 | ActiveHandle: HWND;
24 | I: Integer;
25 | begin
26 | Result := nil;
27 | ActiveHandle := Application.ActiveFormHandle;
28 |
29 | for I := 0 to Application.ComponentCount-1 do
30 | if Application.Components[I] is TForm then
31 | with TForm(Application.Components[I]) do
32 | if (Handle = ActiveHandle) and Visible then
33 | Exit( TForm(Application.Components[I]) );
34 | end;
35 |
36 | procedure OpenMessage(AText: string);
37 | begin
38 | OpenMessage('Message', AText);
39 | end;
40 |
41 | procedure OpenMessage(ATitle, AText: string);
42 | begin
43 | with FXMessageBox.Create do
44 | try
45 | Parent := GetActiveForm;
46 |
47 | Title := ATitle;
48 | Text := AText;
49 |
50 | Execute;
51 | finally
52 | Free;
53 | end;
54 | end;
55 |
56 | function OpenDialog(AText: string; AButtons: TMsgDlgButtons): TModalResult; overload;
57 | begin
58 | Result := OpenDialog('Dialog', AText, AButtons);
59 | end;
60 |
61 | function OpenDialog(ATitle, AText: string; AButtons: TMsgDlgButtons): TModalResult;
62 | begin
63 | with FXModalDialog.Create do
64 | try
65 | Parent := GetActiveForm;
66 |
67 | Title := ATitle;
68 | Text := AText;
69 |
70 | Buttons := AButtons;
71 |
72 | Result := Execute;
73 | finally
74 | Free;
75 | end;
76 | end;
77 |
78 | function OpenDialog(AText: string; AKind: FXDialogKind; AButtons: TMsgDlgButtons): TModalResult;
79 | var
80 | ATitle: string;
81 | begin
82 | ATitle := '';
83 | case AKind of
84 | FXDialogKind.Information: ATitle := 'Information';
85 | FXDialogKind.Error: ATitle := 'Error';
86 | FXDialogKind.Question: ATitle := 'Confirmation';
87 | FXDialogKind.Success: ATitle := 'Sucess';
88 | FXDialogKind.Warning: ATitle := 'Warning';
89 | FXDialogKind.Star: ATitle := 'Attention';
90 | end;
91 | Result := OpenDialog(ATitle, AText, AKind, AButtons);
92 | end;
93 |
94 | function OpenDialog(ATitle, AText: string; AKind: FXDialogKind; AButtons: TMsgDlgButtons): TModalResult;
95 | begin
96 | with FXModalIconDialog.Create do
97 | try
98 | Parent := GetActiveForm;
99 |
100 | Title := ATitle;
101 | Text := AText;
102 | Kind := AKind;
103 |
104 | Buttons := AButtons;
105 |
106 | Result := Execute;
107 | finally
108 | Free;
109 | end;
110 | end;
111 |
112 | function OpenDialog(ATitle, AText: string; AButtons: TArray): integer; overload;
113 | begin
114 | Result := OpenDialog(ATitle, AText, FXDialogKind.None, AButtons);
115 | end;
116 |
117 | function OpenDialog(ATitle, AText: string; AKind: FXDialogKind; AButtons: TArray): integer; overload;
118 | begin
119 | with FXDialog.Create do
120 | try
121 | Parent := GetActiveForm;
122 |
123 | Title := ATitle;
124 | Text := AText;
125 |
126 | ButtonDynamicSizing := true;
127 |
128 | for var I := 0 to High(AButtons) do
129 | AddButton(AButtons[I], '');
130 |
131 | Result := Execute;
132 | finally
133 | Free;
134 | end;
135 | end;
136 |
137 | function OpenInput(ATitle, AText: string; var AValue: string): boolean;
138 | begin
139 | with FXInputBox.Create do
140 | try
141 | Parent := GetActiveForm;
142 |
143 | Title := ATitle;
144 | Text := AText;
145 |
146 | Value := AValue;
147 |
148 | // Run
149 | Result := Execute;
150 | if Result then
151 | AValue := Value;
152 | finally
153 | Free;
154 | end;
155 | end;
156 |
157 | function OpenInput(ATitle, AText: string; var AValue: integer; DefaultValue: integer): boolean;
158 | begin
159 | with FXInputBox.Create do
160 | try
161 | Parent := GetActiveForm;
162 |
163 | NumbersOnly := true;
164 |
165 | Title := ATitle;
166 | Text := AText;
167 |
168 | Value := AValue.ToString;
169 |
170 | // Run
171 | Result := Execute;
172 | if Result then begin
173 | if Value = '' then
174 | AValue := DefaultValue
175 | else
176 | AValue := Value.ToInteger;
177 | end;
178 | finally
179 | Free;
180 | end;
181 | end;
182 |
183 | end.
184 |
--------------------------------------------------------------------------------
/Source/CFX.RatingControl.pas:
--------------------------------------------------------------------------------
1 | unit CFX.RatingControl;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Messages,
8 | Windows,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | Types,
13 | CFX.Colors,
14 | CFX.ThemeManager,
15 | CFX.Graphics,
16 | CFX.Constants,
17 | SysUtils,
18 | CFX.Classes,
19 | CFX.Types,
20 | CFX.VarHelpers,
21 | CFX.Linker,
22 | CFX.Controls;
23 |
24 | type
25 | FXRatingControl = class(FXWindowsControl)
26 | private
27 | var DrawRect: TRect;
28 | FDrawColors: FXCompleteColorSet;
29 | FCustomColors: FXColorSets;
30 |
31 | // Getters
32 |
33 | // Setters
34 |
35 | protected
36 | procedure PaintBuffer; override;
37 |
38 | // Internal
39 | procedure UpdateColors; override;
40 | procedure UpdateRects; override;
41 |
42 | // Scaler
43 | procedure ScaleChanged(Scaler: single); override;
44 |
45 | // State
46 | procedure InteractionStateChanged(AState: FXControlState); override;
47 |
48 | published
49 | // Custom Colors
50 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
51 |
52 | // Props
53 |
54 | // Default props
55 | property Align;
56 | property Transparent;
57 | property Opacity;
58 | property Constraints;
59 | property Anchors;
60 | property Hint;
61 | property ShowHint;
62 | property TabStop;
63 | property TabOrder;
64 | property FocusFlags;
65 | property DragKind;
66 | property DragCursor;
67 | property DragMode;
68 | property OnDragDrop;
69 | property OnDragOver;
70 | property OnEndDrag;
71 | property OnStartDrag;
72 | property OnEnter;
73 | property OnExit;
74 | property OnClick;
75 | property OnKeyDown;
76 | property OnKeyUp;
77 | property OnKeyPress;
78 | property OnMouseUp;
79 | property OnMouseDown;
80 | property OnMouseEnter;
81 | property OnMouseLeave;
82 | property OnMouseMove;
83 |
84 | public
85 | constructor Create(aOwner: TComponent); override;
86 | destructor Destroy; override;
87 |
88 | // Interface
89 | function Background: TColor; override;
90 | end;
91 |
92 | implementation
93 |
94 | function FXRatingControl.Background: TColor;
95 | begin
96 | Result := FDrawColors.BackGround;
97 | end;
98 |
99 | constructor FXRatingControl.Create(aOwner: TComponent);
100 | begin
101 | inherited;
102 | // Custom Color
103 | FCustomColors := FXColorSets.Create(Self);
104 |
105 | FDrawColors := FXCompleteColorSet.Create;
106 |
107 | // Sizing
108 | Height := 40;
109 | Width := 200;
110 | end;
111 |
112 | destructor FXRatingControl.Destroy;
113 | begin
114 | FreeAndNil( FCustomColors );
115 | FreeAndNil( FDrawColors );
116 | inherited;
117 | end;
118 |
119 | procedure FXRatingControl.InteractionStateChanged(AState: FXControlState);
120 | begin
121 | inherited;
122 | Redraw;
123 | end;
124 |
125 | procedure FXRatingControl.PaintBuffer;
126 | begin
127 | // Background
128 | Color := FDrawColors.BackGround;
129 | PaintBackground;
130 |
131 | // Draw
132 |
133 | // Inherit
134 | inherited;
135 | end;
136 |
137 | procedure FXRatingControl.UpdateColors;
138 | begin
139 | // Access theme manager
140 | FDrawColors.Assign( ThemeManager.SystemColor );
141 | if not Enabled then begin
142 | FDrawColors.Foreground := $808080;
143 | end
144 | else
145 | if FCustomColors.Enabled then
146 | // Custom Colors
147 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
148 | end;
149 |
150 | procedure FXRatingControl.UpdateRects;
151 | begin
152 | // Rect
153 | DrawRect := GetClientRect;
154 | end;
155 |
156 | procedure FXRatingControl.ScaleChanged(Scaler: single);
157 | begin
158 | inherited;
159 | // update scale
160 | end;
161 |
162 | end.
163 |
--------------------------------------------------------------------------------
/Source/CFX.RegisterClass.pas:
--------------------------------------------------------------------------------
1 | unit CFX.RegisterClass;
2 |
3 | interface
4 | uses Classes, CFX.Classes, CFX.Constants, CFX.Controls,
5 | CFX.Button, CFX.ButtonDesign, CFX.Checkbox, CFX.Panels,
6 | CFX.StandardIcons, CFX.Slider, CFX.BlurMaterial, CFX.PopupMenu,
7 | CFX.ImageList, CFX.TextBox, CFX.RadioButton, CFX.Scrollbar,
8 | CFX.ScrollBox, CFX.Selector, CFX.Edit, CFX.PopupConnector,
9 | CFX.IconView, CFX.ScrollText, CFX.Progress, CFX.RatingControl,
10 | CFX.Effects, CFX.AppManager, CFX.PaintBox, CFX.TabStrip, CFX.Lists,
11 | CFX.Animation.Component, CFX.Layouts, CFX.Shapes, CFX.TitlebarPanel;
12 |
13 | procedure Register;
14 |
15 | implementation
16 |
17 | procedure Register;
18 | begin
19 | // Visual Components
20 | RegisterComponents(REGISTER_CLASS_NAME,
21 | [
22 | FXMinimisePanel,
23 |
24 | FXButton,
25 | FXButtonDesign,
26 | FXPaintBox,
27 | FXCheckBox,
28 | FXStandardIcon,
29 | FXSlider,
30 | FXTabStrip,
31 | FXBlurMaterial,
32 |
33 | FXTextBox,
34 | FXValueTextBox,
35 | FXAnimatedTextBox,
36 | FXScrollText,
37 |
38 | FXRadioButton,
39 | FXScrollbar,
40 | FXSelector,
41 | FXEdit,
42 | FXNumberEdit,
43 | FXIconView,
44 | FXProgress,
45 | FXRatingControl
46 | ]
47 | );
48 |
49 | // Layouts
50 | RegisterComponents(REGISTER_CLASS_LAYOUTS,
51 | [
52 | FXLayout,
53 | FXScrollLayout,
54 |
55 | FXLinearDrawList,
56 | FXLinearStringsList,
57 | FXLinearControlList
58 | ]
59 | );
60 |
61 | // Shapes
62 | RegisterComponents(REGISTER_CLASS_SHAPES,
63 | [
64 | FXShapeSquare,
65 | FXShapeRoundedSquare,
66 | FXShapeCircle,
67 | FXShapeTriangle,
68 | FXShapeTriangleCorner
69 | ]
70 | );
71 |
72 | // Effects
73 | RegisterComponents(REGISTER_CLASS_EFFECTS_NAME,
74 | [
75 | FXBlurEffect,
76 | FXColorEffect,
77 | FXZoomEffect,
78 | FXGrayscaleEffect,
79 | FXInvertEffect,
80 | FXDeepFryEffect,
81 | FXGlowEffect
82 | ]
83 | );
84 |
85 | // Animations
86 | RegisterComponents(REGISTER_CLASS_ANIM_NAME,
87 | [
88 | FXIntAnim,
89 | FXFloatAnim
90 | ]
91 | );
92 |
93 | // Non-Visual Components
94 | RegisterComponents(REGISTER_CLASS_NAME,
95 | [
96 | FXPopupMenu,
97 | FXImageList
98 | ]
99 | );
100 |
101 | // Utils
102 | RegisterComponents(REGISTER_CLASS_UTILS_NAME,
103 | [
104 | FXPopupConnector, FXAppManager, FXAppManagerFormAssist, FXTitleBarPanel
105 | ]
106 | );
107 |
108 | // Legacy
109 | RegisterComponents(REGISTER_CLASS_LEGACY,
110 | [
111 | FXPanel,
112 | FXScrollBox
113 | ]
114 | );
115 | end;
116 |
117 | end.
118 |
--------------------------------------------------------------------------------
/Source/CFX.ScrollText.pas:
--------------------------------------------------------------------------------
1 | unit CFX.ScrollText;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Messages,
8 | Windows,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | Types,
13 | Math,
14 | CFX.Colors,
15 | CFX.ThemeManager,
16 | CFX.Graphics,
17 | CFX.Constants,
18 | SysUtils,
19 | CFX.Classes,
20 | CFX.Types,
21 | CFX.VarHelpers,
22 | CFX.Linker,
23 | CFX.Controls;
24 |
25 | type
26 | FXScrollText = class(FXWindowsControl)
27 | private
28 | var DrawRect, ImageRect, TextRect: TRect;
29 |
30 | FTextSpacing: Integer;
31 | FCustomColors: FXColorSets;
32 | FText: string;
33 | FDrawColors: FXCompleteColorSet;
34 | FVertLayout: FXLayout;
35 | FHorzLayout: FXLayout;
36 | FImage: FXIconSelect;
37 | FImageScale: real;
38 |
39 | FAnimationDelay: integer;
40 | FAnimationSpeed: integer;
41 |
42 | FSpacePercent: FXPercent;
43 |
44 | FOffset: integer;
45 | FOffsetEnd: integer;
46 | FAnimateValue: integer;
47 | FAnimateMax: integer;
48 | FAnimateSpace,
49 | FAnimateWidth: integer;
50 |
51 | FFadeRight,
52 | FFadeLeft: boolean;
53 | FFadeSize: integer;
54 |
55 | FAnimateTimer: TTimer;
56 |
57 | // Set properties
58 | procedure SetText(const Value: string);
59 | procedure SetTextSpacing(const Value: Integer);
60 | procedure SetHorzLayout(const Value: FXLayout);
61 | procedure SetVertLayout(const Value: FXLayout);
62 | procedure SetImage(const Value: FXIconSelect);
63 | procedure SetImageScale(const Value: real);
64 | procedure SetAnimationDelay(const Value: integer);
65 | procedure SetAnimationSpeed(const Value: integer);
66 | procedure SetFadeSize(const Value: integer);
67 |
68 | // Animation
69 | procedure ResetAnimation;
70 |
71 | procedure AnimationProgress(Sender: TObject);
72 |
73 | protected
74 | procedure PaintBuffer; override;
75 |
76 | // Internal
77 | procedure UpdateColors; override;
78 | procedure UpdateRects; override;
79 |
80 | // Size
81 | procedure Sized; override;
82 |
83 | // Scale
84 | procedure ScaleChanged(Scaler: single); override;
85 |
86 | // State
87 | procedure InteractionStateChanged(AState: FXControlState); override;
88 |
89 | published
90 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
91 | property TextSpacing: Integer read FTextSpacing write SetTextSpacing default CHECKBOX_TEXT_SPACE;
92 |
93 | property Text: string read FText write SetText;
94 | property SpacePercent: FXPercent read FSpacePercent write FSpacePercent;
95 | property FadeSize: integer read FFadeSize write SetFadeSize default SCROLL_TEXT_FADE_SIZE;
96 |
97 | property Image: FXIconSelect read FImage write SetImage;
98 | property ImageScale: real read FImageScale write SetImageScale;
99 |
100 | property AnimationDelay: integer read FAnimationDelay write SetAnimationDelay;
101 | property AnimationSpeed: integer read FAnimationSpeed write SetAnimationSpeed;
102 |
103 | property LayoutHorizontal: FXLayout read FHorzLayout write SetHorzLayout default FXLayout.Beginning;
104 | property LayoutVertical: FXLayout read FVertLayout write SetVertLayout default FXLayout.Center;
105 |
106 | property Align;
107 | property Font;
108 | property Transparent;
109 | property Opacity;
110 | property Constraints;
111 | property Anchors;
112 | property Hint;
113 | property ShowHint;
114 | property ParentShowHint;
115 | property TabStop;
116 | property TabOrder;
117 | property FocusFlags;
118 | property DragKind;
119 | property DragCursor;
120 | property DragMode;
121 | property OnDragDrop;
122 | property OnDragOver;
123 | property OnEndDrag;
124 | property OnStartDrag;
125 | property OnEnter;
126 | property OnExit;
127 | property OnClick;
128 | property OnKeyDown;
129 | property OnKeyUp;
130 | property OnKeyPress;
131 | property OnMouseUp;
132 | property OnMouseDown;
133 | property OnMouseEnter;
134 | property OnMouseLeave;
135 | property OnMouseMove;
136 |
137 | public
138 | constructor Create(aOwner: TComponent); override;
139 | destructor Destroy; override;
140 |
141 | // Interface
142 | function Background: TColor; override;
143 | end;
144 |
145 | implementation
146 |
147 | procedure FXScrollText.UpdateColors;
148 | begin
149 | // Access theme manager
150 | FDrawColors.Assign( ThemeManager.SystemColor );
151 | if FCustomColors.Enabled then
152 | // Custom Colors
153 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
154 | end;
155 |
156 | procedure FXScrollText.UpdateRects;
157 | var
158 | ASize, AWidth, SpaceLeft: integer;
159 | TextSpace: integer;
160 | begin
161 | // Rect
162 | DrawRect := GetClientRect;
163 |
164 | // Get Sizes
165 | with Buffer do
166 | begin
167 | Font.Assign(Self.Font);
168 |
169 | ASize := TextHeight(TEXT_SIZE_COMPARER);
170 | AWidth := TextWidth(FText);
171 | end;
172 |
173 | // Image
174 | if Image.Enabled then
175 | begin
176 | ASize := round(ASize * FImageScale);
177 | TextSpace := TextSpacing;
178 | end
179 | else
180 | begin
181 | ASize := 0;
182 | TextSpace := 0;
183 | end;
184 |
185 | // Rects
186 | ImageRect := Rect(DrawRect.Left, DrawRect.Top,
187 | DrawRect.Left+ASize + TextSpace * 2, DrawRect.Bottom);
188 |
189 | TextRect := Rect(ImageRect.Right + TextSpace, DrawRect.Top, DrawRect.Right, DrawRect.Bottom);
190 | TextRect.Width := ImageRect.Right + TextSpace + AWidth;
191 |
192 | // Image alignment
193 | case FVertLayout of
194 | FXLayout.Beginning: ImageRect.Height := ImageRect.Width;
195 | FXLayout.Ending: ImageRect.Top := ImageRect.Bottom-ImageRect.Width;
196 | end;
197 |
198 | // Offset
199 | SpaceLeft := DrawRect.Right - TextRect.Right;
200 | if SpaceLeft > 0 then
201 | case FHorzLayout of
202 | FXLayout.Center: begin
203 | TextRect.Offset(SpaceLeft div 2, 0);
204 | ImageRect.Offset(SpaceLeft div 2, 0);
205 | end;
206 | FXLayout.Ending: begin
207 | TextRect.Offset(SpaceLeft, 0);
208 | ImageRect.Offset(SpaceLeft, 0);
209 | end;
210 | end;
211 |
212 | // Animation Settings
213 | FAnimateWidth := AWidth;
214 | FAnimateSpace := FSpacePercent.OfNumberInt(DrawRect.Right);
215 | FAnimateMax := AWidth + FAnimateSpace;
216 |
217 | // Enable
218 | FAnimateTimer.Enabled := (SpaceLeft <= 0) and not IsDesigning;
219 |
220 | // Fades
221 | FFadeRight := FAnimateTimer.Enabled;
222 | end;
223 |
224 | procedure FXScrollText.ScaleChanged(Scaler: single);
225 | begin
226 | FTextSpacing := round(FTextSpacing * Scaler);
227 | inherited;
228 | end;
229 |
230 | procedure FXScrollText.SetAnimationDelay(const Value: integer);
231 | begin
232 | if FAnimationDelay = Value then
233 | Exit;
234 |
235 | FAnimationDelay := Value;
236 |
237 | if FAnimateValue < 0 then
238 | FAnimateValue := -Value;
239 | end;
240 |
241 | procedure FXScrollText.SetAnimationSpeed(const Value: integer);
242 | begin
243 | if FAnimationSpeed = Value then
244 | Exit;
245 |
246 | FAnimationSpeed := Value;
247 | end;
248 |
249 | procedure FXScrollText.SetFadeSize(const Value: integer);
250 | begin
251 | if FFadeSize = Value then
252 | Exit;
253 |
254 | FFadeSize := Value;
255 | StandardUpdateDraw;
256 | end;
257 |
258 | procedure FXScrollText.SetHorzLayout(const Value: FXLayout);
259 | begin
260 | if FHorzLayout = Value then
261 | Exit;
262 |
263 | FHorzLayout := Value;
264 | StandardUpdateLayout;
265 | end;
266 |
267 | procedure FXScrollText.SetImage(const Value: FXIconSelect);
268 | begin
269 | if FImage = Value then
270 | Exit;
271 |
272 | FImage := Value;
273 | StandardUpdateLayout;
274 | end;
275 |
276 | procedure FXScrollText.SetImageScale(const Value: real);
277 | begin
278 | if FImageScale = Value then
279 | Exit;
280 |
281 | FImageScale := Value;
282 | StandardUpdateLayout;
283 | end;
284 |
285 | procedure FXScrollText.SetText(const Value: string);
286 | begin
287 | if FText = Value then
288 | Exit;
289 |
290 | FText := Value;
291 |
292 | ResetAnimation;
293 | StandardUpdateLayout;
294 | end;
295 |
296 | procedure FXScrollText.SetTextSpacing(const Value: Integer);
297 | begin
298 | if Value = FTextSpacing then
299 | Exit;
300 |
301 | FTextSpacing := Value;
302 | ResetAnimation;
303 | StandardUpdateLayout;
304 | end;
305 |
306 | procedure FXScrollText.SetVertLayout(const Value: FXLayout);
307 | begin
308 | if FVertLayout = Value then
309 | Exit;
310 |
311 | FVertLayout := Value;
312 | StandardUpdateLayout;
313 | end;
314 |
315 | procedure FXScrollText.Sized;
316 | begin
317 | inherited;
318 | ResetAnimation;
319 | end;
320 |
321 | constructor FXScrollText.Create(aOwner: TComponent);
322 | begin
323 | inherited;
324 | TabStop := false;
325 |
326 | FAnimateTimer := TTimer.Create(nil);
327 | with FAnimateTimer do
328 | begin
329 | Enabled := false;
330 | Interval := 1;
331 | OnTimer := AnimationProgress;
332 | end;
333 |
334 | FTextSpacing := CHECKBOX_TEXT_SPACE;
335 | AutoFocusLine := true;
336 | BufferedComponent := true;
337 | FHorzLayout := FXLayout.Beginning;
338 | FVertLayout := FXLayout.Center;
339 | FSpacePercent := SCROLL_TEXT_SPACE;
340 | FAnimationDelay := SCROLL_TEXT_DELAY;
341 | FAnimationSpeed := SCROLL_TEXT_SPEED;
342 | FFadeSize := SCROLL_TEXT_FADE_SIZE;
343 |
344 | // Image
345 | FImage := FXIconSelect.Create(Self);
346 | FImageScale := NORMAL_IMAGE_SCALE;
347 |
348 | // Custom Color
349 | FCustomColors := FXColorSets.Create(Self);
350 |
351 | FDrawColors := FXCompleteColorSet.Create;
352 |
353 | FText := TEXT_LONG_GENERIC;
354 |
355 | // Sizing
356 | Height := 30;
357 | Width := 180;
358 | end;
359 |
360 | destructor FXScrollText.Destroy;
361 | begin
362 | FreeAndNil( FImage );
363 | FreeAndNil( FCustomColors );
364 | FreeAndNil( FDrawColors );
365 | FAnimateTimer.Enabled := false;
366 | FreeAndNil( FAnimateTimer );
367 | inherited;
368 | end;
369 |
370 | procedure FXScrollText.InteractionStateChanged(AState: FXControlState);
371 | begin
372 | // do not update
373 | end;
374 |
375 | procedure FXScrollText.AnimationProgress(Sender: TObject);
376 | begin
377 | // Draw
378 | if FAnimateValue > 0 then
379 | begin
380 | FOffset := -FAnimateValue;
381 | FOffsetEnd := -(FAnimateValue - (FAnimateSpace+FAnimateWidth));
382 |
383 | FFadeLeft := FOffsetEnd > FFadeSize;
384 |
385 | Redraw;
386 | end;
387 |
388 | // Done
389 | if FAnimateValue >= FAnimateMax then
390 | begin
391 | ResetAnimation;
392 | Redraw;
393 | end;
394 |
395 | // Increase
396 | Inc(FAnimateValue, AnimationSpeed);
397 | end;
398 |
399 | function FXScrollText.Background: TColor;
400 | begin
401 | Result := FDrawColors.Background;
402 | end;
403 |
404 | procedure FXScrollText.PaintBuffer;
405 | var
406 | DrawFlags: FXTextFlags;
407 | RectText, RectImage, DRect: TRect;
408 | Fade: integer;
409 |
410 | I: Integer;
411 | ARect: TRect;
412 | begin
413 | // Background
414 | Color := FDrawColors.BackGround;
415 | PaintBackground;
416 |
417 | for I := 1 to 2 do
418 | begin
419 | // Offset rects
420 | RectText := TextRect;
421 | RectImage := ImageRect;
422 |
423 | case I of
424 | 1: begin
425 | RectText.Offset(FOffset, 0);
426 | RectImage.Offset(FOffset, 0);
427 |
428 | if RectText.Right < 0 then
429 | Continue;
430 | end;
431 | 2: begin
432 | RectText.Offset(FOffsetEnd, 0);
433 | RectImage.Offset(FOffsetEnd, 0);
434 |
435 | if RectText.Right < 0 then
436 | Continue;
437 | end;
438 | end;
439 |
440 | // Draw
441 | with Buffer do
442 | begin
443 | // Draw text
444 | Brush.Style := bsClear;
445 | Font.Assign(Self.Font);
446 | Font.Color := FDrawColors.Foreground;
447 |
448 | DrawFlags := [];
449 |
450 | case FVertLayout of
451 | FXLayout.Beginning: DrawFlags := DrawFlags + [FXTextFlag.Top];
452 | FXLayout.Center: DrawFlags := DrawFlags + [FXTextFlag.VerticalCenter];
453 | FXLayout.Ending: DrawFlags := DrawFlags + [FXTextFlag.Bottom];
454 | end;
455 |
456 | DrawTextRect(Buffer, RectText, FText, DrawFlags);
457 |
458 | // Paint Image
459 | if Image.Enabled then
460 | Image.DrawIcon(Buffer, RectImage);
461 | end;
462 | end;
463 |
464 | // Draw Fade
465 | with Buffer do
466 | begin
467 | // This function will need a custom DrawRect, as the text
468 | // overflows outside the draw boundaries
469 | DRect := DrawRect;
470 | DRect.Left := 0;
471 | DRect.Right := Width;
472 |
473 | // Draw
474 | Fade := Min(FadeSize, FAnimateValue);
475 | if FFadeLeft then
476 | for I := 1 to Fade do
477 | begin
478 | ARect := Rect(DRect.Left+I-1, DRect.Top,
479 | DRect.Left+I, DRect.Bottom);
480 |
481 | CopyRectWithOpacity(Buffer, ARect, GetBackground, ARect, 255-trunc(I / Fade * 255));
482 | end;
483 |
484 | Fade := FadeSize;
485 | if FFadeRight then
486 | for I := 1 to Fade do
487 | begin
488 | ARect := Rect(DRect.Right-I, DRect.Top, DRect.Right-I+1, DRect.Bottom);
489 |
490 | CopyRectWithOpacity(Buffer, ARect, GetBackground, ARect, 255-trunc(I / Fade * 255));
491 | end;
492 | end;
493 |
494 | inherited;
495 | end;
496 |
497 | procedure FXScrollText.ResetAnimation;
498 | begin
499 | FOffset := 0;
500 | FOffsetEnd := 0;
501 | FFadeLeft := false;
502 | FAnimateValue := -AnimationDelay;
503 | end;
504 |
505 | end.
506 |
--------------------------------------------------------------------------------
/Source/CFX.Selector.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Selector;
2 |
3 | interface
4 | uses
5 | Classes,
6 | Messages,
7 | Windows,
8 | Vcl.Controls,
9 | Vcl.Graphics,
10 | Types,
11 | Math,
12 | CFX.Colors,
13 | CFX.ThemeManager,
14 | CFX.Graphics,
15 | CFX.Constants,
16 | SysUtils,
17 | CFX.Classes,
18 | CFX.VarHelpers,
19 | CFX.Types,
20 | CFX.Linker,
21 | CFX.Animation.Component,
22 | CFX.Controls;
23 |
24 | type
25 | FXSelector = class(FXWindowsControl)
26 | private
27 | var DrawRect, MainRect: TRect;
28 | ItemRects: TArray;
29 | ItemWidth: integer;
30 | FOnChange: TNotifyEvent;
31 | FOnChangeValue: TNotifyEvent;
32 | FCustomColors: FXCompleteColorSets;
33 | FItemAccentColors: FXSingleColorStateSet;
34 | FDrawColors: FXCompleteColorSet;
35 | FItems: TStringList;
36 | FHoverOver, FSelectedItem: integer;
37 | FDrawPosition: integer;
38 | FAnimation: boolean;
39 | FAnim: FXIntAnim;
40 |
41 | // Select
42 | procedure SelectNext;
43 | procedure SelectLast;
44 | function MakeDrawPositionRect: TRect;
45 |
46 | procedure SelectorItemsChange(Sender: TObject);
47 |
48 | // Animation
49 | procedure AnimationDoStep(Sender: TObject; Step, TotalSteps: integer);
50 |
51 | // Paint
52 | function GetRoundness(OfItems: boolean): integer; // OfItemss -> in contentrect, else clientrect
53 | procedure AnimateToPosition;
54 |
55 | // Setters
56 | procedure SetItems(const Value: TStringList);
57 | procedure SetSelectedItem(const Value: integer);
58 |
59 | protected
60 | procedure PaintBuffer; override;
61 |
62 | // Internal
63 | procedure UpdateColors; override;
64 | procedure UpdateRects; override;
65 |
66 | // Scale
67 | procedure ScaleChanged(Scaler: single); override;
68 |
69 | // State
70 | procedure InteractionStateChanged(AState: FXControlState); override;
71 |
72 | // Focus
73 | procedure UpdateFocusRect; override;
74 |
75 | // Key Presses
76 | procedure KeyPress(var Key: Char); override;
77 | procedure HandleKeyDown(var CanHandle: boolean; Key: integer; ShiftState: TShiftState); override;
78 |
79 | // Inherited Mouse Detection
80 | procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
81 | procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
82 |
83 | published
84 | property CustomColors: FXCompleteColorSets read FCustomColors write FCustomColors stored true;
85 | property OnChange: TNotifyEvent read FOnChange write FOnChange;
86 | property OnChangeValue: TNotifyEvent read FOnChangeValue write FOnChangeValue;
87 |
88 | property SelectedItem: integer read FSelectedItem write SetSelectedItem;
89 | property Items: TStringList read FItems write SetItems;
90 |
91 | property Animation: boolean read FAnimation write FAnimation default true;
92 |
93 | property Align;
94 | property Font;
95 | property Transparent;
96 | property Opacity;
97 | property PaddingFill;
98 | property Constraints;
99 | property Anchors;
100 | property Hint;
101 | property ShowHint;
102 | property ParentShowHint;
103 | property TabStop;
104 | property TabOrder;
105 | property FocusFlags;
106 | property DragKind;
107 | property DragCursor;
108 | property DragMode;
109 | property OnDragDrop;
110 | property OnDragOver;
111 | property OnEndDrag;
112 | property OnStartDrag;
113 | property OnEnter;
114 | property OnExit;
115 | property OnClick;
116 | property OnKeyDown;
117 | property OnKeyUp;
118 | property OnKeyPress;
119 | property OnMouseUp;
120 | property OnMouseDown;
121 | property OnMouseEnter;
122 | property OnMouseLeave;
123 | property OnMouseMove;
124 |
125 | public
126 | constructor Create(aOwner: TComponent); override;
127 | destructor Destroy; override;
128 |
129 | // Interface
130 | function Background: TColor; override;
131 | end;
132 |
133 | implementation
134 |
135 | procedure FXSelector.InteractionStateChanged(AState: FXControlState);
136 | begin
137 | inherited;
138 | case AState of
139 | FXControlState.None: FHoverOver := -1;
140 | end;
141 | Redraw;
142 | end;
143 |
144 | procedure FXSelector.KeyPress(var Key: Char);
145 | begin
146 | inherited;
147 | // Move with - or +
148 | case Key of
149 | '+', '=': SelectNext;
150 | '-': SelectLast;
151 | end;
152 | end;
153 |
154 | function FXSelector.MakeDrawPositionRect: TRect;
155 | begin
156 | Result := Rect(FDrawPosition, MainRect.Top, FDrawPosition + ItemWidth, MainRect.Bottom)
157 | end;
158 |
159 | procedure FXSelector.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
160 | Y: integer);
161 | begin
162 | inherited;
163 | if (FHoverOver <> SelectedItem) and (FHoverOver <> -1) then
164 | begin
165 | SelectedItem := FHoverOver;
166 |
167 | // Notify
168 | if Assigned(FOnChange) then
169 | FOnChange(Self);
170 |
171 | Redraw;
172 | end;
173 | end;
174 |
175 | procedure FXSelector.MouseMove(Shift: TShiftState; X, Y: Integer);
176 | var
177 | I: Integer;
178 | APoint: TPoint;
179 | AItem: integer;
180 | begin
181 | inherited;
182 | APoint := Point(X, Y);
183 |
184 | // Hover
185 | AItem := FHoverOver;
186 | FHoverOver := -1;
187 | for I := 0 to High(ItemRects) do
188 | if ItemRects[I].Contains(APoint) then
189 | FHoverOver := I;
190 |
191 | // Changed
192 | if AItem <> FHoverOver then
193 | Redraw;
194 |
195 | end;
196 |
197 | procedure FXSelector.UpdateColors;
198 | begin
199 | FDrawColors.Assign( ThemeManager.SystemColor );
200 | if not Enabled then
201 | begin
202 | FItemAccentColors := FXSingleColorStateSet.Create($808080,
203 | ChangeColorLight($808080, ACCENT_DIFFERENTIATE_CONST),
204 | ChangeColorLight($808080, -ACCENT_DIFFERENTIATE_CONST));
205 | end
206 | else
207 | begin
208 | // Access theme manager
209 | if FCustomColors.Enabled then
210 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme)
211 | else
212 | begin
213 | if ThemeManager.DarkTheme then
214 | FDrawColors.BackGroundInterior := ChangeColorLight(ThemeManager.SystemColor.BackGroundInterior, 20)
215 | else
216 | FDrawColors.BackGroundInterior := ChangeColorLight(ThemeManager.SystemColor.BackGroundInterior, -20);
217 | end;
218 |
219 | FItemAccentColors := FXSingleColorStateSet.Create(FDrawColors.Accent,
220 | ChangeColorLight(FDrawColors.Accent, ACCENT_DIFFERENTIATE_CONST),
221 | ChangeColorLight(FDrawColors.Accent, -ACCENT_DIFFERENTIATE_CONST));
222 | end;
223 | end;
224 |
225 | procedure FXSelector.UpdateFocusRect;
226 | begin
227 | FocusRect := MakeDrawPositionRect;
228 | end;
229 |
230 | procedure FXSelector.UpdateRects;
231 | var
232 | I: Integer;
233 | begin
234 | // Rect
235 | DrawRect := ClientRect;
236 | MainRect := ContentRect;
237 |
238 | // Width
239 | ItemWidth := trunc(MainRect.Width / FItems.Count);
240 |
241 | // Individual Rects
242 | SetLength(ItemRects, FItems.Count);
243 | for I := 0 to High(ItemRects) do
244 | begin
245 | with ItemRects[I] do
246 | begin
247 | Left := MainRect.Left + ItemWidth * I;
248 | Right := MainRect.Left + ItemWidth * (I+1);
249 |
250 | Top := MainRect.Top;
251 | Bottom := MainRect.Bottom;
252 | end;
253 | end;
254 |
255 | // Pos
256 | FDrawPosition := ItemRects[SelectedItem].Left;
257 | end;
258 |
259 | constructor FXSelector.Create(aOwner: TComponent);
260 | begin
261 | inherited;
262 | AutoFocusLine := true;
263 | BufferedComponent := true;
264 | FAnimation := true;
265 |
266 | // Items
267 | FItems := TStringList.Create;
268 |
269 | FItems.Add('Item1');
270 | FItems.Add('Item2');
271 | FItems.Add('Item3');
272 |
273 | FItems.OnChange := SelectorItemsChange;
274 |
275 | FSelectedItem := 0;
276 |
277 | // Anim
278 | FAnim := FXIntAnim.Create(Self);
279 | with FAnim do begin
280 | Duration := 0.4;
281 | Kind := FXAnimationKind.ReverseExpo;
282 |
283 | LatencyAdjustments := true;
284 | LatencyCanSkipSteps := true;
285 |
286 | OnStep := AnimationDoStep;
287 | end;
288 |
289 | // Custom Color
290 | FCustomColors := FXCompleteColorSets.Create(Self);
291 | FItemAccentColors := FXSingleColorStateSet.Create;
292 |
293 | FDrawColors := FXCompleteColorSet.Create;
294 |
295 | // Sizing
296 | Height := 30;
297 | Width := 250;
298 | end;
299 |
300 | destructor FXSelector.Destroy;
301 | begin
302 | FreeAndNil( FAnim );
303 | FreeAndNil( FCustomColors );
304 | FreeAndNil( FDrawColors );
305 | FreeAndNil( FItemAccentColors );
306 | FreeAndNil( FItems );
307 | inherited;
308 | end;
309 |
310 | function FXSelector.GetRoundness(OfItems: boolean): integer;
311 | begin
312 | if OfItems then
313 | Result := Min(ItemWidth, MainRect.Height)
314 | else
315 | Result := Min(ItemWidth, DrawRect.Height)
316 | end;
317 |
318 | procedure FXSelector.HandleKeyDown(var CanHandle: boolean; Key: integer;
319 | ShiftState: TShiftState);
320 | begin
321 | inherited;
322 | case Key of
323 | VK_LEFT: begin
324 | SelectLast;
325 | CanHandle := false;
326 | end;
327 |
328 | VK_RIGHT: begin
329 | SelectNext;
330 | CanHandle := false;
331 | end;
332 | end;
333 | end;
334 |
335 | procedure FXSelector.AnimateToPosition;
336 | begin
337 | FAnim.Stop;
338 |
339 | FAnim.StartValue := FDrawPosition;
340 | FAnim.EndValue := ItemRects[SelectedItem].Left;
341 |
342 | FAnim.Start;
343 | end;
344 |
345 | procedure FXSelector.AnimationDoStep(Sender: TObject; Step,
346 | TotalSteps: integer);
347 | begin
348 | FDrawPosition := FAnim.CurrentValue;
349 |
350 | StandardUpdateDraw;
351 | end;
352 |
353 | function FXSelector.Background: TColor;
354 | begin
355 | Result := FDrawColors.Background;
356 | end;
357 |
358 | procedure FXSelector.PaintBuffer;
359 | var
360 | I: integer;
361 | ARound: integer;
362 | DrawBackground: boolean;
363 | AColor: TColor;
364 | ARect: TRect;
365 | begin
366 | // Background
367 | Color := FDrawColors.BackGround;
368 | PaintBackground;
369 |
370 | // Draw
371 | with Buffer do
372 | begin
373 | // Main Rectangle
374 | GDIRoundRect(MakeRoundRect(DrawRect, GetRoundness(false)), GetRGB(FDrawColors.BackGroundInterior).MakeGDIBrush, nil);
375 |
376 | // Draw Backgrounds
377 | ARound := GetRoundness(true);
378 | for I := 0 to High(ItemRects) do
379 | begin
380 | DrawBackground := (FHoverOver = I);
381 |
382 | // Background Items
383 | if DrawBackground then
384 | begin
385 | ARect := ItemRects[I];
386 |
387 | AColor := ChangeColorLight(FDrawColors.backGroundInterior, 10);
388 |
389 | GDIRoundRect(MakeRoundRect(ARect, ARound), GetRGB(AColor).MakeGDIBrush, nil);
390 | end;
391 | end;
392 |
393 | // Draw foreground Item
394 | if FHoverOver = Selecteditem then
395 | AColor := FItemAccentColors.GetColor(InteractionState)
396 | else
397 | AColor := FItemAccentColors.None;
398 | ARect := MakeDrawPositionRect;
399 | GDIRoundRect(MakeRoundRect(ARect, ARound), GetRGB(AColor).MakeGDIBrush, nil);
400 |
401 | // Draw Texts
402 | for I := 0 to High(ItemRects) do
403 | begin
404 | // Text
405 | Brush.Style := bsClear;
406 | Font.Assign(Self.Font);
407 | Font.Color := FDrawColors.ForeGround;
408 |
409 | DrawTextRect(Buffer, ItemRects[I], FItems[I], [FXTextFlag.Center, FXTextFlag.VerticalCenter]);
410 | end;
411 | end;
412 |
413 | inherited;
414 | end;
415 |
416 | procedure FXSelector.ScaleChanged(Scaler: single);
417 | begin
418 | ItemWidth := round(ItemWidth * Scaler);
419 | inherited;
420 | end;
421 |
422 | procedure FXSelector.SelectLast;
423 | begin
424 | if SelectedItem > 0 then
425 | SelectedItem := SelectedItem - 1;
426 |
427 | // Notify
428 | if Assigned(FOnChange) then
429 | FOnChange(Self);
430 | end;
431 |
432 | procedure FXSelector.SelectNext;
433 | begin
434 | if SelectedItem < FItems.Count then
435 | SelectedItem := SelectedItem + 1;
436 |
437 | // Notify
438 | if Assigned(FOnChange) then
439 | FOnChange(Self);
440 | end;
441 |
442 | procedure FXSelector.SelectorItemsChange(Sender: TObject);
443 | begin
444 | UpdateRects;
445 | Redraw;
446 | end;
447 |
448 | procedure FXSelector.SetItems(const Value: TStringList);
449 | begin
450 | FItems.Assign(Value);
451 |
452 | UpdateRects;
453 | Redraw;
454 | end;
455 |
456 | procedure FXSelector.SetSelectedItem(const Value: integer);
457 | begin
458 | if (FSelectedItem = Value) or (Value < 0) or (Value >= FItems.Count) then
459 | Exit;
460 |
461 |
462 | FSelectedItem := Value;
463 |
464 | if Animation and not IsReading and not IsDesigning then
465 | AnimateToPosition
466 | else
467 | FDrawPosition := ItemRects[Value].Left;
468 |
469 | // Notify
470 | if not IsReading then
471 | if Assigned(FOnChangeValue) then
472 | FOnChangeValue(Self);
473 |
474 | // Draw
475 | StandardUpdateDraw;
476 | end;
477 |
478 | end.
479 |
--------------------------------------------------------------------------------
/Source/CFX.StandardIcons.pas:
--------------------------------------------------------------------------------
1 | unit CFX.StandardIcons;
2 |
3 | interface
4 |
5 | uses
6 | SysUtils,
7 | Classes,
8 | Vcl.Controls,
9 | Vcl.Graphics,
10 | Messaging,
11 | Types,
12 | Math,
13 | Vcl.Styles,
14 | Vcl.Themes,
15 | CFX.Types,
16 | CFX.Controls,
17 | CFX.Colors,
18 | CFX.Graphics,
19 | CFX.ThemeManager,
20 | CFX.Constants,
21 | CFX.Linker,
22 | CFX.VarHelpers,
23 | UITypes,
24 | Winapi.Windows;
25 |
26 | type
27 | FXStandardIcon = class(FXWindowsControl)
28 | private
29 | var DrawRect, MainRect: TRect;
30 | FIcon : FXStandardIconType;
31 | FPenWidth: integer;
32 | FDrawColors: FXColorSet;
33 | FCustomColors: FXColorSets;
34 | FProportional: boolean;
35 | FUseAccentColor: boolean;
36 |
37 | // Star drawing
38 | class procedure DrawPentacle(Canvas : TCanvas; Pent : TPent);
39 | class function MakePent(X, Y, L : integer) : TPent;
40 | class procedure MakeStar(Canvas : TCanvas; cX, cY, size : integer; Colour :TColor; bordersize: integer; bordercolor: TColor);
41 |
42 | // Setters
43 | procedure SetIcon(const Value: FXStandardIconType);
44 | procedure SetWid(const Value: integer);
45 | procedure SetProportional(const Value: boolean);
46 | procedure SetUseAccentColor(const Value: boolean);
47 |
48 | protected
49 | procedure PaintBuffer; override;
50 |
51 | // Update
52 | procedure UpdateColors; override;
53 | procedure UpdateRects; override;
54 |
55 | // Interaction
56 | procedure InteractionStateChanged(AState: FXControlState); override;
57 |
58 | published
59 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
60 |
61 | property Transparent;
62 | property PaddingFill;
63 | property OnMouseEnter;
64 | property OnMouseLeave;
65 | property OnMouseDown;
66 | property OnMouseUp;
67 | property OnMouseMove;
68 | property OnClick;
69 | property OnDblClick;
70 |
71 | property Color;
72 |
73 | property Align;
74 | property Constraints;
75 | property Anchors;
76 | property Hint;
77 | property ShowHint;
78 | property Cursor;
79 | property Visible;
80 | property Enabled;
81 |
82 | property Proportional: boolean read FProportional write SetProportional default true;
83 | property UseAccentColor: boolean read FUseAccentColor write SetUseAccentColor default false;
84 | property SelectedIcon : FXStandardIconType read FIcon write SetIcon;
85 | property PenWidth : integer read FPenWidth write SetWid;
86 |
87 | public
88 | constructor Create(AOwner : TComponent); override;
89 | destructor Destroy; override;
90 |
91 | // Override
92 | procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
93 |
94 | // Interface
95 | function Background: TColor; override;
96 | end;
97 |
98 | implementation
99 |
100 | { FXStandardIcon }
101 |
102 | function FXStandardIcon.Background: TColor;
103 | begin
104 | Result := FDrawColors.BackGround;
105 | end;
106 |
107 | constructor FXStandardIcon.Create(AOwner: TComponent);
108 | begin
109 | inherited;
110 | FProportional := true;
111 | FIcon := FXStandardIconType.Checkmark;
112 | FPenWidth := 10;
113 | FUseAccentColor := false;
114 |
115 | FCustomColors := FXColorSets.Create(Self);
116 | FDrawColors := FXColorSet.Create;
117 |
118 | // Sizing
119 | Width := 60;
120 | Height := 60;
121 | end;
122 |
123 | destructor FXStandardIcon.Destroy;
124 | begin
125 | FDrawColors.Free;
126 | FCustomColors.Free;
127 | inherited;
128 | end;
129 |
130 | class procedure FXStandardIcon.MakeStar(Canvas : TCanvas; cX, cY, size : integer; Colour :TColor; bordersize: integer; bordercolor: TColor);
131 | var
132 | Pent : TPent;
133 | begin
134 | Pent := MakePent(cX, cY, size);
135 | BeginPath(Canvas.Handle);
136 | DrawPentacle(Canvas, Pent);
137 | EndPath(Canvas.Handle);
138 | SetPolyFillMode(Canvas.Handle, WINDING);
139 | if bordersize <> 0 then
140 | Canvas.Brush.Color := bordercolor
141 | else
142 | Canvas.Brush.Color := Colour;
143 | FillPath(Canvas.Handle);
144 |
145 | if bordersize <> 0 then begin
146 | Pent := MakePent(cX, cY + trunc(bordersize / 1.2), size - bordersize);
147 | BeginPath(Canvas.Handle);
148 | DrawPentacle(Canvas, Pent);
149 | EndPath(Canvas.Handle);
150 | SetPolyFillMode(Canvas.Handle, WINDING);
151 | Canvas.Brush.Color := Colour;
152 | FillPath(Canvas.Handle);
153 | end;
154 | end;
155 |
156 | class function FXStandardIcon.MakePent(X, Y, L : integer) : TPent;
157 | var
158 | DX1, DY1, DX2, DY2 : integer;
159 | const
160 | Sin54 = 0.809;
161 | Cos54 = 0.588;
162 | Tan72 = 3.078;
163 | begin
164 | DX1 := trunc(L * Sin54);
165 | DY1 := trunc(L * Cos54);
166 | DX2 := L div 2;
167 | DY2 := trunc(L * Tan72 / 2);
168 | Result[0] := point(X, Y);
169 | Result[1] := point(X - DX1, Y + DY1);
170 | Result[2] := point(X - DX2, Y + DY2);
171 | Result[3] := point(X + DX2, Y + DY2);
172 | Result[4] := point(X + DX1, Y + DY1);
173 | end;
174 |
175 | class procedure FXStandardIcon.DrawPentacle(Canvas : TCanvas; Pent : TPent);
176 | begin
177 | with Canvas do begin
178 | MoveTo(Pent[0].X, Pent[0].Y);
179 | LineTo(Pent[2].X, Pent[2].Y);
180 | LineTo(Pent[4].X, Pent[4].Y);
181 | LineTo(Pent[1].X, Pent[1].Y);
182 | LineTo(Pent[3].X, Pent[3].Y);
183 | LineTo(Pent[0].X, Pent[0].Y);
184 | end;
185 | end;
186 |
187 | procedure FXStandardIcon.InteractionStateChanged(AState: FXControlState);
188 | begin
189 | // do not redraw
190 | end;
191 |
192 | procedure FXStandardIcon.PaintBuffer;
193 | procedure Move(X, Y: real); overload;
194 | begin
195 | Buffer.MoveTo( trunc(ContentRect.Left+X), trunc(ContentRect.Top+Y) );
196 | end;
197 | procedure Line(X, Y: real); overload;
198 | begin
199 | Buffer.LineTo( trunc(ContentRect.Left+X), trunc(ContentRect.Top+Y) );
200 | end;
201 | procedure Text(AStr: string);
202 | begin
203 | with Buffer do
204 | TextOut( ContentRect.Width div 2-TextWidth(AStr) div 2 ,
205 | ContentRect.Height div 2-TextHeight(AStr) div 2 ,
206 | AStr);
207 | end;
208 | var
209 | AWidth, AHeight: integer;
210 | begin
211 | // Background
212 | Color := FDrawColors.BackGround;
213 | PaintBackground;
214 |
215 | // Draw
216 | with Buffer do begin
217 | // Circle color
218 | if UseAccentColor then
219 | Brush.Color := FDrawColors.Accent
220 | else
221 | case FIcon of
222 | FXStandardIconType.Checkmark: Brush.Color := ICON_GREEN;
223 | FXStandardIconType.Error: Brush.Color := ICON_ROSE;
224 | FXStandardIconType.Question: Brush.Color := ICON_ICEBLUE;
225 | FXStandardIconType.Information: Brush.Color := ICON_ICEBLUE;
226 | FXStandardIconType.Warning: Brush.Color := ICON_YELLOW;
227 | FXStandardIconType.Star: Brush.Color := ICON_YELLOW;
228 | FXStandardIconType.None: Exit;
229 | end;
230 |
231 | // Circle
232 | Pen.Style := psClear;
233 | GDICircle(DrawRect, GetRGB(Brush.Color).MakeGDIBrush, nil);
234 |
235 | // Data
236 | AWidth := ContentRect.Width;
237 | AHeight := ContentRect.Height;
238 |
239 | // Brush
240 | Brush.Style := bsClear;
241 |
242 | // Pen
243 | Pen.Style := psSolid;
244 | Pen.Color := FDrawColors.ForeGround;
245 | Pen.Width := (FPenWidth * AWidth) div 100;
246 |
247 | // Font
248 | Font.Style := [fsBold];
249 | Font.Name := 'Calibri';
250 | Font.Color := FDrawColors.ForeGround;
251 | Font.Size := trunc(Min(AWidth, AHeight) / 1.8);
252 |
253 | // Icons
254 | case FIcon of
255 | // Checkmark
256 | FXStandardIconType.Checkmark: begin
257 | Move( AWidth / 4.9, ContentRect.Height / 1.9 );
258 | Line( AWidth / 2.5, ContentRect.Height / 1.4 );
259 | Line( AWidth / 1.35, ContentRect.Height / 3.6 );
260 | end;
261 |
262 | // Error
263 | FXStandardIconType.Error: begin
264 | Move( AWidth / 3, AHeight / 3 );
265 | Line( AWidth - AWidth / 3, AHeight - AHeight / 3 );
266 |
267 | Move( AWidth - AWidth / 3, AHeight / 3 );
268 | Line( AWidth / 3, AHeight - AHeight / 3 );
269 | end;
270 |
271 | // Info
272 | FXStandardIconType.Information: Text('i');
273 |
274 | // Question
275 | FXStandardIconType.Question: Text('?');
276 |
277 | // Warning
278 | FXStandardIconType.Warning: Text('!');
279 |
280 | // Star
281 | FXStandardIconType.Star:
282 | MakeStar(Buffer, AWidth div 2, round(AHeight / 7.5),
283 | trunc(AWidth / 2.25), font.Color, 0, $0001BAF8);
284 | end;
285 | end;
286 |
287 | inherited;
288 | end;
289 |
290 | procedure FXStandardIcon.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
291 | begin
292 | if FProportional then begin
293 | const ChangeW = AWidth <> Width;
294 | const ChangeH = AHeight <> Height;
295 |
296 | if ChangeW and ChangeH then
297 | AHeight := AWidth
298 | else
299 | if ChangeW then
300 | AHeight := AWidth
301 | else
302 | if ChangeH then
303 | AWidth := AHeight;
304 | end;
305 |
306 | inherited;
307 | end;
308 |
309 | procedure FXStandardIcon.SetIcon(const Value: FXStandardIconType);
310 | begin
311 | if FIcon = Value then
312 | Exit;
313 |
314 | FIcon := Value;
315 | StandardUpdateLayout;
316 | end;
317 |
318 | procedure FXStandardIcon.SetProportional(const Value: boolean);
319 | begin
320 | if FProportional = Value then
321 | Exit;
322 |
323 | if Value and (Height <> Width) then
324 | inherited Height := Width;
325 |
326 | FProportional := Value;
327 | UpdateRects;
328 | StandardUpdateLayout;
329 | end;
330 |
331 | procedure FXStandardIcon.SetUseAccentColor(const Value: boolean);
332 | begin
333 | if FUseAccentColor = Value then
334 | Exit;
335 |
336 | FUseAccentColor := Value;
337 | StandardUpdateLayout;
338 | end;
339 |
340 | procedure FXStandardIcon.SetWid(const Value: integer);
341 | begin
342 | if FPenWidth = Value then
343 | Exit;
344 |
345 | FPenWidth := Value;
346 | StandardUpdateLayout;
347 | end;
348 |
349 | procedure FXStandardIcon.UpdateColors;
350 | begin
351 | // Access theme mangager
352 | FDrawColors.Assign(ThemeManager.SystemColor);
353 | if FCustomColors.Enabled then
354 | // Custom colors
355 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme)
356 | end;
357 |
358 | procedure FXStandardIcon.UpdateRects;
359 | begin
360 | DrawRect := ClientRect;
361 | MainRect := ContentRect;
362 | end;
363 |
364 | end.
365 |
366 |
--------------------------------------------------------------------------------
/Source/CFX.TabStrip.pas:
--------------------------------------------------------------------------------
1 | unit CFX.TabStrip;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Messages,
8 | Windows,
9 | Vcl.Controls,
10 | Vcl.Graphics,
11 | Vcl.ExtCtrls,
12 | Types,
13 | CFX.Colors,
14 | CFX.ThemeManager,
15 | CFX.Graphics,
16 | CFX.Constants,
17 | SysUtils,
18 | CFX.Classes,
19 | CFX.Types,
20 | CFX.VarHelpers,
21 | CFX.Linker,
22 | CFX.Controls;
23 |
24 | type
25 | FXTabStrip = class(FXWindowsControl)
26 | private
27 | var DrawRect: TRect;
28 | FDrawColors: FXCompleteColorSet;
29 | FCustomColors: FXColorSets;
30 |
31 | // Getters
32 |
33 | // Setters
34 |
35 | protected
36 | procedure PaintBuffer; override;
37 |
38 | // Internal
39 | procedure UpdateColors; override;
40 | procedure UpdateRects; override;
41 |
42 | // Scaler
43 | procedure ScaleChanged(Scaler: single); override;
44 |
45 | // State
46 | procedure InteractionStateChanged(AState: FXControlState); override;
47 |
48 | published
49 | // Custom Colors
50 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
51 |
52 | // Props
53 |
54 | // Default props
55 | property Align;
56 | //property PaddingFill;
57 | property Constraints;
58 | property Anchors;
59 | property Hint;
60 | property ShowHint;
61 | property TabStop;
62 | property TabOrder;
63 | property FocusFlags;
64 | property DragKind;
65 | property DragCursor;
66 | property DragMode;
67 | property OnDragDrop;
68 | property OnDragOver;
69 | property OnEndDrag;
70 | property OnStartDrag;
71 | property OnEnter;
72 | property OnExit;
73 | property OnClick;
74 | property OnKeyDown;
75 | property OnKeyUp;
76 | property OnKeyPress;
77 | property OnMouseUp;
78 | property OnMouseDown;
79 | property OnMouseEnter;
80 | property OnMouseLeave;
81 |
82 | public
83 | constructor Create(aOwner: TComponent); override;
84 | destructor Destroy; override;
85 |
86 | // Interface
87 | function Background: TColor; override;
88 | end;
89 |
90 | implementation
91 |
92 | function FXTabStrip.Background: TColor;
93 | begin
94 | Result := FDrawColors.BackGround;
95 | end;
96 |
97 | constructor FXTabStrip.Create(aOwner: TComponent);
98 | begin
99 | inherited;
100 | // Custom Color
101 | FCustomColors := FXColorSets.Create(Self);
102 |
103 | FDrawColors := FXCompleteColorSet.Create;
104 |
105 | // Sizing
106 | Height := 40;
107 | Width := 300;
108 | end;
109 |
110 | destructor FXTabStrip.Destroy;
111 | begin
112 | FreeAndNil( FCustomColors );
113 | FreeAndNil( FDrawColors );
114 | inherited;
115 | end;
116 |
117 | procedure FXTabStrip.InteractionStateChanged(AState: FXControlState);
118 | begin
119 | inherited;
120 | end;
121 |
122 | procedure FXTabStrip.PaintBuffer;
123 | begin
124 | // Background
125 | Color := FDrawColors.BackGround;
126 | PaintBackground;
127 |
128 | // Draw
129 |
130 | // Inherit
131 | inherited;
132 | end;
133 |
134 | procedure FXTabStrip.UpdateColors;
135 | begin
136 | // Access theme manager
137 | FDrawColors.Assign( ThemeManager.SystemColor );
138 | if not Enabled then begin
139 | FDrawColors.Foreground := $808080;
140 | end
141 | else
142 | if FCustomColors.Enabled then
143 | // Custom Colors
144 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
145 | end;
146 |
147 | procedure FXTabStrip.UpdateRects;
148 | begin
149 | // Rect
150 | DrawRect := GetClientRect;
151 | end;
152 |
153 | procedure FXTabStrip.ScaleChanged(Scaler: single);
154 | begin
155 | inherited;
156 | // update scale
157 | end;
158 |
159 | end.
160 |
--------------------------------------------------------------------------------
/Source/CFX.Template.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Template;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Messages,
7 | Winapi.Windows,
8 | System.Classes,
9 | System.Types,
10 | System.SysUtils,
11 | Vcl.Controls,
12 | Vcl.Graphics,
13 | Vcl.ExtCtrls,
14 | CFX.Colors,
15 | CFX.ThemeManager,
16 | CFX.Graphics,
17 | CFX.Constants,
18 | CFX.Classes,
19 | CFX.Types,
20 | CFX.VarHelpers,
21 | CFX.Linker,
22 | CFX.Controls;
23 |
24 | type
25 | FXTemplate = class(FXWindowsControl)
26 | private
27 | var DrawRect: TRect;
28 | FDrawColors: FXCompleteColorSet;
29 | FCustomColors: FXColorSets;
30 |
31 | // Getters
32 |
33 | // Setters
34 |
35 | protected
36 | procedure PaintBuffer; override;
37 |
38 | // Internal
39 | procedure UpdateColors; override;
40 | procedure UpdateRects; override;
41 |
42 | // Scaler
43 | procedure ScaleChanged(Scaler: single); override;
44 |
45 | // State
46 | procedure InteractionStateChanged(AState: FXControlState); override;
47 |
48 | published
49 | // Custom Colors
50 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
51 |
52 | // Props
53 |
54 | // Default props
55 | property Align;
56 | //property PaddingFill;
57 | property Constraints;
58 | property Anchors;
59 | property Hint;
60 | property ShowHint;
61 | property TabStop;
62 | property TabOrder;
63 | property FocusFlags;
64 | property DragKind;
65 | property DragCursor;
66 | property DragMode;
67 | property OnDragDrop;
68 | property OnDragOver;
69 | property OnEndDrag;
70 | property OnStartDrag;
71 | property OnEnter;
72 | property OnExit;
73 | property OnClick;
74 | property OnKeyDown;
75 | property OnKeyUp;
76 | property OnKeyPress;
77 | property OnMouseUp;
78 | property OnMouseDown;
79 | property OnMouseEnter;
80 | property OnMouseLeave;
81 |
82 | public
83 | constructor Create(aOwner: TComponent); override;
84 | destructor Destroy; override;
85 |
86 | // Interface
87 | function IsContainer: Boolean; override;
88 | function Background: TColor; override;
89 | end;
90 |
91 | implementation
92 |
93 | function FXTemplate.Background: TColor;
94 | begin
95 | Result := FDrawColors.BackGround;
96 | end;
97 |
98 | constructor FXTemplate.Create(aOwner: TComponent);
99 | begin
100 | inherited;
101 | // Custom Color
102 | FCustomColors := FXColorSets.Create(Self);
103 | FDrawColors := FXCompleteColorSet.Create;
104 |
105 | // Sizing
106 | Height := 30;
107 | Width := 180;
108 | end;
109 |
110 | destructor FXTemplate.Destroy;
111 | begin
112 | FreeAndNil( FCustomColors );
113 | FreeAndNil( FDrawColors );
114 | inherited;
115 | end;
116 |
117 | procedure FXTemplate.InteractionStateChanged(AState: FXControlState);
118 | begin
119 | inherited;
120 | end;
121 |
122 | function FXTemplate.IsContainer: Boolean;
123 | begin
124 | Result := false;
125 | end;
126 |
127 | procedure FXTemplate.PaintBuffer;
128 | begin
129 | // Background
130 | Color := FDrawColors.BackGround;
131 | PaintBackground;
132 |
133 | // Draw
134 |
135 | // Inherit
136 | inherited;
137 | end;
138 |
139 | procedure FXTemplate.UpdateColors;
140 | begin
141 | // Access theme manager
142 | FDrawColors.Assign( ThemeManager.SystemColor );
143 | if not Enabled then begin
144 | FDrawColors.Foreground := $808080;
145 | end
146 | else
147 | if FCustomColors.Enabled then
148 | // Custom Colors
149 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
150 | end;
151 |
152 | procedure FXTemplate.UpdateRects;
153 | begin
154 | // Rect
155 | DrawRect := GetClientRect;
156 | end;
157 |
158 | procedure FXTemplate.ScaleChanged(Scaler: single);
159 | begin
160 | inherited;
161 | // update scale
162 | end;
163 |
164 | end.
165 |
--------------------------------------------------------------------------------
/Source/CFX.Test.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Test;
2 |
3 | interface
4 | uses
5 | Vcl.Controls, Classes, Types, CFX.Classes;
6 |
7 | type
8 | TTest = class(TControl)
9 | private
10 | FTest: FXSideValues;
11 |
12 | published
13 | property Test: FXSideValues read FTest write FTest;
14 |
15 | public
16 | constructor Create(AOwner: TComponent); override;
17 | destructor Destroy; override;
18 | end;
19 |
20 | procedure Register;
21 |
22 | implementation
23 |
24 | procedure Register;
25 | begin
26 | //RegisterComponents('Standard', [TTest]);
27 | end;
28 |
29 | { TTest }
30 |
31 | constructor TTest.Create(AOwner: TComponent);
32 | begin
33 | inherited;
34 | FTest := FXSideValues.Create(Self);
35 | end;
36 |
37 | destructor TTest.Destroy;
38 | begin
39 | FTest.Free;
40 | inherited;
41 | end;
42 |
43 | end.
44 |
--------------------------------------------------------------------------------
/Source/CFX.Threading.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Threading;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | Winapi.Messages,
8 | Winapi.Windows,
9 | Types,
10 | Math,
11 | SysUtils,
12 | Threading;
13 |
14 | type
15 | FXThreadHelper = class helper for TThread
16 | public
17 | function Running: boolean;
18 |
19 | procedure Halt;
20 | end;
21 |
22 | implementation
23 |
24 | { FXThreadHelper }
25 |
26 | procedure FXThreadHelper.Halt;
27 | begin
28 | TerminateThread(Handle, 0);
29 | end;
30 |
31 | function FXThreadHelper.Running: boolean;
32 | begin
33 | Result := Started and not Finished;
34 | end;
35 |
36 | end.
37 |
--------------------------------------------------------------------------------
/Source/CFX.TitlebarPanel.pas:
--------------------------------------------------------------------------------
1 | unit CFX.TitlebarPanel;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Messages,
7 | Winapi.Windows,
8 | System.Classes,
9 | System.Types,
10 | Vcl.Controls,
11 | Vcl.TitleBarCtrls,
12 | Vcl.Graphics,
13 | Vcl.ExtCtrls,
14 | CFX.Colors,
15 | Math,
16 | CFX.ThemeManager,
17 | CFX.Graphics,
18 | CFX.constants,
19 | SysUtils,
20 | CFX.Messages,
21 | CFX.Classes,
22 | CFX.Types,
23 | CFX.VarHelpers,
24 | CFX.Linker,
25 | CFX.Controls;
26 |
27 | type
28 | FXTitleBarPanel = class(TCustomTitleBarPanel, IFXComponent, IFXControl)
29 | private
30 | var DrawRect: TRect;
31 | FDrawColors: FXCompleteColorSet;
32 | FCustomColors: FXColorSets;
33 |
34 | // Internal
35 | procedure UpdateColors;
36 | procedure UpdateRects;
37 |
38 | protected
39 | // Handle messages
40 | procedure WndProc(var Message: TMessage); override;
41 |
42 | published
43 | // Custom Colors
44 | property CustomColors: FXColorSets read FCustomColors write FCustomColors stored true;
45 |
46 | // Default props
47 | property Margins;
48 | property OnPaint;
49 | property CustomButtons;
50 |
51 | public
52 | constructor Create(aOwner: TComponent); override;
53 | destructor Destroy; override;
54 |
55 | // Draw
56 | procedure Redraw;
57 |
58 | // Interface
59 | function IsContainer: Boolean;
60 | procedure UpdateTheme(const UpdateChildren: Boolean);
61 | function Background: TColor;
62 | end;
63 |
64 | implementation
65 |
66 |
67 | { FXTitleBarPanel }
68 |
69 | function FXTitleBarPanel.Background: TColor;
70 | begin
71 | Result := FDrawColors.BackGround;
72 | end;
73 |
74 | constructor FXTitleBarPanel.Create(aOwner: TComponent);
75 | begin
76 | inherited Create(aOwner);
77 | // Custom Color
78 | FCustomColors := FXColorSets.Create(Self);
79 | FDrawColors := FXCompleteColorSet.Create;
80 |
81 | // Update
82 | UpdateRects;
83 | UpdateColors;
84 | end;
85 |
86 | destructor FXTitleBarPanel.Destroy;
87 | begin
88 | FreeAndNil( FCustomColors );
89 | FreeAndNil( FDrawColors );
90 | inherited;
91 | end;
92 |
93 | function FXTitleBarPanel.IsContainer: Boolean;
94 | begin
95 | Result := true;
96 | end;
97 |
98 | procedure FXTitleBarPanel.Redraw;
99 | begin
100 | Invalidate;
101 | end;
102 |
103 | procedure FXTitleBarPanel.UpdateColors;
104 | begin
105 | // Access theme manager
106 | FDrawColors.Assign( ThemeManager.SystemColor );
107 | if not Enabled then begin
108 | FDrawColors.Foreground := $808080;
109 | end
110 | else
111 | if FCustomColors.Enabled then
112 | // Custom Colors
113 | FDrawColors.LoadFrom(FCustomColors, ThemeManager.DarkTheme);
114 | end;
115 |
116 | procedure FXTitleBarPanel.UpdateRects;
117 | begin
118 | // Rect
119 | DrawRect := Rect(0, 0, Width, Height);
120 | end;
121 |
122 | procedure FXTitleBarPanel.UpdateTheme(const UpdateChildren: Boolean);
123 | begin
124 | UpdateColors;
125 | UpdateRects;
126 | Invalidate;
127 |
128 | // Update children
129 | if UpdateChildren then
130 | for var I := 0 to ControlCount-1 do
131 | if Supports(Controls[I], IFXComponent) then
132 | (Controls[I] as IFXComponent).UpdateTheme(UpdateChildren);
133 | end;
134 |
135 | procedure FXTitleBarPanel.WndProc(var Message: TMessage);
136 | begin
137 | inherited;
138 | if InRange(Message.Msg, WM_CFX_MESSAGES, WM_CFX_MESSAGES_END) then
139 | Broadcast( Message );
140 | end;
141 |
142 | end.
143 |
--------------------------------------------------------------------------------
/Source/CFX.ToolTip.pas:
--------------------------------------------------------------------------------
1 | unit CFX.ToolTip;
2 |
3 | interface
4 | uses
5 | Classes, Types, Winapi.Windows, Winapi.Messages, Vcl.Controls, Vcl.Graphics, CFX.Constants,
6 | CFX.ThemeManager, CFX.Colors, CFX.Graphics;
7 |
8 | type
9 | FXCustomTooltip = class(THintWindow)
10 | const
11 | VERT_SPACE: Byte = 5;
12 | HORZ_SPACE: Byte = 7;
13 | private
14 | var ShowShadow: Boolean;
15 | var BorderThickness: Byte;
16 | var BorderColor, BackColor: TColor;
17 | protected
18 | procedure CreateParams(var Params: TCreateParams); override;
19 | procedure Paint; override;
20 | procedure NCPaint(DC: HDC); override;
21 | public
22 | constructor Create(aOwner: TComponent); override;
23 | function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; override;
24 | end;
25 |
26 | FXLightTooltip = class(FXCustomTooltip)
27 | public
28 | constructor Create(aOwner: TComponent); override;
29 |
30 | procedure ApplyColor;
31 | end;
32 |
33 | FXDarkTooltip = class(FXCustomTooltip)
34 | public
35 | constructor Create(aOwner: TComponent); override;
36 |
37 | procedure ApplyColor;
38 | end;
39 |
40 | implementation
41 |
42 | { FXLightTooltip }
43 | constructor FXLightTooltip.Create(aOwner: TComponent);
44 | begin
45 | inherited;
46 | ApplyColor;
47 | end;
48 |
49 | procedure FXLightTooltip.ApplyColor;
50 | begin
51 | inherited;
52 | BackColor := ThemeManager.FSystemToolTip.LightBackGround;
53 | BorderColor := ThemeManager.FSystemToolTip.LightBackGroundInterior;
54 | end;
55 |
56 | { FXDarkTooltip }
57 | constructor FXDarkTooltip.Create(aOwner: TComponent);
58 | begin
59 | inherited;
60 | ApplyColor;
61 | end;
62 |
63 | procedure FXDarkTooltip.ApplyColor;
64 | begin
65 | inherited;
66 | BackColor := ThemeManager.FSystemToolTip.DarkBackGround;
67 | BorderColor := ThemeManager.FSystemToolTip.DarkBackGroundInterior;
68 | end;
69 |
70 | { FXCustomTooltip }
71 | // MAIN CLASS
72 | constructor FXCustomTooltip.Create(aOwner: TComponent);
73 | begin
74 | inherited;
75 | ShowShadow := true;
76 | BorderThickness := TOOLTIP_WIDTH;
77 | Font.Name := TOOLTIP_FONT_NAME;
78 | Font.Size := TOOLTIP_FONT_SIZE;
79 | end;
80 |
81 | procedure FXCustomTooltip.CreateParams(var Params: TCreateParams);
82 | begin
83 | inherited;
84 | Params.Style := Params.Style and not WS_BORDER;
85 | if not ShowShadow then
86 | Params.WindowClass.style := Params.WindowClass.style and not CS_DROPSHADOW;
87 | end;
88 |
89 | // CUSTOM METHODS
90 | function FXCustomTooltip.CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect;
91 | begin
92 | Canvas.Font.Assign(Font);
93 | Result := Rect(0, 0, MaxWidth, 0);
94 | DrawText(Canvas.Handle, AHint, -1, Result,
95 | DT_CALCRECT or DT_LEFT or DT_WORDBREAK or DT_NOPREFIX or DrawTextBiDiModeFlagsReadingOnly);
96 | Inc(Result.Right, 2 * (HORZ_SPACE + BorderThickness));
97 | Inc(Result.Bottom, 2 * (VERT_SPACE + BorderThickness));
98 | end;
99 |
100 | procedure FXCustomTooltip.Paint;
101 | var
102 | TextRect: TRect;
103 | begin
104 | // Do not inherited
105 | // Paint background
106 | Canvas.Brush.Style := bsSolid;
107 | Canvas.Brush.Color := BackColor;
108 | Canvas.FillRect(Rect(0, 0, Width, Height));
109 | // Draw border
110 | Canvas.Brush.Style := bsClear;
111 | DrawBorder(Canvas, Rect(0, 0, Width, Height), BorderColor, BorderThickness, TOOLTIP_ROUND);
112 | // Draw text
113 | Canvas.Font.Assign(Font);
114 | Canvas.Font.Color := GetTextColorFromBackground(BackColor);
115 | TextRect := Rect(
116 | HORZ_SPACE + BorderThickness, VERT_SPACE + BorderThickness,
117 | Width - HORZ_SPACE - BorderThickness, Height - VERT_SPACE - BorderThickness);
118 | DrawText(Canvas.Handle, Caption, -1, TextRect, DT_WORDBREAK or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS);
119 | end;
120 |
121 | procedure FXCustomTooltip.NCPaint(DC: HDC);
122 | begin
123 | // Do nothing
124 | end;
125 | end.
126 |
--------------------------------------------------------------------------------
/Source/CFX.TypeInfo.pas:
--------------------------------------------------------------------------------
1 | unit CFX.TypeInfo;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Vcl.Graphics, Types, UITypes, Classes, Vcl.Forms, Math,
7 | CFX.Types, TypInfo;
8 |
9 | function PropertyExists(Instance: TObject; const PropName: string): boolean;
10 |
11 | implementation
12 |
13 | function PropertyExists(Instance: TObject; const PropName: string): boolean; overload;
14 | var
15 | AProp: PPropInfo;
16 | begin
17 | AProp := GetPropInfo(PTypeInfo(Instance.ClassInfo), PropName);
18 |
19 | Result := AProp <> nil;
20 | end;
21 |
22 | end.
23 |
--------------------------------------------------------------------------------
/Source/CFX.UXTheme.pas:
--------------------------------------------------------------------------------
1 | unit CFX.UXTheme;
2 | {$WARN SYMBOL_PLATFORM OFF}
3 | {$ALIGN ON}
4 | {$MINENUMSIZE 4}
5 |
6 | interface
7 | uses
8 | Winapi.Windows, SysUtils;
9 |
10 | type
11 | TPreferredAppMode = (DefaultMode, AllowDarkMode, ForceDarkMode, ForceLightMode, ModeMax);
12 |
13 | implementation
14 |
15 | uses
16 | CFX.ThemeManager;
17 |
18 | var
19 | UXThemeDLL: HMODULE = 0;
20 |
21 | type
22 | SystemcallThemePre18 = function(allow: BOOL): BOOL; stdcall;
23 | SystemcallTheme = function(appMode: TPreferredAppMode): TPreferredAppMode;
24 |
25 | function IsWindows10OrGreater(buildNumber: DWORD): Boolean;
26 | begin
27 | Result := (TOSVersion.Major > 10) or ((TOSVersion.Major = 10) and (TOSVersion.Minor = 0) and (DWORD(TOSVersion.Build) >= buildNumber));
28 | end;
29 | function CheckBuildNumber(buildNumber: DWORD): Boolean;
30 | begin
31 | Result :=
32 | IsWindows10OrGreater(20348) or
33 | IsWindows10OrGreater(19045) or //
34 | IsWindows10OrGreater(19044) or //
35 | IsWindows10OrGreater(19043) or //
36 | IsWindows10OrGreater(19042) or //
37 | IsWindows10OrGreater(19041) or // 2004
38 | IsWindows10OrGreater(18363) or // 1909
39 | IsWindows10OrGreater(18362) or // 1903
40 | IsWindows10OrGreater(17763); // 1809
41 | end;
42 |
43 | initialization
44 | if ((TOSVersion.Major <> 10) or (TOSVersion.Minor <> 0) or not CheckBuildNumber(TOSVersion.Build)) then
45 | Exit;
46 |
47 | // Load undocumented DLL proc only for Win64
48 | {$IFDEF WIN64}
49 | UXThemeDLL := LoadLibrary('uxtheme.dll');
50 | if (UXThemeDLL <> 0) and not IsDesigning then begin
51 | const Proc = GetProcAddress(UXThemeDLL, MakeIntResource(135));
52 | if TOSVersion.Build < 18362 then
53 | SystemcallThemePre18(Proc)(true)
54 | else
55 | SystemcallTheme(Proc)(TPreferredAppMode.AllowDarkMode);
56 | end;
57 | {$ENDIF}
58 |
59 | finalization
60 | if UXThemeDLL <> 0 then
61 | FreeLibrary(UXThemeDLL);
62 |
63 | end.
64 |
--------------------------------------------------------------------------------
/Source/CFX.Utilities.pas:
--------------------------------------------------------------------------------
1 | unit CFX.Utilities;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, Win.Registry, System.UITypes,
7 | Types, Vcl.Forms, Vcl.Graphics, CFX.Colors, CFX.Registry, Winapi.ShellAPI,
8 | CFX.Types, IOUTils, RegularExpressions, CFX.Files, CFX.Constants;
9 |
10 | function GetAppsUseDarkTheme: Boolean;
11 | function GetAccentColor( brightencolor: boolean = true ): TColor;
12 | /// Returns the scroll amount in Pixels.
13 | function GetScrollAmount(Delta: integer; ViewHeight: integer): integer;
14 | function GetLinesPerScroll: integer;
15 | function GetLineScrollHeight: integer;
16 | function GetNTKernelVersion: single;
17 |
18 | function GetUserNameString: string;
19 |
20 | // Shell
21 | procedure ShellRun(Command: string; Parameters: string = '');
22 |
23 | // String
24 | function IsStringAlphaNumeric(const S: string): Boolean;
25 |
26 | // File
27 | function GetFileBytesString(FileName: string; FirstCount: integer): TArray;
28 | function ReadFileSignature(FileName: string): TFileType;
29 |
30 | // General Folder
31 | function GetAppDataFolder: string;
32 | function GetPackagesFolder: string;
33 |
34 | // Screen
35 | procedure QuickScreenShot(var BitMap: TBitMap; Monitor: integer = -2);
36 | procedure AppScreenShot(var BitMap: TBitMap; ApplicationCapton: string);
37 |
38 |
39 | implementation
40 |
41 | function GetNTKernelVersion: single;
42 | begin
43 | Result := Win32MajorVersion + Win32MinorVersion / 10;
44 | end;
45 |
46 | function GetAppsUseDarkTheme: Boolean;
47 | var
48 | R: TRegistry;
49 | begin
50 | Result := False;
51 | R := TRegistry.Create;
52 | try
53 | R.RootKey := HKEY_CURRENT_USER;
54 | if R.OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\Themes\Personalize\') and R.ValueExists('AppsUseLightTheme') then begin
55 | Result := R.ReadInteger('AppsUseLightTheme') <> 1;
56 | end;
57 | finally
58 | R.Free;
59 | end;
60 | end;
61 |
62 | function GetAccentColor( brightencolor: boolean = true ): TColor;
63 | var
64 | R: TRegistry;
65 | ARGB: cardinal;
66 | begin
67 | Result := $D77800; // Default value on error
68 | R := TRegistry.Create;
69 | try
70 | R.RootKey := HKEY_CURRENT_USER;
71 | if R.OpenKeyReadOnly('Software\Microsoft\Windows\DWM\') and R.ValueExists('AccentColor') then begin
72 | ARGB := R.ReadCardinal('AccentColor');
73 | Result := ARGB mod $FF000000; // ARGB to RGB
74 | end;
75 | finally
76 | R.Free;
77 | end;
78 |
79 | if brightencolor then
80 | Result := ChangeColorLight(Result, 50);
81 | end;
82 |
83 | function GetLinesPerScroll: integer;
84 | var
85 | R: TRegistry;
86 | begin
87 | Result := DEFAULT_SCROLL_LINES; // default value
88 | R := TRegistry.Create;
89 | try
90 | R.RootKey := HKEY_CURRENT_USER;
91 | if R.OpenKeyReadOnly('Control Panel\Desktop') and R.ValueExists('WheelScrollLines') then begin
92 | try
93 | Result := R.ReadString('WheelScrollLines').ToInteger;
94 | except
95 | end;
96 | end;
97 | finally
98 | R.Free;
99 | end;
100 | end;
101 |
102 | function GetScrollAmount(Delta: integer; ViewHeight: integer): integer;
103 | begin
104 | // Sign
105 | Result := -(Delta div abs(Delta));
106 |
107 | // Registry
108 | const LinePerScroll = GetLinesPerScroll;
109 |
110 | // Full page
111 | if LinePerScroll = -1 then
112 | Result := Result * ViewHeight
113 | else
114 | Result := Result * LinePerScroll * GetLineScrollHeight;
115 | end;
116 |
117 | function GetLineScrollHeight: integer;
118 | begin
119 | Result := DEFAULT_LINE_SIZE;
120 | end;
121 |
122 | function GetUserNameString: string;
123 | var
124 | nSize: DWord;
125 | begin
126 | nSize := 1024;
127 | SetLength(Result, nSize);
128 | if GetUserName(PChar(Result), nSize) then
129 | SetLength(Result, nSize-1)
130 | else
131 | RaiseLastOSError;
132 | end;
133 |
134 | procedure ShellRun(Command, Parameters: string);
135 | begin
136 | ShellExecute(0, 'open', PChar(Command), PChar(Parameters), nil, SW_NORMAL);
137 | end;
138 |
139 | function IsStringAlphaNumeric(const S: string): Boolean;
140 | begin
141 | Result := TRegEx.IsMatch(S, '^[a-zA-Z0-9]+$');
142 | end;
143 |
144 | function GetFileBytesString(FileName: string; FirstCount: integer): TArray;
145 | var
146 | Bytes: TBytes;
147 | I, Total: Integer;
148 | begin
149 | // Get File
150 | Bytes := TFile.ReadAllBytes(FileName);
151 | Total := Length( Bytes );
152 |
153 | // Total Items
154 | if (FirstCount = -1) or (FirstCount > Total) then
155 | FirstCount := Total;
156 |
157 | // Size
158 | SetLength( Result, FirstCount );
159 |
160 | // Convert
161 | for I := 0 to FirstCount - 1 do
162 | Result[I] := DecToHex( Bytes[I] );
163 | end;
164 |
165 | function ReadFileSignature(FileName: string): TFileType;
166 | const
167 | MAX_READ_BUFF = 16;
168 |
169 | FTYP = '66 74 79 70';
170 |
171 | BMP_SIGN: TArray = ['42 4D'];
172 | PNG_SIGN: TArray = ['89 50 4E 47 0D 0A 1A 0A'];
173 | GIF_SIGN: TArray = ['47 49 46'];
174 | JPEG_SIGN: TArray = ['FF D8 FF', '49 46 00 01'];
175 | HEIF_SIGN: TArray = [FTYP + '68 65 69 63'];
176 | TIFF_SIGN: TArray = ['49 49 2A 00', '4D 4D 00 2A'];
177 |
178 | MP3_SIGN: TArray = ['49 44 33', 'FF FB', 'FF F3', 'FF F2'];
179 | MP4_SIGN: TArray = [FTYP + '69 73 6F 6D'];
180 | FLAC_SIGN: TArray = ['66 4C 61 43'];
181 | MDI_SIGN: TArray = ['4D 54 68 64'];
182 | OGG_SIGN: TArray = ['4F 67 67 53'];
183 | SND_SIGN: TArray = ['2E 73 6E 64'];
184 | M3U8_SIGN: TArray = ['23 45 58 54 4D 33 55'];
185 |
186 | EXE_SIGN: TArray = ['4D 5A'];
187 | MSI_SIGN: TArray = ['D0 CF 11 E0 A1 B1 1A E1'];
188 |
189 | ZIP_SIGN: TArray = ['50 4B 03 04', '50 4B 05 06', '50 4B 07 08'];
190 | GZIP_SIGN: TArray = ['1F 8B'];
191 | ZIP7_SIGN: TArray = ['37 7A BC AF 27 1C'];
192 | CABINET_SIGN: TArray = ['4D 53 43 46'];
193 | TAR_SIGN: TArray = ['75 73 74 61 72 00 30 30', '75 73 74 61 72 20 20 00'];
194 | RAR_SIGN: TArray = ['52 61 72 21 1A 07 00', '52 61 72 21 1A 07 01 00'];
195 | LZIP_SIGN: TArray = ['4C 5A 49 50'];
196 |
197 | ISO_SIGN: TArray = ['43 44 30 30 31', '49 73 5A 21'];
198 |
199 | PDF_SIGN: TArray = ['25 50 44 46 2D'];
200 |
201 | HLP_SIGN: TArray = ['3F 5F'];
202 |
203 | CHM_SIGN: TArray = ['49 54 53 46 03 00 00 00'];
204 | var
205 | HexArray: TArray;
206 | HEX: string;
207 | I: Integer;
208 |
209 | function HasSignature(HEX: string; ValidSign: TArray): boolean;
210 | var
211 | I: integer;
212 | begin
213 | Result := false;
214 | for I := 0 to High(ValidSign) do
215 | begin
216 | ValidSign[I] := ValidSign[I].Replace(' ', '');
217 |
218 | if Copy( HEX, 1, Length(ValidSign[I]) ) = ValidSign[I] then
219 | Exit(True);
220 | end;
221 | end;
222 | begin
223 | Result := TFileType.Text;
224 |
225 | // Get File
226 | HexArray := GetFileBytesString( FileName, MAX_READ_BUFF );
227 |
228 | HEX := '';
229 | for I := 0 to High(HexArray) do
230 | HEX := HEX + HexArray[I];
231 |
232 | SetLength(HexArray, 0);
233 |
234 | // Invalid
235 | if HEX = '' then
236 | Exit;
237 |
238 | // All Types Listed (not great)
239 |
240 | (* Picture Types *)
241 | if HasSignature(HEX, BMP_SIGN) then
242 | Exit( TFileType.BMP );
243 |
244 | if HasSignature(HEX, PNG_SIGN) then
245 | Exit( TFileType.PNG );
246 |
247 | if HasSignature(HEX, JPEG_SIGN) then
248 | Exit( TFileType.JPEG );
249 |
250 | if HasSignature(HEX, GIF_SIGN) then
251 | Exit( TFileType.GIF );
252 |
253 | if HasSignature(HEX, TIFF_SIGN) then
254 | Exit( TFileType.TIFF );
255 |
256 | (* Video/Audio Media *)
257 | if HasSignature(HEX, MP3_SIGN) then
258 | Exit( TFileType.MP3 );
259 |
260 | if HasSignature(HEX, FLAC_SIGN) then
261 | Exit( TFileType.Flac );
262 |
263 | if HasSignature(HEX, MDI_SIGN) then
264 | Exit( TFileType.MDI );
265 |
266 | if HasSignature(HEX, OGG_SIGN) then
267 | Exit( TFileType.OGG );
268 |
269 | if HasSignature(HEX, SND_SIGN) then
270 | Exit( TFileType.SND );
271 |
272 | if HasSignature(HEX, M3U8_SIGN) then
273 | Exit( TFileType.M3U8 );
274 |
275 | (* Executable *)
276 | if HasSignature(HEX, EXE_SIGN) then
277 | Exit( TFileType.EXE );
278 |
279 | if HasSignature(HEX, MSI_SIGN) then
280 | Exit( TFileType.MSI );
281 |
282 | (* Zip *)
283 | if HasSignature(HEX, ZIP_SIGN) then
284 | Exit( TFileType.Zip );
285 |
286 | if HasSignature(HEX, GZIP_SIGN) then
287 | Exit( TFileType.GZip );
288 |
289 | if HasSignature(HEX, ZIP7_SIGN) then
290 | Exit( TFileType.Zip7 );
291 |
292 | if HasSignature(HEX, CABINET_SIGN) then
293 | Exit( TFileType.Cabinet );
294 |
295 | if HasSignature(HEX, TAR_SIGN) then
296 | Exit( TFileType.TAR );
297 |
298 | if HasSignature(HEX, RAR_SIGN) then
299 | Exit( TFileType.RAR );
300 |
301 | if HasSignature(HEX, LZIP_SIGN) then
302 | Exit( TFileType.LZIP );
303 |
304 | (* ISO *)
305 | if HasSignature(HEX, ISO_SIGN) then
306 | Exit( TFileType.ISO );
307 |
308 | (* PDF *)
309 | if HasSignature(HEX, PDF_SIGN) then
310 | Exit( TFileType.PDF );
311 |
312 | (* Help File *)
313 | if HasSignature(HEX, HLP_SIGN) then
314 | Exit( TFileType.HLP );
315 |
316 | if HasSignature(HEX, CHM_SIGN) then
317 | Exit( TFileType.CHM );
318 | end;
319 |
320 | function GetAppDataFolder: string;
321 | begin
322 | Result := IncludeTrailingPathDelimiter(ReplaceWinPath('%APPDATA%'));
323 | end;
324 |
325 | function GetPackagesFolder: string;
326 | begin
327 | Result := IncludeTrailingPathDelimiter(GetAppDataFolder + 'Packages');
328 | end;
329 |
330 | procedure QuickScreenShot(var BitMap: TBitMap; Monitor: integer);
331 | var
332 | C: TCanvas;
333 | R: TRect;
334 | begin
335 | /// PARAMETER VALUES ///
336 | /// ///
337 | /// -2 All Monitors (Default) ///
338 | /// ///
339 | /// -1 Default Monitor ///
340 | /// ///
341 | /// >= 0 Monitor Index ///
342 | /// ///
343 |
344 | case Monitor of
345 | -2: R := Rect(Screen.DesktopRect.Left, Screen.DesktopRect.Top, Screen.DesktopRect.Right, Screen.DesktopRect.Bottom);
346 |
347 | -1: R := Rect(Screen.PrimaryMonitor.BoundsRect.Left, Screen.PrimaryMonitor.BoundsRect.Top,
348 | Screen.PrimaryMonitor.BoundsRect.Right, Screen.PrimaryMonitor.BoundsRect.Bottom);
349 |
350 | else R := Rect(Screen.Monitors[Monitor].BoundsRect.Left, Screen.Monitors[Monitor].BoundsRect.Top,
351 | Screen.Monitors[Monitor].BoundsRect.Right, Screen.Monitors[Monitor].BoundsRect.Bottom);
352 | end;
353 |
354 |
355 |
356 | BitMap.Width := R.Width;
357 | BitMap.Height := R.Height;
358 |
359 | C := TCanvas.Create;
360 | try
361 | C.Handle := GetDC(0);
362 |
363 | BitMap.Canvas.CopyRect( BitMap.Canvas.ClipRect, C, R );
364 | finally
365 | C.Free;
366 | end;
367 | end;
368 |
369 | procedure AppScreenShot(var BitMap: TBitMap; ApplicationCapton: string);
370 | var
371 | Handle: HWND;
372 | R: TRect;
373 | DC: HDC;
374 | Old: HGDIOBJ;
375 |
376 | begin
377 | Handle := FindWindow(nil, PWideChar(ApplicationCapton));
378 | GetWindowRect(Handle, R);
379 |
380 | Bitmap := TBitmap.Create;
381 | Bitmap.Width := R.Right - R.Left;
382 | Bitmap.Height := R.Bottom - R.Top;
383 |
384 | DC := GetDC(Handle);
385 | Old := SelectObject(DC, Bitmap.Canvas.Handle);
386 | BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, DC, 0, 0, SRCCOPY);
387 | SelectObject(DC, Old);
388 | ReleaseDC(Handle, DC);
389 | end;
390 |
391 | end.
392 |
393 |
--------------------------------------------------------------------------------
/Source/CFX.Version.pas:
--------------------------------------------------------------------------------
1 | { Imported from Cod Library Pack }
2 |
3 | unit CFX.Version;
4 |
5 | interface
6 | uses
7 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
8 | System.Types, IdSNTP, Registry, DateUtils, IdHTTP, Math, JSON, IdSSLOpenSSL,
9 | CFX.Math, CFX.Constants;
10 |
11 | type
12 | FXVersion = record
13 | Major,
14 | Minor,
15 | Maintenance,
16 | Build: cardinal;
17 |
18 | APIResponse: TJsonObject;
19 |
20 | // Main
21 | constructor Create(AString: string); overload;
22 | constructor Create(AMajor, AMinor, AMaintenance: cardinal; ABuild: cardinal=0); overload;
23 | procedure Clear;
24 |
25 | // Load
26 | procedure Parse(From: string);
27 | procedure NetworkLoad(URL: string);
28 | procedure HtmlLoad(URL: string);
29 | procedure APILoad(AppName: string; Endpoint: string = DEFAULT_API); overload;
30 | procedure APILoad(AppName: string; Current: FXVersion; Endpoint: string = DEFAULT_API); overload;
31 |
32 | // Comparation
33 | function Empty: boolean;
34 | function CompareTo(Version: FXVersion): TValueRelationship;
35 | function NewerThan(Version: FXVersion): boolean;
36 | function OlderThan(Version: FXVersion): boolean;
37 |
38 | // Utils
39 | function GetDownloadLink(JSONValue: string = DEFAULT_UPDATE_NAME): string;
40 |
41 | // Conversion
42 | function ToString: string; overload;
43 | function ToString(IncludeBuild: boolean): string; overload;
44 | function ToString(Separator: char; IncludeBuild: boolean = false): string; overload;
45 |
46 | // Operators
47 | class operator Equal(A, B: FXVersion): Boolean;
48 | class operator NotEqual(A, B: FXVersion): Boolean;
49 | end;
50 |
51 | function MakeVersion(Major, Minor, Maintenance: cardinal; Build: cardinal = 0): FXVersion;
52 |
53 | const
54 | VERSION_EMPTY: FXVersion = (Major:0; Minor:0; Maintenance:0; Build:0);
55 |
56 | implementation
57 |
58 | function MakeVersion(Major, Minor, Maintenance: cardinal; Build: cardinal = 0): FXVersion;
59 | begin
60 | Result.Major := Major;
61 | Result.Minor := Minor;
62 | Result.Maintenance := Maintenance;
63 | Result.Build := Build;
64 | end;
65 |
66 |
67 | { TVersionRec }
68 |
69 | procedure FXVersion.NetworkLoad(URL: string);
70 | var
71 | IdHttp: TIdHTTP;
72 | HTML: string;
73 | begin
74 | IdHttp := TIdHTTP.Create(nil);
75 | try
76 | HTML := IdHttp.Get(URL);
77 |
78 | Parse(HTML);
79 | finally
80 | IdHttp.Free;
81 | end;
82 | end;
83 |
84 |
85 | function FXVersion.NewerThan(Version: FXVersion): boolean;
86 | begin
87 | Result := CompareTo(Version) = GreaterThanValue;
88 | end;
89 |
90 | class operator FXVersion.NotEqual(A, B: FXVersion): Boolean;
91 | begin
92 | Result := A.CompareTo(B) <> GreaterThanValue;
93 | end;
94 |
95 | function FXVersion.OlderThan(Version: FXVersion): boolean;
96 | begin
97 | Result := CompareTo(Version) = LessThanValue;
98 | end;
99 |
100 | procedure FXVersion.APILoad(AppName, Endpoint: string);
101 | begin
102 | APILoad(AppName, VERSION_EMPTY, EndPoint);
103 | end;
104 |
105 | procedure FXVersion.APILoad(AppName: string; Current: FXVersion;
106 | Endpoint: string);
107 | var
108 | HTTP: TIdHTTP;
109 | SSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
110 | Request: TJSONObject;
111 | RequestStream: TStringStream;
112 | Result: string;
113 | begin
114 | // Create HTTP and SSLIOHandler components
115 | HTTP := TIdHTTP.Create(nil);
116 | SSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
117 | Request := TJSONObject.Create;
118 |
119 | // Build Request
120 | Request.AddPair('mode', 'getversion');
121 | Request.AddPair('app', AppName);
122 | if not Current.Empty then
123 | Request.AddPair('client-version', Current.ToString(true));
124 |
125 | // Request
126 | RequestStream := TStringStream.Create(Request.ToJSON, TEncoding.UTF8);
127 | try
128 | // Set SSL/TLS options
129 | SSLIOHandler.SSLOptions.SSLVersions := [sslvTLSv1_2];
130 | HTTP.IOHandler := SSLIOHandler;
131 |
132 | // Set headers
133 | HTTP.Request.ContentType := 'application/json';
134 |
135 | // Send POST
136 | Result := HTTP.Post(Endpoint, RequestStream);
137 |
138 | // Parse
139 | APIResponse := TJSONObject.ParseJSONValue( Result ) as TJSONObject;
140 |
141 | // Parse response
142 | Parse(APIResponse.GetValue('version'));
143 | finally
144 | // Free
145 | (* dont free APIResponse *)
146 | HTTP.Free;
147 | Request.Free;
148 | RequestStream.Free;
149 | end;
150 | end;
151 |
152 | procedure FXVersion.Clear;
153 | begin
154 | Major := 0;
155 | Minor := 0;
156 | Maintenance := 0;
157 | Build := 0;
158 | end;
159 |
160 | function FXVersion.CompareTo(Version: FXVersion): TValueRelationship;
161 | begin
162 | Result := CompareValue(Major, Version.Major);
163 | if Result <> EqualsValue then
164 | Exit;
165 |
166 | Result := CompareValue(Minor, Version.Minor);
167 | if Result <> EqualsValue then
168 | Exit;
169 |
170 | Result := CompareValue(Maintenance, Version.Maintenance);
171 | if Result <> EqualsValue then
172 | Exit;
173 |
174 | Result := CompareValue(Build, Version.Build);
175 | end;
176 |
177 | constructor FXVersion.Create(AString: string);
178 | begin
179 | Parse(AString);
180 | end;
181 |
182 | constructor FXVersion.Create(AMajor, AMinor, AMaintenance, ABuild: cardinal);
183 | begin
184 | Major := AMajor;
185 | Minor := AMinor;
186 | Maintenance := AMaintenance;
187 | Build := ABuild;
188 | end;
189 |
190 | function FXVersion.Empty: boolean;
191 | begin
192 | Result := CompareTo(VERSION_EMPTY) = EqualsValue;
193 | end;
194 |
195 | class operator FXVersion.Equal(A, B: FXVersion): Boolean;
196 | begin
197 | Result := A.CompareTo(B) = EqualsValue;
198 | end;
199 |
200 | function FXVersion.GetDownloadLink(JSONValue: string): string;
201 | begin
202 | if not APIResponse.TryGetValue(JSONValue, Result) then
203 | Result := '';
204 | end;
205 |
206 | procedure FXVersion.HtmlLoad(URL: string);
207 | var
208 | IdHttp: TIdHTTP;
209 | HTML: string;
210 | begin
211 | IdHttp := TIdHTTP.Create(nil);
212 | try
213 | IdHttp.Request.CacheControl := 'no-cache';
214 | HTML := IdHttp.Get(URL);
215 |
216 | HTML := Trim(HTML).Replace(#13, '').DeQuotedString;
217 |
218 | Parse(HTML);
219 | finally
220 | IdHttp.Free;
221 | end;
222 | end;
223 |
224 | procedure FXVersion.Parse(From: string);
225 | var
226 | Separator: char;
227 | Splitted: TArray;
228 | I: Integer;
229 | Value: cardinal;
230 | AVersions: integer;
231 | begin
232 | // Separator
233 | if From.IndexOf('.') <> -1 then
234 | Separator := '.'
235 | else
236 | if From.IndexOf(',') <> -1 then
237 | Separator := ','
238 | else
239 | if From.IndexOf('-') <> -1 then
240 | Separator := '-'
241 | else
242 | Separator := #0;
243 |
244 | // Values
245 | Splitted := From.Split(Separator);
246 |
247 | AVersions := Length(Splitted);
248 | if AVersions < 0 then
249 | Exit;
250 |
251 | // Write
252 | Clear;
253 |
254 | for I := 0 to AVersions-1 do
255 | begin
256 | Value := Splitted[I].ToInteger;
257 | case I of
258 | 0: Major := Value;
259 | 1: Minor := Value;
260 | 2: Maintenance := Value;
261 | 3: Build := Value;
262 | end;
263 | end;
264 | end;
265 |
266 | function FXVersion.ToString: string;
267 | begin
268 | Result := ToString(false);
269 | end;
270 |
271 | function FXVersion.ToString(IncludeBuild: boolean): string;
272 | begin
273 | Result := ToString('.', IncludeBuild);
274 | end;
275 |
276 | function FXVersion.ToString(Separator: char; IncludeBuild: boolean): string;
277 | begin
278 | Result := Major.ToString + Separator + Minor.ToString + Separator + Maintenance.ToString;
279 |
280 | if IncludeBuild then
281 | Result := Result + Separator + Build.ToString;
282 | end;
283 |
284 | end.
285 |
--------------------------------------------------------------------------------
/Test/Backup/CFXTest.pas:
--------------------------------------------------------------------------------
1 | unit CFXTest;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UCL.Form,
8 |
9 | // CFX LIBRARY
10 | CFX.Forms, CFX.Colors, CFX.ThemeManager, Vcl.StdCtrls, Vcl.TitleBarCtrls,
11 | Vcl.ExtCtrls, Cod.Panels, Vcl.Imaging.jpeg, Cod.Button, CFX.Button,
12 | Vcl.Imaging.pngimage, Cod.Image, UCL.CheckBox, CFX.Checkbox, CFX.Panels;
13 |
14 | type
15 | TForm1 = class(FXForm)
16 | Label1: TLabel;
17 | Button2: TButton;
18 | Timer1: TTimer;
19 | FXButton1: FXButton;
20 | CImage1: CImage;
21 | FXButton2: FXButton;
22 | FXButton4: FXButton;
23 | FXButton5: FXButton;
24 | FXButton6: FXButton;
25 | FXButton3: FXButton;
26 | FXButton8: FXButton;
27 | procedure Button2Click(Sender: TObject);
28 | procedure Timer1Timer(Sender: TObject);
29 | private
30 | { Private declarations }
31 | public
32 | { Public declarations }
33 | end;
34 |
35 | var
36 | Form1: FXForm;
37 |
38 | implementation
39 |
40 | {$R *.dfm}
41 |
42 | procedure TForm1.Button2Click(Sender: TObject);
43 | begin
44 | Self.SmokeEffect := NOT Self.SmokeEffect;
45 | end;
46 |
47 | procedure TForm1.Timer1Timer(Sender: TObject);
48 | begin
49 | Self.SmokeEffect := false;
50 | end;
51 |
52 | end.
53 |
--------------------------------------------------------------------------------
/Test/CFXTest.pas:
--------------------------------------------------------------------------------
1 | unit CFXTest;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Forms, Threading, Types, Math,
8 |
9 | // CFX LIBRARY
10 | CFX.Forms, CFX.Colors, CFX.ThemeManager, Vcl.StdCtrls, Vcl.TitleBarCtrls,
11 | Vcl.ExtCtrls, Vcl.Imaging.jpeg, CFX.ButtonDesign, CFX.Checkbox, CFX.Panels,
12 | CFX.StandardIcons, CFX.Dialogs, CFX.BlurMaterial, CFX.Selector,
13 | CFX.Classes, CFX.PopupMenu, CFX.Constants, CFX.Types, CFX.ToolTip, CFX.Hint,
14 | CFX.Slider, CFX.ImageList, CFX.Controls, CFX.Test, CFX.TextBox, CFX.RadioButton,
15 | CFX.Scrollbar, CFX.ScrollBox, CFX.Edit, CFX.Button,
16 | CFX.PopupConnector, Vcl.Buttons, CFX.IconView, CFX.ScrollText, CFX.FormClasses,
17 | CFX.Messages, CFX.VarHelpers, CFX.Graphics, CFX.RatingControl, CFX.Effects,
18 | CFX.Progress, CFX.GDI, CFX.Utilities, CFX.QuickDialogs, CFX.Instances,
19 | CFX.PaintBox, CFX.Lists, CFX.TabStrip, CFX.AppManager, CFX.Shapes,
20 | CFX.Layouts, CFX.TitlebarPanel, CFX.FormTemplates,
21 |
22 | // Cod Windows Runtime
23 |
24 |
25 | // VCL COMPONENTS
26 | Vcl.Dialogs, Vcl.Menus, Vcl.Controls, Vcl.Imaging.pngimage, Vcl.ControlList,
27 | Vcl.ExtDlgs, System.ImageList, UITypes, Vcl.ComCtrls, Vcl.Mask,
28 | Vcl.Themes, System.Generics.Collections,
29 | Vcl.NumberBox;
30 |
31 | type
32 | TForm1 = class(FXForm)
33 | FXStandardIcon1: FXStandardIcon;
34 | FXEdit1: FXEdit;
35 | FXEdit2: FXEdit;
36 | FXButton1: FXButton;
37 | FXButtonDesign3: FXButtonDesign;
38 | FXButtonDesign1: FXButtonDesign;
39 | FXButton3: FXButton;
40 | FXButton7: FXButton;
41 | FXButton8: FXButton;
42 | FXButtonDesign2: FXButtonDesign;
43 | FXButtonDesign4: FXButtonDesign;
44 | FXButton11: FXButton;
45 | FXButton12: FXButton;
46 | FXScrollText2: FXScrollText;
47 | FXSlider1: FXSlider;
48 | FXCheckBox1: FXCheckBox;
49 | FXSelector1: FXSelector;
50 | FXButton4: FXButton;
51 | FXButton5: FXButton;
52 | FXTextBox2: FXTextBox;
53 | FXTextBox3: FXTextBox;
54 | FXTextBox4: FXTextBox;
55 | FXTextBox5: FXTextBox;
56 | FXPopupMenu1: FXPopupMenu;
57 | FXBlurMaterial1: FXBlurMaterial;
58 | FXButton14: FXButton;
59 | FXButton16: FXButton;
60 | PaintBox1: TPaintBox;
61 | FXTextBox8: FXTextBox;
62 | FXIconView1: FXIconView;
63 | FXTabStrip1: FXTabStrip;
64 | FXTitleBarPanel1: FXTitleBarPanel;
65 | FXBlurMaterial2: FXBlurMaterial;
66 | FXButton9: FXButton;
67 | FXScrollText1: FXScrollText;
68 | FXScrollbar1: FXScrollbar;
69 | FXButton2: FXButton;
70 | FXAppManager1: FXAppManager;
71 | FXScrollLayout1: FXScrollLayout;
72 | FXButton6: FXButton;
73 | FXStandardIcon2: FXStandardIcon;
74 | FXSelector2: FXSelector;
75 | FXEdit3: FXEdit;
76 | FXProgress1: FXProgress;
77 | FXButton10: FXButton;
78 | FXButton13: FXButton;
79 | FXButton15: FXButton;
80 | FXButton17: FXButton;
81 | procedure FXButton5Click(Sender: TObject);
82 | procedure FXButton12Click(Sender: TObject);
83 | procedure FXButtonDesign4Click(Sender: TObject);
84 | procedure FXButton14Click(Sender: TObject);
85 | procedure FXButton16Click(Sender: TObject);
86 | procedure PaintBox1Paint(Sender: TObject);
87 | procedure FXSlider1Change(Sender: TObject);
88 | procedure FormCreate(Sender: TObject);
89 | procedure FXAppManager1UpdateChecked(Sender: TObject);
90 | procedure FXPaintBox1Draw(Sender: TObject);
91 | procedure FXButton2Click(Sender: TObject);
92 | procedure FXButton4Click(Sender: TObject);
93 | private
94 | { Private declarations }
95 | public
96 | { Public declarations }
97 | end;
98 |
99 | var
100 | Form1: FXForm;
101 |
102 | H: FXHintPopup;
103 |
104 | implementation
105 |
106 | {$R *.dfm}
107 |
108 | procedure TForm1.FormCreate(Sender: TObject);
109 | begin
110 | FXPopupMenu1.Items[1].Text := '-';
111 | AllowThemeChangeAnimation := true;
112 | end;
113 |
114 | procedure TForm1.FXAppManager1UpdateChecked(Sender: TObject);
115 | begin
116 | if not AppManager.UpdateCheckSuccess then
117 | OpenMessage('Update checking failed')
118 | else
119 | OpenMessage('Latest server version: ' + AppManager.ServerVersion.ToString)
120 | end;
121 |
122 | procedure TForm1.FXButton12Click(Sender: TObject);
123 | begin
124 | FXButton(Sender).Tag := FXButton(Sender).Tag + 1;
125 | FXButton(Sender).StateText := FXButton(Sender).Tag.ToString;
126 | end;
127 |
128 | procedure TForm1.FXButton14Click(Sender: TObject);
129 | var
130 | A: FXFormUpdateTemplate;
131 | begin
132 | A := FXFormUpdateTemplate.CreateNew(Self);
133 | with A do
134 | try
135 | FillMode := FXFormFill.TitleBar;
136 | Self.Width := Self.Width - 1;
137 |
138 | AppName := 'Cool Application';
139 |
140 | DownloadURL := 'https://codrutsoft.com/downloads/software/ibroadcast/Cods%20iBroadcast%201.7.0-x64.exe';
141 | InstallParameters := '-ad';
142 |
143 | Show;
144 | finally
145 | //Free;
146 | end;
147 | end;
148 |
149 | procedure TForm1.FXButton16Click(Sender: TObject);
150 | var
151 | A: FXFormMessageTemplate;
152 | begin
153 | A := FXFormMessageTemplate.CreateNew(Self);
154 | with A do
155 | try
156 | FillMode := FXFormFill.TitleBar;
157 | Self.Width := Self.Width - 1;
158 |
159 | IconKind := FXStandardIconType.Warning;
160 |
161 | Title := 'Hello world!';
162 | Text := 'This is a text message. Read It carefully as It may aid you in the future.';
163 |
164 | Show;
165 | finally
166 | //Free;
167 | end;
168 | end;
169 |
170 | procedure TForm1.FXButton2Click(Sender: TObject);
171 | begin
172 | OpenDialog('Would you like to download the software?', FXDialogKind.Question, [mbYes, mbNo]);
173 | end;
174 |
175 | procedure TForm1.FXButton4Click(Sender: TObject);
176 | var
177 | A: FXModalDialog;
178 | begin
179 | A := FXModalDialog.Create;
180 |
181 | with A do
182 | try
183 | Title := 'Hello World!';
184 | Text := 'This is a fluent dialog box! Here you can press any of the buttons below!';
185 |
186 | //Kind := FXMessageType.Warning;
187 | Buttons := [mbOk, mbCancel];
188 | Parent := Self;
189 |
190 | Execute;
191 | finally
192 | Free;
193 | end;
194 | end;
195 |
196 | procedure TForm1.FXButton5Click(Sender: TObject);
197 | begin
198 | if ThemeManager.DarkTheme then
199 | ThemeManager.DarkThemeMode := FXDarkSetting.ForceLight
200 | else
201 | ThemeManager.DarkThemeMode := FXDarkSetting.ForceDark;
202 |
203 | ThemeManager.UpdateSettings;
204 | end;
205 |
206 | procedure TForm1.FXButtonDesign4Click(Sender: TObject);
207 | var
208 | S: string;
209 | begin
210 | with FXInputBox.Create do
211 | try
212 | Title := 'Search';
213 | Text := 'Enter the search query to begin searching';
214 |
215 | Parent := Self;
216 | Value := '';
217 | TextHint := 'Type here';
218 |
219 | SelectAll := true;
220 | Value := 'Example';
221 | if Execute then
222 | S := Value
223 | else
224 | Exit;
225 |
226 | with FXModalDialog.Create do
227 | try
228 | Title := 'Search Query';
229 | Text := Format('Your search for "%S" returned no results.', [S]);
230 |
231 | Buttons := [mbOk, mbCancel];
232 |
233 | Parent := Self;
234 |
235 | Execute;
236 | finally
237 | Free;
238 | end;
239 | finally
240 | Free;
241 | end;
242 | end;
243 |
244 | procedure TForm1.FXPaintBox1Draw(Sender: TObject);
245 | begin
246 | with FXPaintBox(Sender).Buffer do
247 | begin
248 | Brush.Color := clRed;
249 | Rectangle( ClipRect );
250 | end;
251 | end;
252 |
253 | procedure TForm1.FXSlider1Change(Sender: TObject);
254 | begin
255 | PaintBox1.Tag := round(FXSlider(Sender).Position / 100 * 360);
256 | PaintBox1.Repaint;
257 | end;
258 |
259 | procedure TForm1.PaintBox1Paint(Sender: TObject);
260 | var
261 | R: TRect;
262 | begin
263 | with TPaintBox(Sender).Canvas do
264 | begin
265 | R := ClipRect;
266 |
267 | Font.Height := 22;
268 |
269 | GDIText('Hello world! This is truly incredibile, text rotating! :)',
270 | R, [FXTextFlag.WordWrap, FXTextFlag.NoClip, FXTextFlag.VerticalCenter,
271 | FXTextFlag.Center],
272 | TPaintBox(Sender).Tag);
273 | end;
274 | end;
275 |
276 | end.
277 |
--------------------------------------------------------------------------------
/Test/FluentUXTest.dpr:
--------------------------------------------------------------------------------
1 | program FluentUXTest;
2 |
3 | uses
4 | Vcl.Forms,
5 | CFX.ThemeManager,
6 | CFXTest in 'CFXTest.pas' {Form1},
7 | CFX.Template in '..\Source\CFX.Template.pas';
8 |
9 | {$R *.res}
10 | begin
11 | Application.Initialize;
12 |
13 | Application.MainFormOnTaskbar := True;
14 | Application.CreateForm(TForm1, Form1);
15 | Application.Run;
16 | end.
17 |
--------------------------------------------------------------------------------
/Test/FluentUXTest.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {C2419184-08D1-42DF-AF12-4A57EF324EB9}
4 | FluentUXTest.dpr
5 | True
6 | Debug
7 | 1
8 | Application
9 | VCL
10 | 20.1
11 | Win32
12 | FluentUXTest
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | true
39 | Cfg_1
40 | true
41 | true
42 |
43 |
44 | true
45 | Base
46 | true
47 |
48 |
49 | true
50 | Cfg_2
51 | true
52 | true
53 |
54 |
55 | true
56 | Cfg_2
57 | true
58 | true
59 |
60 |
61 | false
62 | false
63 | false
64 | false
65 | false
66 | 00400000
67 | FluentUXTest
68 | Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
69 | 2057
70 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=
71 |
72 |
73 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
74 | activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar
75 |
76 |
77 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
78 | Debug
79 | true
80 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
81 | 1033
82 | $(BDS)\bin\default_app.manifest
83 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
84 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
85 | $(BDS)\bin\delphi_PROJECTICON.ico
86 | none
87 |
88 |
89 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
90 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
91 |
92 |
93 | RELEASE;$(DCC_Define)
94 | 0
95 | false
96 | 0
97 |
98 |
99 | PerMonitorV2
100 |
101 |
102 | DEBUG;$(DCC_Define)
103 | false
104 | true
105 | true
106 | true
107 |
108 |
109 | Debug
110 |
111 |
112 | PerMonitorV2
113 | true
114 | 1033
115 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
116 |
117 |
118 |
119 | MainSource
120 |
121 |
122 |
123 |
124 |
125 |
126 | Base
127 |
128 |
129 | Cfg_1
130 | Base
131 |
132 |
133 | Cfg_2
134 | Base
135 |
136 |
137 |
138 | Delphi.Personality.12
139 |
140 |
141 |
142 |
143 | FluentUXTest.dpr
144 |
145 |
146 | Embarcadero C++Builder Office 2000 Servers Package
147 | Embarcadero C++Builder Office XP Servers Package
148 | Microsoft Office 2000 Sample Automation Server Wrapper Components
149 | Microsoft Office XP Sample Automation Server Wrapper Components
150 |
151 |
152 |
153 | False
154 | False
155 | True
156 | False
157 |
158 |
159 | 12
160 |
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------