Skip to content

Commit 29430fe

Browse files
committed
improve TFMXImageSlider
update documents
1 parent 0b1adcc commit 29430fe

32 files changed

+1555
-224
lines changed

ComponentsSource/FMX.ImageSlider.pas

+222-33
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@
99
// https://github.com/zhaoyipeng/FMXComponents
1010
//
1111
// ***************************************************************************
12-
1312
// version history
1413
// 2017-01-20, v0.1.0.0 : first release
1514
// 2018-01-31, v0.2.0.0 : merged with loko's change
15+
// 2018-03-02, v0.3.0.0 : merged with kwon hwang-jung's change 2018-03-02
16+
// 1. add three Add methods to add bitmap directly
17+
// 2. add Next, Prev methods
18+
// 3. add AutoSlider property can auto slide
19+
// 4. add TimerInterval to control AutoSlider interval
20+
// 5. use ActivePage property move page, ex)ActivePage := 1
21+
// 6. add Datas property, can set tagstring on each page
1622

1723
unit FMX.ImageSlider;
1824

@@ -28,60 +34,165 @@ interface
2834
FMX.Layouts,
2935
FMX.Objects,
3036
FMX.Ani,
37+
FMX.Graphics,
3138
FMX.ComponentsCommon;
3239

3340
type
3441

3542
[ComponentPlatformsAttribute(TFMXPlatforms)]
3643
TFMXImageSlider = class(TLayout)
3744
private
38-
FContainer: TLayout;
39-
FPages: TList<TLayout>;
40-
FActivePage: Integer;
41-
FStartDrag: Boolean;
42-
FDownPos: TPointF;
43-
FDownIndex: Integer;
44-
FAnimation: TFloatAnimation;
45-
procedure MoveToActivePage; { add }
45+
FIsTimer : Boolean;
46+
FAutoSlider : Boolean;
47+
FTimer : TTimer;
48+
FContainer : TLayout;
49+
FPages : TList<TLayout>;
50+
FActivePage : Integer;
51+
FIsMove : Boolean;
52+
FStartDrag : Boolean;
53+
FDownPos : TPointF;
54+
FDownIndex : Integer;
55+
FAnimation : TFloatAnimation;
56+
FOnItemTap : TTapEvent;
57+
FOnItemClick : TNotifyEvent;
58+
FOnPageChanged: TNotifyEvent;
59+
procedure MoveToActivePage(IsIn: Boolean = True);
60+
procedure OnTimer(Sender: TObject);
61+
function GetDatas(Index: Integer): string;
62+
function GetPageCount: Integer;
63+
function GetTimerInterval: Integer;
64+
4665
procedure SetActivePage(const Value: Integer); { change }
66+
procedure SetAutoSlider(const Value: Boolean);
4767
procedure SetPageCount(const Value: Integer);
48-
function GetPageCount: Integer;
68+
procedure SetDatas(Index: Integer; const Value: string);
4969
protected
70+
procedure SetTimerInterval(const Value: Integer);
5071
procedure Resize; override;
72+
procedure DoTab(Sender: TObject; const Point: TPointF);
5173
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
5274
procedure MouseMove(Shift: TShiftState; X, Y: Single); override;
53-
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; { change }
75+
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
5476
public
5577
constructor Create(AOwner: TComponent); override;
5678
destructor Destroy; override;
5779
procedure SetPage(Index: Integer; AImage: TImage);
80+
procedure Add(Bitmap: TBitmap);overload; //add bitmap
81+
procedure Add(Value:String; Bitmap: TBitmap);overload; //add bitmap and value
82+
procedure Add(Value:String; Bitmap: TStream);overload; //add bitmap stream and value
83+
procedure Clear; //Page Clear;
84+
procedure Prev; //Previous Page
85+
procedure Next; //Next Page
86+
property Datas[Index: Integer]: string read GetDatas write SetDatas; //Page value(ex 0page = Datas[0])
5887
published
59-
property ActivePage: Integer read FActivePage write SetActivePage;
60-
property PageCount: Integer read GetPageCount write SetPageCount;
6188
property Align;
89+
property Height;
6290
property Position;
6391
property Width;
64-
property Height;
92+
property ActivePage : Integer read FActivePage write SetActivePage; //page move
93+
property AutoSlider : Boolean read FAutoSlider write SetAutoSlider; //auto slider property
94+
property PageCount : Integer read GetPageCount write SetPageCount;
95+
property TimerInterval : Integer read GetTimerInterval write SetTimerInterval; //auto slider timer
96+
property OnPageChanged : TNotifyEvent read FOnPageChanged write FOnPageChanged;
97+
property OnItemClick : TNotifyEvent read FOnItemClick write FOnItemClick; //page click event(use Desktop)
98+
property OnItemTap : TTapEvent read FOnItemTap write FOnItemTap; //page tab event(use Mobile, Pad)
6599
end;
66100

67101
implementation
68102

69103
{ TFMXImageSlider }
70104

105+
procedure TFMXImageSlider.Add(Bitmap: TBitmap);
106+
begin
107+
Add('', Bitmap);
108+
end;
109+
110+
procedure TFMXImageSlider.Add(Value: String; Bitmap: TBitmap);
111+
var
112+
Item: TLayout;
113+
Img : TImage;
114+
begin
115+
Item := TLayout.Create(Self);
116+
Item.Parent := Self.FContainer;
117+
Item.Width := Self.Width;
118+
Item.Height := Self.Height;
119+
Item.Stored := False;
120+
Item.Position.X := FPages.Count * Width;
121+
Item.Index := FPages.Add(Item);
122+
Item.OnTap := DoTab;
123+
Img := TImage.Create(Item);
124+
Img.Parent := Item;
125+
Img.HitTest := False;
126+
Img.Align := TAlignLayout.Client;
127+
Img.Bitmap.Assign(Bitmap);
128+
Item.TagString := Value;
129+
//ActivePage := 0;
130+
FContainer.Width := FPages.Count * Width;
131+
FContainer.Position.X := 0;
132+
if FActivePage = -1 then
133+
FActivePage := 0;
134+
end;
135+
136+
procedure TFMXImageSlider.Add(Value: String; Bitmap: TStream);
137+
var
138+
Item: TLayout;
139+
Img : TImage;
140+
begin
141+
Item := TLayout.Create(Self);
142+
Item.Parent := Self.FContainer;
143+
Item.Width := Self.Width;
144+
Item.Height := Self.Height;
145+
Item.Stored := False;
146+
Item.Position.X := FPages.Count * Width;
147+
Item.Index := FPages.Add(Item);
148+
Item.OnTap := DoTab;
149+
Img := TImage.Create(Item);
150+
Img.Parent := Item;
151+
Img.HitTest := False;
152+
Img.Align := TAlignLayout.Client;
153+
Img.Bitmap.LoadFromStream(Bitmap);
154+
Item.TagString := Value;
155+
//ActivePage := 0;
156+
FContainer.Width := FPages.Count * Width;
157+
FContainer.Position.X := 0;
158+
if FActivePage = -1 then
159+
FActivePage := 0;
160+
end;
161+
162+
procedure TFMXImageSlider.Clear;
163+
var
164+
I: Integer;
165+
begin
166+
for I := FPages.Count-1 downto 0 do
167+
begin
168+
FPages[I].DisposeOf;
169+
end;
170+
FPages.Clear;
171+
ActivePage := -1;
172+
end;
173+
71174
constructor TFMXImageSlider.Create(AOwner: TComponent);
72175
begin
73176
inherited;
74-
FContainer := TLayout.Create(Self);
177+
FTimer := TTimer.Create(Self);
178+
FTimer.Interval := 1000 * 5;
179+
FTimer.Enabled := False;
180+
FTimer.OnTimer := OnTimer;
181+
FAutoSlider := False;
182+
FContainer := TLayout.Create(Self);
75183
FContainer.Parent := Self;
76184
FContainer.Stored := False;
185+
FContainer.Height := Height;
186+
FContainer.Position.Y := 0;
77187
FAnimation := TFloatAnimation.Create(Self);
188+
FAnimation.Interpolation := TInterpolationType.Quintic;
78189
FAnimation.PropertyName := 'Position.X';
79190
FAnimation.Parent := FContainer;
80191
FAnimation.Duration := 0.1;
81-
FPages := TList<TLayout>.Create;
82-
HitTest := True;
83-
ActivePage := -1;
84-
FStartDrag := False;
192+
FPages := TList<TLayout>.Create;
193+
HitTest := True;
194+
ActivePage := -1;
195+
FStartDrag := False;
85196
AutoCapture := True;
86197
end;
87198

@@ -91,14 +202,32 @@ destructor TFMXImageSlider.Destroy;
91202
inherited;
92203
end;
93204

205+
procedure TFMXImageSlider.DoTab(Sender: TObject; const Point: TPointF);
206+
begin
207+
if Assigned(FOnItemTap) then FOnItemTap(Sender, Point);
208+
end;
209+
210+
function TFMXImageSlider.GetDatas(Index: Integer): string;
211+
begin
212+
Result := FPages[Index].TagString;
213+
end;
214+
94215
function TFMXImageSlider.GetPageCount: Integer;
95216
begin
96217
Result := FPages.Count;
97218
end;
98219

220+
function TFMXImageSlider.GetTimerInterval: Integer;
221+
begin
222+
Result := FTimer.Interval;
223+
end;
224+
99225
procedure TFMXImageSlider.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
100226
begin
101227
inherited;
228+
FIsTimer := FTimer.Enabled;
229+
if FIsTimer then FTimer.Enabled := False;
230+
FIsMove := False;
102231
if (PageCount > 0) and (Button = TMouseButton.mbLeft) then
103232
begin
104233
FStartDrag := True;
@@ -114,17 +243,26 @@ procedure TFMXImageSlider.MouseMove(Shift: TShiftState; X, Y: Single);
114243
inherited;
115244
if FStartDrag then
116245
begin
246+
if Abs(FDownPos.X - X) > 5 then FIsMove := True;
117247
DeltaX := X - FDownPos.X;
118248
NewX := -FDownIndex * Width + DeltaX;
119249
FContainer.Position.X := NewX;
120250
end;
121251
end;
122252

123-
procedure TFMXImageSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); { change }
253+
procedure TFMXImageSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
124254
var
125255
DeltaX: Single;
126256
begin
127257
inherited;
258+
if (not FIsMove) and FStartDrag then
259+
begin
260+
if FIsTimer then FTimer.Enabled := True;
261+
FStartDrag := False;
262+
if Assigned(FOnItemClick) then FOnItemClick(FPages[Self.ActivePage]);
263+
if Assigned(FOnItemTap) then FOnItemTap(FPages[Self.ActivePage], PointF(X, Y));
264+
Exit;
265+
end;
128266
if FStartDrag then
129267
begin
130268
FStartDrag := False;
@@ -139,18 +277,44 @@ procedure TFMXImageSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y
139277
if FActivePage < PageCount - 1 then
140278
FActivePage := FActivePage + 1;
141279
end;
142-
{ Loko } MoveToActivePage; // move to page
280+
MoveToActivePage(DeltaX < 0);
281+
if FIsTimer then FTimer.Enabled := True;
282+
if Assigned(FOnPageChanged) then Self.FOnPageChanged(Self);
143283
end;
144284
end;
145285

146-
procedure TFMXImageSlider.MoveToActivePage; { add }
286+
procedure TFMXImageSlider.MoveToActivePage(IsIn: Boolean);
287+
begin
288+
{ a method to move to your active Page }
289+
FAnimation.StartValue := FContainer.Position.X;
290+
FAnimation.StopValue := -FActivePage * Width;
291+
if IsIn then
292+
FAnimation.AnimationType := TAnimationType.Out
293+
else
294+
FAnimation.AnimationType := TAnimationType.&In;
295+
FAnimation.Start;
296+
end;
297+
298+
procedure TFMXImageSlider.Next;
299+
begin
300+
if FActivePage = FPages.Count - 1 then Exit;
301+
FActivePage := FActivePage + 1;
302+
MoveToActivePage(True);
303+
if Assigned(FOnPageChanged) then Self.FOnPageChanged(Self);
304+
end;
305+
306+
procedure TFMXImageSlider.OnTimer(Sender: TObject);
307+
begin
308+
if Self.FActivePage = Self.FPages.Count - 1 then Self.SetActivePage(0)
309+
else Next;
310+
end;
311+
312+
procedure TFMXImageSlider.Prev;
147313
begin
148-
{ a methode to move to your active Page }
149-
{ Loko } FAnimation.StartValue := FContainer.Position.X;
150-
{ Loko } FAnimation.StopValue := -FActivePage * Width;
151-
{ Loko } FAnimation.Interpolation := TInterpolationType.Quintic;
152-
{ Loko } FAnimation.AnimationType := TAnimationType.Out;
153-
{ Loko } FAnimation.Start;
314+
if FActivePage = 0 then Exit;
315+
FActivePage := FActivePage - 1;
316+
MoveToActivePage(False);
317+
if Assigned(FOnPageChanged) then Self.FOnPageChanged(Self);
154318
end;
155319

156320
procedure TFMXImageSlider.Resize;
@@ -167,15 +331,35 @@ procedure TFMXImageSlider.Resize;
167331
FPages[I].Width := Width;
168332
FPages[I].Height := Height;
169333
FPages[I].Position.X := I * Width;
334+
FPages[i].RecalcSize;
170335
end;
171336
end;
172337

173-
procedure TFMXImageSlider.SetActivePage(const Value: Integer); { change }
338+
procedure TFMXImageSlider.SetActivePage(const Value: Integer);
339+
var
340+
IsIn: Boolean;
174341
begin
175-
if (Value < 0) or (Value > FPages.Count - 1) then // check if value valid
176-
exit;
177-
FActivePage := Value; // set FActivePage
178-
MoveToActivePage; // move Page
342+
if FActivePage <> Value then
343+
begin
344+
if FActivePage = -1 then FContainer.Position.X := 0
345+
else
346+
begin
347+
IsIn := FActivePage < Value;
348+
FActivePage := Value;
349+
MoveToActivePage(IsIn);
350+
end;
351+
end;
352+
end;
353+
354+
procedure TFMXImageSlider.SetAutoSlider(const Value: Boolean);
355+
begin
356+
FAutoSlider := Value;
357+
FTimer.Enabled := Value;
358+
end;
359+
360+
procedure TFMXImageSlider.SetDatas(Index: Integer; const Value: string);
361+
begin
362+
FPages[Index].TagString := Value;
179363
end;
180364

181365
procedure TFMXImageSlider.SetPage(Index: Integer; AImage: TImage);
@@ -232,4 +416,9 @@ procedure TFMXImageSlider.SetPageCount(const Value: Integer);
232416
end;
233417
end;
234418

419+
procedure TFMXImageSlider.SetTimerInterval(const Value: Integer);
420+
begin
421+
FTimer.Interval := Value;
422+
end;
423+
235424
end.

0 commit comments

Comments
 (0)