9
9
// https://github.com/zhaoyipeng/FMXComponents
10
10
//
11
11
// ***************************************************************************
12
-
13
12
// version history
14
13
// 2017-01-20, v0.1.0.0 : first release
15
14
// 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
16
22
17
23
unit FMX.ImageSlider;
18
24
@@ -28,60 +34,165 @@ interface
28
34
FMX.Layouts,
29
35
FMX.Objects,
30
36
FMX.Ani,
37
+ FMX.Graphics,
31
38
FMX.ComponentsCommon;
32
39
33
40
type
34
41
35
42
[ComponentPlatformsAttribute(TFMXPlatforms)]
36
43
TFMXImageSlider = class (TLayout)
37
44
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
+
46
65
procedure SetActivePage (const Value : Integer); { change }
66
+ procedure SetAutoSlider (const Value : Boolean);
47
67
procedure SetPageCount (const Value : Integer);
48
- function GetPageCount : Integer;
68
+ procedure SetDatas (Index : Integer; const Value : string) ;
49
69
protected
70
+ procedure SetTimerInterval (const Value : Integer);
50
71
procedure Resize ; override;
72
+ procedure DoTab (Sender: TObject; const Point: TPointF);
51
73
procedure MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
52
74
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;
54
76
public
55
77
constructor Create(AOwner: TComponent); override;
56
78
destructor Destroy; override;
57
79
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])
58
87
published
59
- property ActivePage: Integer read FActivePage write SetActivePage;
60
- property PageCount: Integer read GetPageCount write SetPageCount;
61
88
property Align;
89
+ property Height;
62
90
property Position;
63
91
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)
65
99
end ;
66
100
67
101
implementation
68
102
69
103
{ TFMXImageSlider }
70
104
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
+
71
174
constructor TFMXImageSlider.Create(AOwner: TComponent);
72
175
begin
73
176
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);
75
183
FContainer.Parent := Self;
76
184
FContainer.Stored := False;
185
+ FContainer.Height := Height;
186
+ FContainer.Position.Y := 0 ;
77
187
FAnimation := TFloatAnimation.Create(Self);
188
+ FAnimation.Interpolation := TInterpolationType.Quintic;
78
189
FAnimation.PropertyName := ' Position.X' ;
79
190
FAnimation.Parent := FContainer;
80
191
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;
85
196
AutoCapture := True;
86
197
end ;
87
198
@@ -91,14 +202,32 @@ destructor TFMXImageSlider.Destroy;
91
202
inherited ;
92
203
end ;
93
204
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
+
94
215
function TFMXImageSlider.GetPageCount : Integer;
95
216
begin
96
217
Result := FPages.Count;
97
218
end ;
98
219
220
+ function TFMXImageSlider.GetTimerInterval : Integer;
221
+ begin
222
+ Result := FTimer.Interval;
223
+ end ;
224
+
99
225
procedure TFMXImageSlider.MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Single);
100
226
begin
101
227
inherited ;
228
+ FIsTimer := FTimer.Enabled;
229
+ if FIsTimer then FTimer.Enabled := False;
230
+ FIsMove := False;
102
231
if (PageCount > 0 ) and (Button = TMouseButton.mbLeft) then
103
232
begin
104
233
FStartDrag := True;
@@ -114,17 +243,26 @@ procedure TFMXImageSlider.MouseMove(Shift: TShiftState; X, Y: Single);
114
243
inherited ;
115
244
if FStartDrag then
116
245
begin
246
+ if Abs(FDownPos.X - X) > 5 then FIsMove := True;
117
247
DeltaX := X - FDownPos.X;
118
248
NewX := -FDownIndex * Width + DeltaX;
119
249
FContainer.Position.X := NewX;
120
250
end ;
121
251
end ;
122
252
123
- procedure TFMXImageSlider.MouseUp (Button: TMouseButton; Shift: TShiftState; X, Y: Single); { change }
253
+ procedure TFMXImageSlider.MouseUp (Button: TMouseButton; Shift: TShiftState; X, Y: Single);
124
254
var
125
255
DeltaX: Single;
126
256
begin
127
257
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 ;
128
266
if FStartDrag then
129
267
begin
130
268
FStartDrag := False;
@@ -139,18 +277,44 @@ procedure TFMXImageSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y
139
277
if FActivePage < PageCount - 1 then
140
278
FActivePage := FActivePage + 1 ;
141
279
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);
143
283
end ;
144
284
end ;
145
285
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 ;
147
313
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);
154
318
end ;
155
319
156
320
procedure TFMXImageSlider.Resize ;
@@ -167,15 +331,35 @@ procedure TFMXImageSlider.Resize;
167
331
FPages[I].Width := Width;
168
332
FPages[I].Height := Height;
169
333
FPages[I].Position.X := I * Width;
334
+ FPages[i].RecalcSize;
170
335
end ;
171
336
end ;
172
337
173
- procedure TFMXImageSlider.SetActivePage (const Value : Integer); { change }
338
+ procedure TFMXImageSlider.SetActivePage (const Value : Integer);
339
+ var
340
+ IsIn: Boolean;
174
341
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 ;
179
363
end ;
180
364
181
365
procedure TFMXImageSlider.SetPage (Index: Integer; AImage: TImage);
@@ -232,4 +416,9 @@ procedure TFMXImageSlider.SetPageCount(const Value: Integer);
232
416
end ;
233
417
end ;
234
418
419
+ procedure TFMXImageSlider.SetTimerInterval (const Value : Integer);
420
+ begin
421
+ FTimer.Interval := Value ;
422
+ end ;
423
+
235
424
end .
0 commit comments