Componentes.Terceros.jvcl/official/3.00/run/JvgSplit.pas

418 lines
10 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvgSplit.PAS, released on 2003-01-15.
The Initial Developer of the Original Code is Andrey V. Chudin, [chudin att yandex dott ru]
Portions created by Andrey V. Chudin are Copyright (C) 2003 Andrey V. Chudin.
All Rights Reserved.
Contributor(s):
Michael Beck [mbeck att bigfoot dott com].
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvgSplit.pas,v 1.15 2005/02/17 10:21:21 marquardt Exp $
unit JvgSplit;
{$I jvcl.inc}
interface
uses
{$IFDEF USEJVCL}
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Windows, Messages, Classes, Controls, Graphics, ExtCtrls,
JvComponent, JVCLVer;
{$ELSE}
Windows, Messages, Classes, Controls, Graphics, ExtCtrls;
{$ENDIF USEJVCL}
type
TJvgSplitter = class(TSplitter)
private
{$IFDEF USEJVCL}
FAboutJVCL: TJVCLAboutInfo;
{$ENDIF USEJVCL}
FHotTrack: Boolean;
FTrackCount: Integer;
FActive: Boolean;
FDisplace: Boolean;
FKeepSize: Integer; (* +++ RDB --- *)
procedure CMMouseEnter(var Msg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
procedure WMMouseDblClick(var Msg: TMessage); message WM_LBUTTONDBLCLK;
procedure SetTrackCount(const Value: Integer);
procedure UpdateControlSize;
function FindControl: TControl;
procedure PrepareMarcs(Align: TAlign; var Pt1, Pt2, Pt3, Pt4, Pt5, Pt6: TPoint);
procedure SetDisplace(const Value: Boolean);
public
constructor Create(AOwner: TComponent); override;
procedure Paint; override;
published
{$IFDEF USEJVCL}
property AboutJVCL: TJVCLAboutInfo read FAboutJVCL write FAboutJVCL stored False;
{$ENDIF USEJVCL}
property Displace: Boolean read FDisplace write SetDisplace default True;
property HotTrack: Boolean read FHotTrack write FHotTrack default True;
property TrackCount: Integer read FTrackCount write SetTrackCount default 20;
property Width default 6;
end;
{$IFDEF USEJVCL}
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvgSplit.pas,v $';
Revision: '$Revision: 1.15 $';
Date: '$Date: 2005/02/17 10:21:21 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
{$ENDIF USEJVCL}
implementation
{$IFDEF USEJVCL}
uses
JvThemes;
{$ENDIF USEJVCL}
constructor TJvgSplitter.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF USEJVCL}
IncludeThemeStyle(Self, [csParentBackground]);
{$ENDIF USEJVCL}
FKeepSize := 0;
//..defaults
Width := 6;
FHotTrack := True;
FDisplace := True;
FTrackCount := 20;
end;
procedure TJvgSplitter.Paint;
var
I: Integer;
SColor: TColor;
Pt1, Pt2, Pt3, Pt4, Pt5, Pt6: TPoint;
R, R1, R2: TRect;
begin
with Canvas do
begin
Brush.Color := Self.Color;
{$IFDEF USEJVCL}
DrawThemedBackground(Self, Canvas, ClientRect);
{$ELSE}
Canvas.FillRect(ClientRect);
{$ENDIF USEJVCL}
if (Align = alBottom) or (Align = alTop) then
begin
R1 := Classes.Bounds((Width - FTrackCount * 4) div 2, 0, 3, 3);
R2 := Classes.Bounds((Width - FTrackCount * 4) div 2, 3, 3, 3);
end
else
begin
R1 := Classes.Bounds(0, (Height - FTrackCount * 4) div 2, 3, 3);
R2 := Classes.Bounds(3, (Height - FTrackCount * 4) div 2, 3, 3);
end;
for I := 0 to FTrackCount - 1 do
begin
{$IFDEF JVCLThemesEnabled}
if FActive and HotTrack and ThemeServices.ThemesEnabled then
SColor := RGB(100, 100, 100)
else
{$ENDIF JVCLThemesEnabled}
if FActive and HotTrack then
SColor := clBlack
else
SColor := clBtnShadow;
R := R1;
Frame3D(Canvas, R, clBtnHighlight, SColor, 1);
R := R2;
Frame3D(Canvas, R, clBtnHighlight, SColor, 1);
if (Align = alBottom) or (Align = alTop) then
begin
OffsetRect(R1, 4, 0);
OffsetRect(R2, 4, 0);
end
else
begin
OffsetRect(R1, 0, 4);
OffsetRect(R2, 0, 4);
end;
end;
if FDisplace then
begin
PrepareMarcs(Align, Pt1, Pt2, Pt3, Pt4, Pt5, Pt6);
if FActive then
Canvas.Brush.Color := clGray
else
Canvas.Brush.Color := clWhite;
Canvas.Polygon([Pt1, Pt2, Pt3]);
Canvas.Polygon([Pt4, Pt5, Pt6]);
end;
end;
end;
procedure TJvgSplitter.PrepareMarcs(Align: TAlign; var Pt1, Pt2, Pt3, Pt4, Pt5, Pt6: TPoint);
begin
case Align of
alRight:
begin
Pt1.X := 1;
Pt1.Y := (Height - FTrackCount * 4) div 2 - 30;
Pt2.X := 1;
Pt2.Y := Pt1.Y + 6;
Pt3.X := 4;
Pt3.Y := Pt1.Y + 3;
Pt4.X := 1;
Pt4.Y := (Height - FTrackCount * 4) div 2 + FTrackCount * 4 + 30 -
7;
Pt5.X := 1;
Pt5.Y := Pt4.Y + 6;
Pt6.X := 4;
Pt6.Y := Pt4.Y + 3;
end;
alLeft:
begin
Pt1.X := 3;
Pt1.Y := (Height - FTrackCount * 4) div 2 - 30;
Pt2.X := 3;
Pt2.Y := Pt1.Y + 6;
Pt3.X := 0;
Pt3.Y := Pt1.Y + 3;
Pt4.X := 3;
Pt4.Y := (Height - FTrackCount * 4) div 2 + FTrackCount * 4 + 30 -
7;
Pt5.X := 3;
Pt5.Y := Pt4.Y + 6;
Pt6.X := 0;
Pt6.Y := Pt4.Y + 3;
end;
alTop:
begin
Pt1.X := (Width - FTrackCount * 4) div 2 - 30;
Pt1.Y := 4;
Pt2.X := Pt1.X + 6;
Pt2.Y := 4;
Pt3.X := Pt1.X + 3;
Pt3.Y := 1;
Pt4.X := (Width - FTrackCount * 4) div 2 + FTrackCount * 4 + 30 - 7;
Pt4.Y := 4;
Pt5.X := Pt4.X + 6;
Pt5.Y := 4;
Pt6.X := Pt4.X + 3;
Pt6.Y := 1;
end;
alBottom:
begin
Pt1.X := (Width - FTrackCount * 4) div 2 - 30;
Pt1.Y := 1;
Pt2.X := Pt1.X + 6;
Pt2.Y := 1;
Pt3.X := Pt1.X + 3;
Pt3.Y := 4;
Pt4.X := (Width - FTrackCount * 4) div 2 + FTrackCount * 4 + 30 - 7;
Pt4.Y := 1;
Pt5.X := Pt4.X + 6;
Pt5.Y := 1;
Pt6.X := Pt4.X + 3;
Pt6.Y := 4;
end;
end;
end;
procedure TJvgSplitter.CMMouseEnter(var Msg: TMessage);
begin
inherited;
FActive := True;
Invalidate;
end;
procedure TJvgSplitter.CMMouseLeave(var Msg: TMessage);
begin
inherited;
FActive := False;
Invalidate;
end;
procedure TJvgSplitter.SetTrackCount(const Value: Integer);
begin
FTrackCount := Value;
Invalidate;
end;
procedure TJvgSplitter.WMMouseDblClick(var Msg: TMessage);
begin
if FDisplace then
UpdateControlSize;
end;
procedure TJvgSplitter.UpdateControlSize;
const
cNewSize = 0;
var
FControl: TControl;
begin
FControl := FindControl;
if not Assigned(FControl) then
Exit;
if FKeepSize = 0 then
begin
case Align of
alLeft:
begin
FKeepSize := FControl.Width;
FControl.Width := cNewSize;
end;
alTop:
begin
FKeepSize := FControl.Height;
FControl.Height := cNewSize;
end;
alRight:
begin
FKeepSize := FControl.Width;
Parent.DisableAlign;
try
FControl.Left := FControl.Left + (FControl.Width - cNewSize);
FControl.Width := cNewSize;
finally
Parent.EnableAlign;
end;
end;
alBottom:
begin
FKeepSize := FControl.Height;
Parent.DisableAlign;
try
FControl.Top := FControl.Top + (FControl.Height - cNewSize);
FControl.Height := cNewSize;
finally
Parent.EnableAlign;
end;
end;
end;
end
else (* ++++ RDB +++ *)
begin
case Align of
alLeft:
FControl.Width := FKeepSize;
alTop:
FControl.Height := FKeepSize;
alRight:
begin
Parent.DisableAlign;
try
FControl.Left := FControl.Left + (FControl.Width - FKeepSize);
FControl.Width := FKeepSize;
finally
Parent.EnableAlign;
end;
end;
alBottom:
begin
Parent.DisableAlign;
try
FControl.Top := FControl.Top + (FControl.Height - FKeepSize);
FControl.Height := FKeepSize;
finally
Parent.EnableAlign;
end;
end;
end;
FKeepSize := 0; (* --- RDB --- *)
end;
Update;
if Assigned(OnMoved) then
OnMoved(Self);
end;
function TJvgSplitter.FindControl: TControl;
var
P: TPoint;
I: Integer;
R: TRect;
begin
Result := nil;
P := Point(Left, Top);
case Align of
alLeft:
Dec(P.X);
alRight:
Inc(P.X, Width);
alTop:
Dec(P.Y);
alBottom:
Inc(P.Y, Height);
else
Exit;
end;
for I := 0 to Parent.ControlCount - 1 do
begin
Result := Parent.Controls[I];
if Result.Visible and Result.Enabled then
begin
R := Result.BoundsRect;
if (R.Right - R.Left) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Left)
else
Inc(R.Right);
if (R.Bottom - R.Top) = 0 then
if Align in [alTop, alLeft] then
Dec(R.Top)
else
Inc(R.Bottom);
if PtInRect(R, P) then
Exit;
end;
end;
Result := nil;
end;
procedure TJvgSplitter.SetDisplace(const Value: Boolean);
begin
FDisplace := Value;
Invalidate;
end;
{$IFDEF USEJVCL}
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
{$ENDIF USEJVCL}
end.