📄 gr32_image.pas
字号:
begin
if Value < 0.001 then Value := 0.001;
if Value <> FScaleX then
begin
InvalidateCache;
FScaleX := Value;
FScaleY := Value;
DoScaleChange;
Changed;
end;
end;
procedure TCustomImage32.SetScaleX(Value: Single);
begin
if Value < 0.001 then Value := 0.001;
if Value <> FScaleX then
begin
InvalidateCache;
FScaleX := Value;
DoScaleChange;
Changed;
end;
end;
procedure TCustomImage32.SetScaleY(Value: Single);
begin
if Value < 0.001 then Value := 0.001;
if Value <> FScaleY then
begin
InvalidateCache;
FScaleY := Value;
DoScaleChange;
Changed;
end;
end;
procedure TCustomImage32.SetScaleMode(Value: TScaleMode);
begin
if Value <> FScaleMode then
begin
InvalidateCache;
FScaleMode := Value;
Changed;
end;
end;
procedure TCustomImage32.SetupBitmap(DoClear: Boolean = False; ClearColor: TColor32 = $FF000000);
begin
FBitmap.BeginUpdate;
with GetViewPortRect do
FBitmap.SetSize(Right - Left, Bottom - Top);
if DoClear then FBitmap.Clear(ClearColor);
FBitmap.EndUpdate;
InvalidateCache;
Changed;
end;
procedure TCustomImage32.UpdateCache;
begin
if CacheValid then Exit;
CachedBitmapRect := GetBitmapRect;
with CachedBitmapRect, CachedXForm do
begin
if Bitmap.Empty then CachedXForm := UnitXForm
else
begin
ShiftX := Left;
ShiftY := Top;
ScaleX := MulDiv(Right - Left, $10000, Bitmap.Width);
ScaleY := MulDiv(Bottom - Top, $10000, Bitmap.Height);
RevScaleX := MulDiv(Bitmap.Width, $10000, Right - Left);
RevScaleY := MulDiv(Bitmap.Height, $10000, Bottom - Top);
end;
end;
CacheValid := True;
end;
function TCustomImage32.InvalidRectsAvailable: Boolean;
begin
// avoid calling inherited, we have a totally different behaviour here...
DoPrepareInvalidRects;
Result := FInvalidRects.Count > 0;
end;
procedure TCustomImage32.SetRepaintMode(const Value: TRepaintMode);
begin
inherited;
case Value of
rmOptimizer:
begin
FBitmap.OnAreaChanged := BitmapAreaChangeHandler;
FBitmap.OnChange := nil;
end;
rmDirect:
begin
FBitmap.OnAreaChanged := BitmapDirectAreaChangeHandler;
FBitmap.OnChange := nil;
end;
else
FBitmap.OnAreaChanged := nil;
FBitmap.OnChange := BitmapChangeHandler;
end;
end;
{ TIVScrollProperties }
function TIVScrollProperties.GetIncrement: Integer;
begin
Result := Round(TCustomRangeBar(Master).Increment);
end;
function TIVScrollProperties.GetSize: Integer;
begin
Result := ImgView.FScrollBarSize;
end;
function TIVScrollProperties.GetVisibility: TScrollbarVisibility;
begin
Result := ImgView.FScrollBarVisibility;
end;
procedure TIVScrollProperties.SetIncrement(Value: Integer);
begin
TCustomRangeBar(Master).Increment := Value;
TCustomRangeBar(Slave).Increment := Value;
end;
procedure TIVScrollProperties.SetSize(Value: Integer);
begin
ImgView.FScrollBarSize := Value;
ImgView.AlignAll;
end;
procedure TIVScrollProperties.SetVisibility(const Value: TScrollbarVisibility);
begin
if Value <> ImgView.FScrollBarVisibility then
begin
ImgView.FScrollBarVisibility := Value;
ImgView.Resize;
end;
end;
{ TCustomImgView32 }
procedure TCustomImgView32.AlignAll;
var
ScrollbarVisible: Boolean;
begin
with GetViewportRect do
begin
ScrollbarVisible := GetScrollBarsVisible;
If Assigned(HScroll) then
begin
HScroll.BoundsRect := Rect(Left, Bottom, Right, Height);
HScroll.Visible := ScrollbarVisible;
HScroll.Repaint;
end;
If Assigned(VScroll) then
begin
VScroll.BoundsRect := Rect(Right, Top, Width, Bottom);
VScroll.Visible := ScrollbarVisible;
VScroll.Repaint;
end;
end;
end;
procedure TCustomImgView32.BitmapResized;
begin
inherited;
UpdateScrollBars;
if Centered then ScrollToCenter(Bitmap.Width div 2, Bitmap.Height div 2)
else
begin
HScroll.Position := 0;
VScroll.Position := 0;
UpdateImage;
end;
end;
constructor TCustomImgView32.Create(AOwner: TComponent);
begin
inherited;
HScroll := TCustomRangeBar.Create(Self);
VScroll := TCustomRangeBar.Create(Self);
with HScroll do
begin
HScroll.Parent := Self;
BorderStyle := bsNone;
Centered := True;
OnUserChange := ScrollHandler;
end;
with VScroll do
begin
Parent := Self;
BorderStyle := bsNone;
Centered := True;
Kind := sbVertical;
OnUserChange := ScrollHandler;
end;
FCentered := True;
ScaleMode := smScale;
BitmapAlign := baCustom;
with GetViewportRect do
begin
OldSzX := Right - Left;
OldSzY := Bottom - Top;
end;
FScrollBars := TIVScrollProperties.Create;
FScrollBars.ImgView := Self;
FScrollBars.Master := HScroll;
FScrollBars.Slave := VScroll;
AlignAll;
end;
destructor TCustomImgView32.Destroy;
begin
FreeAndNil(FScrollBars);
inherited;
end;
procedure TCustomImgView32.DoDrawSizeGrip(R: TRect);
begin
{$IFNDEF CLX}
if USE_THEMES then
begin
Canvas.Brush.Color := clBtnFace;
Canvas.FillRect(R);
DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, SBP_SIZEBOX, SZB_RIGHTALIGN, R, nil);
end
else
DrawFrameControl(Canvas.Handle, R, DFC_SCROLL, DFCS_SCROLLSIZEGRIP)
{$ENDIF}
end;
procedure TCustomImgView32.DoScaleChange;
begin
inherited;
InvalidateCache;
UpdateScrollBars;
UpdateImage;
Invalidate;
end;
procedure TCustomImgView32.DoScroll;
begin
if Assigned(FOnScroll) then FOnScroll(Self);
end;
function TCustomImgView32.GetScrollBarSize: Integer;
{$IFDEF CLX}
var
Size: TSize;
{$ENDIF}
begin
if GetScrollBarsVisible then
begin
Result := FScrollBarSize;
{$IFDEF CLX}
QStyle_scrollBarExtent(Application.Style.Handle, @Size);
if Result = 0 then Result := Size.cy;
{$ELSE}
if Result = 0 then Result := GetSystemMetrics(SM_CYHSCROLL);
{$ENDIF}
end
else
Result := 0;
end;
function TCustomImgView32.GetScrollBarsVisible: Boolean;
begin
Result := True;
if Assigned(FScrollBars) and Assigned(HScroll) and Assigned(VScroll) then
case FScrollBars.Visibility of
svAlways:
Result := True;
svHidden:
Result := False;
svAuto:
Result := (HScroll.Range > TRangeBarAccess(HScroll).EffectiveWindow) or
(VScroll.Range > TRangeBarAccess(VScroll).EffectiveWindow);
end;
end;
function TCustomImgView32.GetSizeGripRect: TRect;
var
Sz: Integer;
begin
Sz := GetScrollBarSize;
Result := GetClientRect;
with Result do
begin
Left := Right - Sz;
Top := Bottom - Sz;
end;
end;
function TCustomImgView32.GetViewportRect: TRect;
var
Sz: Integer;
begin
Result := Rect(0, 0, Width, Height);
Sz := GetScrollBarSize;
Dec(Result.Right, Sz);
Dec(Result.Bottom, Sz);
end;
function TCustomImgView32.IsSizeGripVisible: Boolean;
var
P: TWinControl;
begin
case SizeGrip of
sgAuto:
begin
Result := False;
if Align <> alClient then Exit;
P := Parent;
while True do
begin
if P is TCustomForm then
begin
Result := True;
Break;
end
else if not Assigned(P) or (P.Align <> alClient) then Exit;
P := P.Parent;
end;
end;
sgNone: Result := False
else { sgAlways }
Result := True;
end;
end;
procedure TCustomImgView32.Loaded;
begin
AlignAll;
Invalidate;
UpdateScrollBars;
if Centered then with Bitmap do ScrollToCenter(Width div 2, Height div 2);
inherited;
end;
procedure TCustomImgView32.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{$IFNDEF CLX}
var
Action: Cardinal;
Msg: TMessage;
P: TPoint;
{$ENDIF}
begin
{$IFNDEF CLX}
if IsSizeGripVisible and (Owner is TCustomForm) then
begin
P.X := X; P.Y := Y;
if PtInRect(GetSizeGripRect, P) then
begin
Action := HTBOTTOMRIGHT;
Application.ProcessMessages;
Msg.Msg := WM_NCLBUTTONDOWN;
Msg.WParam := Action;
SetCaptureControl(nil);
with Msg do SendMessage(TCustomForm(Owner).Handle, Msg, wParam, lParam);
Exit;
end;
end;
{$ENDIF}
inherited;
end;
procedure TCustomImgView32.MouseMove(Shift: TShiftState; X, Y: Integer);
var
P: TPoint;
begin
inherited;
if IsSizeGripVisible then
begin
P.X := X; P.Y := Y;
if PtInRect(GetSizeGripRect, P) then Screen.Cursor := crSizeNWSE;
end;
end;
procedure TCustomImgView32.Paint;
begin
if IsSizeGripVisible then
DoDrawSizeGrip(GetSizeGripRect)
else
begin
Canvas.Brush.Color := clBtnFace;
Canvas.FillRect(GetSizeGripRect);
end;
inherited;
end;
procedure TCustomImgView32.Resize;
begin
AlignAll;
if IsSizeGripVisible then
DoDrawSizeGrip(GetSizeGripRect)
else
begin
Canvas.Brush.Color := clBtnFace;
Canvas.FillRect(GetSizeGripRect);
end;
InvalidateCache;
UpdateScrollBars;
UpdateImage;
Invalidate;
inherited;
end;
procedure TCustomImgView32.Scroll(Dx, Dy: Integer);
begin
DisableScrollUpdate := True;
HScroll.Position := HScroll.Position + Dx;
VScroll.Position := VScroll.Position + Dy;
DisableScrollUpdate := False;
UpdateImage;
end;
procedure TCustomImgView32.ScrollHandler(Sender: TObject);
begin
if DisableScrollUpdate then Exit;
if Sender = HScroll then HScroll.Repaint;
if Sender = VScroll then VScroll.Repaint;
UpdateImage;
DoScroll;
Repaint;
end;
procedure TCustomImgView32.ScrollToCenter(X, Y: Integer);
var
ScaledDOversize: Integer;
begin
DisableScrollUpdate := True;
AlignAll;
ScaledDOversize := Round(FOversize * Scale);
with GetViewportRect do
begin
HScroll.Position := X * Scale - (Right - Left) / 2 + ScaledDOversize;
VScroll.Position := Y * Scale - (Bottom - Top) / 2 + ScaledDOversize;
end;
DisableScrollUpdate := False;
UpdateImage;
end;
procedure TCustomImgView32.Recenter;
begin
InvalidateCache;
HScroll.Centered := FCentered;
VScroll.Centered := FCentered;
UpdateScrollBars;
UpdateImage;
if FCentered then
with Bitmap do
ScrollToCenter(Width div 2, Height div 2)
else
ScrollToCenter(0, 0);
end;
procedure TCustomImgView3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -