unit ksplitter; { A splitter component that remembers the split position Author: Vesa Lappalainen Date: 28.2.1998 Changes: Must be read in FormShow } interface uses {$ifndef DELPHI5} Types, {$endif} SysUtils, Classes, {$ifdef CLX} QGraphics, QControls, QForms, QDialogs, QExtCtrls, {$else} Windows, Messages, Graphics, Controls, Forms, Dialogs, extctrls, {$endif} kIniSave; type TkSplitter = class(TSplitter) private FIni : TIniSave; FAsString: string; protected public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Loaded; override; function GetAsString : string; virtual; procedure SetAsString(value:string); virtual; function FindNextControl: TControl; virtual; procedure UpdateToThisSize(x,y:integer); virtual; procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; published property Ini : TIniSave read FIni write FIni; property AsString : string read FAsString write SetAsString stored false; end; procedure Register; implementation uses kDouble; //------------------------------------------------------------------------------ procedure Register; begin RegisterComponents('KaveOptions', [TkSplitter]); end; //----------------------------------------------------------------------------- constructor TkSplitter.Create(AOwner: TComponent); // override; begin inherited; FIni := TIniSave.Create(self); Ini.PropName := 'AsString'; Ini.GenName := ''; end; //----------------------------------------------------------------------------- destructor TkSplitter.Destroy; // override; begin Ini.Save; Ini.Free; inherited; end; //----------------------------------------------------------------------------- procedure TkSplitter.Loaded; // override; begin inherited; Ini.Load; end; //----------------------------------------------------------------------------- function TkSplitter.FindNextControl: TControl; var P: TPoint; I: Integer; begin Result := nil; P := Point(Left, Top); case Align of alLeft: Dec(P.X); alRight: Inc(P.X, Width+1); alTop: Dec(P.Y); alBottom: Inc(P.Y, Height+1); else Exit; end; for I := 0 to Parent.ControlCount - 1 do begin Result := Parent.Controls[I]; if PtInRect(Result.BoundsRect, P) then Exit; end; Result := nil; end; //----------------------------------------------------------------------------- procedure TkSplitter.UpdateToThisSize(x,y:integer); var S: Integer; FControl: TControl; FNewSize,FSplit : integer; begin FControl := FindNextControl; if ( FControl = nil ) then exit; if Align in [alLeft, alRight] then FSplit := X - Left else FSplit := Y - Top; S := 0; case Align of alLeft: S := FControl.Width + FSplit; alRight: S := FControl.Width - FSplit; alTop: S := FControl.Height + FSplit; alBottom: S := FControl.Height - FSplit; end; FNewSize := S; if S < MinSize then FNewSize := MinSize; // else if S > MaxSize then // FNewSize := FMaxSize; if S <> FNewSize then begin // if Align in [alRight, alBottom] then // S := S - FNewSize else // S := FNewSize - S; // Inc(FSplit, S); end; case Align of alLeft: FControl.Width := FNewSize; alTop: FControl.Height := FNewSize; alRight: begin Parent.DisableAlign; try FControl.Left := FControl.Left + (FControl.Width - FNewSize); FControl.Width := FNewSize; finally Parent.EnableAlign; end; end; alBottom: begin Parent.DisableAlign; try FControl.Top := FControl.Top + (FControl.Height - FNewSize); FControl.Height := FNewSize; finally Parent.EnableAlign; end; end; end; end; //----------------------------------------------------------------------------- procedure TkSplitter.SetAsString(value:string); // virtual; var nx,ny : integer; begin if ( csDesigning in ComponentState ) then exit; nx := ExtractInt(value,',',Left); ny := ExtractInt(value,',',Top); if ( Align in [alRight,alBottom] ) then begin nx := Parent.ClientWidth - nx; ny := Parent.ClientHeight - ny; end; UpdateToThisSize(nx,ny); end; //----------------------------------------------------------------------------- function TkSplitter.GetAsString : string; // virtual; begin if ( csDesigning in ComponentState ) then begin Result := ''; exit; end; Result := IntToStr(Left) + ',' + IntToStr(Top); if ( Align in [alLeft,alTop] ) then exit; if ( not Assigned(Parent) ) then exit; Result := IntToStr(Parent.ClientWidth-Left) + ',' + IntToStr(Parent.ClientHeight-Top); end; //----------------------------------------------------------------------------- procedure TkSplitter.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin inherited; if ( csDesigning in ComponentState ) then exit; FAsString := IntToStr(Left) + ',' + IntToStr(Top); if ( Align in [alLeft,alTop] ) then exit; if ( not Assigned(Parent) ) then exit; FAsString := IntToStr(Parent.ClientWidth-Left) + ',' + IntToStr(Parent.ClientHeight-Top); end; end.