source: tags/1.3.6/LocalPlayer/PVSB.pas

Last change on this file was 612, checked in by chronos, 2 months ago
  • Fixed: Scrollbars behave differently on Linux and Windows. Use conditional code to make it work correctly.
File size: 5.3 KB
Line 
1{$INCLUDE Switches.inc}
2unit PVSB;
3
4interface
5
6uses
7 {$IFDEF WINDOWS}Windows,{$ENDIF}
8 Classes, LCLIntf, LCLType, LMessages, Messages, SysUtils, Math,
9 {$IFDEF DPI}Dpi.Controls, Dpi.Forms, Dpi.StdCtrls{$ELSE}
10 Controls, Forms, StdCtrls{$ENDIF};
11
12type
13
14 { TPVScrollbar }
15
16 TPVScrollBar = class
17 private
18 FOnUpdate: TNotifyEvent;
19 FMax: Integer;
20 function GetMax: Integer;
21 function GetPageSize: Integer;
22 function GetPosition: Integer;
23 procedure ScrollBarChanged(Sender: TObject);
24 procedure SetMax(AValue: Integer);
25 procedure SetPageSize(AValue: Integer);
26 procedure SetPosition(AValue: Integer);
27 public
28 ScrollBar: TScrollBar;
29 WheelSteps: Integer;
30 constructor Create(Parent: TWinControl);
31 destructor Destroy; override;
32 procedure Init(Max, PageSize: Integer);
33 procedure SetPos(Pos: Integer);
34 function Process(const Msg: TMessage): Boolean;
35 function ProcessMouseWheel(Delta: Integer): Boolean;
36 procedure Show(Visible: Boolean);
37 procedure EndSB;
38 procedure SetBorderSpacing(Top, Right, Bottom: Integer);
39 property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
40 property Position: Integer read GetPosition write SetPosition;
41 property Max: Integer read GetMax write SetMax;
42 property PageSize: Integer read GetPageSize write SetPageSize;
43 end;
44
45
46implementation
47
48const
49 Count: Integer = 0;
50
51procedure TPVScrollBar.Init(Max, PageSize: Integer);
52begin
53 ScrollBar.PageSize := PageSize;
54 ScrollBar.Min := 0;
55 Self.Max := Max;
56 ScrollBar.Position := 0;
57 {$IFDEF UNIX}
58 ScrollBar.Visible := Max > ScrollBar.PageSize;
59 {$ELSE}
60 ScrollBar.Visible := Max >= ScrollBar.PageSize;
61 {$ENDIF}
62end;
63
64procedure TPVScrollBar.SetPos(Pos: Integer);
65begin
66 if Pos <> 0 then begin
67 ScrollBar.Position := Pos;
68 end;
69end;
70
71function TPVScrollBar.Process(const Msg: TMessage): Boolean;
72var
73 NewPos: Integer;
74begin
75 if Max < ScrollBar.PageSize then
76 Result := False
77 else
78 begin
79 if (Msg.wParam and $ffff) in [SB_THUMBPOSITION, SB_THUMBTRACK] then
80 begin
81 Result := ((Msg.wParam shr 16) and $ffff) <> ScrollBar.Position;
82 ScrollBar.Position := (Msg.wParam shr 16) and $ffff;
83 end else begin
84 case (Msg.wParam and $ffff) of
85 SB_LINEUP:
86 NewPos := ScrollBar.Position - 1;
87 SB_LINEDOWN:
88 NewPos := ScrollBar.Position + 1;
89 SB_PAGEUP:
90 NewPos := ScrollBar.Position - ScrollBar.PageSize;
91 SB_PAGEDOWN:
92 NewPos := ScrollBar.Position + ScrollBar.PageSize;
93 else
94 NewPos := ScrollBar.Position
95 end;
96 if NewPos < 0 then
97 NewPos := 0;
98 if NewPos > Max - ScrollBar.PageSize + 1 then
99 NewPos := Max - ScrollBar.PageSize + 1;
100 Result := NewPos <> ScrollBar.Position;
101 if (NewPos <> ScrollBar.Position) or ((Msg.wParam and $ffff) = SB_ENDSCROLL) then
102 begin
103 ScrollBar.Position := NewPos;
104 end;
105 end;
106 end;
107end;
108
109function TPVScrollBar.ProcessMouseWheel(Delta: Integer): Boolean;
110var
111 NewPos: Integer;
112begin
113 if Max < ScrollBar.PageSize then Result := False
114 else begin
115 NewPos := ScrollBar.Position - Delta div (120 div WheelSteps);
116 if NewPos < 0 then NewPos := 0;
117 if NewPos > Max - ScrollBar.PageSize + 1 then
118 NewPos := Max - ScrollBar.PageSize + 1;
119 Result := NewPos <> ScrollBar.Position;
120 if NewPos <> ScrollBar.Position then begin
121 ScrollBar.Position := NewPos;
122 end;
123 end;
124end;
125
126procedure TPVScrollBar.Show(Visible: Boolean);
127begin
128 if not Visible or (Max < ScrollBar.PageSize) then
129 ScrollBar.Visible := False
130 else ScrollBar.Visible := True;
131end;
132
133procedure TPVScrollBar.EndSB;
134begin
135 if Max < ScrollBar.PageSize then
136 ScrollBar.Position := 0 // hidden
137 else begin
138 ScrollBar.Position := Max - ScrollBar.PageSize + 1;
139 end;
140end;
141
142procedure TPVScrollBar.SetBorderSpacing(Top, Right, Bottom: Integer);
143begin
144 ScrollBar.BorderSpacing.Top := Top;
145 ScrollBar.BorderSpacing.Right := Right;
146 ScrollBar.BorderSpacing.Bottom := Bottom;
147end;
148
149{ TPVScrollbar }
150
151procedure TPVScrollBar.ScrollBarChanged(Sender: TObject);
152begin
153 if Assigned(FOnUpdate) then FOnUpdate(Self);
154end;
155
156procedure TPVScrollBar.SetMax(AValue: Integer);
157begin
158 FMax := AValue;
159 ScrollBar.Max := Math.Max(0, FMax);
160end;
161
162procedure TPVScrollBar.SetPageSize(AValue: Integer);
163begin
164 ScrollBar.PageSize := AValue;
165end;
166
167function TPVScrollBar.GetPosition: Integer;
168begin
169 Result := ScrollBar.Position;
170end;
171
172function TPVScrollBar.GetMax: Integer;
173begin
174 Result := FMax;
175end;
176
177function TPVScrollBar.GetPageSize: Integer;
178begin
179 Result := ScrollBar.PageSize;
180end;
181
182procedure TPVScrollBar.SetPosition(AValue: Integer);
183begin
184 ScrollBar.Position := AValue;
185end;
186
187constructor TPVScrollBar.Create(Parent: TWinControl);
188begin
189 Inc(Count);
190 ScrollBar := TScrollBar.Create(Parent);
191 ScrollBar.Kind := TScrollBarKind.sbVertical;
192 ScrollBar.Name := 'PVSB' + IntToStr(Count);
193 ScrollBar.Align := TAlign.alRight;
194 ScrollBar.OnChange := ScrollBarChanged;
195 ScrollBar.Parent := Parent;
196 ScrollBar.Width := 16;
197 WheelSteps := 4;
198end;
199
200destructor TPVScrollBar.Destroy;
201begin
202 FreeAndNil(ScrollBar);
203end;
204
205end.
Note: See TracBrowser for help on using the repository browser.