{*********************************************************} {* OVCBORDR.PAS 4.06 *} {*********************************************************} {* ***** BEGIN LICENSE BLOCK ***** *} {* Version: MPL 1.1 *} {* *} {* 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/ *} {* *} {* Software distributed under the License is distributed on an "AS IS" basis, *} {* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License *} {* for the specific language governing rights and limitations under the *} {* License. *} {* *} {* The Original Code is TurboPower Orpheus *} {* *} {* The Initial Developer of the Original Code is TurboPower Software *} {* *} {* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002 *} {* TurboPower Software Inc. All Rights Reserved. *} {* *} {* Contributor(s): *} {* *} {* ***** END LICENSE BLOCK ***** *} {$I OVC.INC} {$B-} {Complete Boolean Evaluation} {$I+} {Input/Output-Checking} {$P+} {Open Parameters} {$T-} {Typed @ Operator} {.W-} {Windows Stack Frame} {$X+} {Extended Syntax} unit ovcbordr; {Old style, To be deprecated - simple, single, solid borders for entry controls} interface uses {$IFNDEF LCL} Windows, Messages, {$ELSE} LclIntf, LMessages, MyMisc, {$ENDIF} Buttons, Classes, Controls, ExtCtrls, Forms, Graphics, Menus, StdCtrls, SysUtils, OvcBase, OvcConst, OvcData, OvcMisc, OvcEditF; type TOvcBorderStyle = (bpsSolid); TOvcBorderEdButton = class(TBitBtn) public procedure Click; override; end; TOvcBorder = class(TPersistent) protected {private} FEnabled : Boolean; {is border used} FBorderStyle : TOvcBorderStyle; {bpsSolid only for now} FPenColor : TColor; {color of pen} FPenStyle : TPenStyle; {Windows pen style} FPenWidth : integer; {width of pen} FOnChange : TNotifyEvent; {notify owner of changes} protected procedure DoOnChange; procedure SetDefaults; procedure SetEnabled(Value : Boolean); procedure SetBorderStyle(Value : TOvcBorderStyle); procedure SetPenColor(Value : TColor); procedure SetPenStyle(Value : TPenStyle); procedure SetPenWidth(Value : integer); public procedure Assign(Value : TPersistent); override; constructor Create; published property BorderStyle : TOvcBorderStyle read FBorderStyle write SetBorderStyle stored FEnabled default bpsSolid; property Enabled : Boolean read FEnabled write SetEnabled default False; property OnChange : TNotifyEvent read FOnChange write FOnChange; property PenColor : TColor read FPenColor write SetPenColor stored FEnabled default clBlack; property PenStyle : TPenStyle read FPenStyle write SetPenStyle stored FEnabled default psSolid; property PenWidth : integer read FPenWidth write SetPenWidth stored FEnabled default 2; end; TOvcBorders = class(TPersistent) protected {private} FLeftBorder : TOvcBorder; FRightBorder : TOvcBorder; FTopBorder : TOvcBorder; FBottomBorder : TOvcBorder; public procedure Assign(Source : TPersistent); override; constructor Create; destructor Destroy; override; published property BottomBorder : TOvcBorder read FBottomBorder write FBottomBorder; property LeftBorder : TOvcBorder read FLeftBorder write FLeftBorder; property RightBorder : TOvcBorder read FRightBorder write FRightBorder; property TopBorder : TOvcBorder read FTopBorder write FTopBorder; end; TOvcBorderParent = class(TOvcCustomControl) {.Z+} protected {private} {property variables} FBorders : TOvcBorders; FEdit : TOvcCustomEdit; FLabelInfo : TOvcLabelInfo; {$IFDEF LCL} FCtl3D : Boolean; {$ENDIF} FOrgHeight : integer; protected DefaultLabelPosition : TOvcLabelPosition; DoingBorders : Boolean; procedure BorderChanged(ABorder : TObject); function GetAttachedLabel : TOvcAttachedLabel; procedure Paint; override; procedure PaintBorders; virtual; procedure WMSetFocus(var Msg : TWMSetFocus); message WM_SETFOCUS; procedure WMKillFocus(var Msg : TWMKillFocus); message WM_KillFOCUS; {internal methods} procedure LabelChange(Sender : TObject); procedure LabelAttach(Sender : TObject; Value : Boolean); procedure PositionLabel; {VCL message methods} procedure CMVisibleChanged(var Msg : TMessage); message CM_VISIBLECHANGED; procedure OrAssignLabel(var Msg : TMessage); message OM_ASSIGNLABEL; procedure OrPositionLabel(var Msg : TMessage); message OM_POSITIONLABEL; procedure OrRecordLabelPosition(var Msg : TMessage); message OM_RECORDLABELPOSITION; procedure CreateWnd; override; procedure Notification(AComponent : TComponent; Operation: TOperation); override; public ButtonWidth : integer; DoShowButton : Boolean; constructor Create(AOwner : TComponent); override; destructor Destroy; override; procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; procedure SetEditControl(EC : TOvcCustomEdit); virtual; property AttachedLabel : TOvcAttachedLabel read GetAttachedLabel; property Canvas; property EditControl : TOvcCustomEdit read FEdit write FEdit; published property Borders : TOvcBorders read FBorders write FBorders; property LabelInfo : TOvcLabelInfo read FLabelInfo write FLabelInfo; {$IFDEF LCL} property Ctl3D : Boolean read FCtl3D write FCtl3D; {$ENDIF} end; implementation uses OvcBCalc; procedure TOvcBorderEdButton.Click; begin TOvcBorderEdPopup(Parent).PopupOpen; end; {******************************************************************************} { TOvcBorder } {******************************************************************************} constructor TOvcBorder.Create; begin inherited Create; SetDefaults; end; procedure TOvcBorder.Assign(Value : TPersistent); var B : TOvcBorder absolute Value; begin if (Value <> nil) and (Value is TOvcBorder) then begin Enabled := B.Enabled; PenColor := B.PenColor; PenStyle := B.PenStyle; PenWidth := B.PenWidth; end else inherited Assign(Value); end; procedure TOvcBorder.DoOnChange; begin if (Assigned(FOnChange)) then FOnChange(Self); end; procedure TOvcBorder.SetDefaults; begin FEnabled := False; FPenColor := clBlack; FPenStyle := psSolid; FPenWidth := 2; end; procedure TOvcBorder.SetBorderStyle(Value : TOvcBorderStyle); begin if (FBorderStyle <> Value) then begin FBorderStyle := Value; DoOnChange; end; end; procedure TOvcBorder.SetEnabled(Value : Boolean); begin if (FEnabled <> Value) then begin FEnabled := Value; DoOnChange; end; end; procedure TOvcBorder.SetPenColor(Value : TColor); begin if (FPenColor <> Value) then begin FPenColor := Value; DoOnChange; end; end; procedure TOvcBorder.SetPenStyle(Value : TPenStyle); begin if (FPenStyle <> Value) then begin FPenStyle := Value; DoOnChange; end; end; procedure TOvcBorder.SetPenWidth(Value : integer); begin if (FPenWidth <> Value) and (Value > 0) then begin FPenWidth := Value; DoOnChange; end; end; {******************************************************************************} { TOvcBorders } {******************************************************************************} constructor TOvcBorders.Create; begin inherited Create; FBottomBorder := TOvcBorder.Create; FLeftBorder := TOvcBorder.Create; FRightBorder := TOvcBorder.Create; FTopBorder := TOvcBorder.Create; end; destructor TOvcBorders.Destroy; begin FBottomBorder.Free; FBottomBorder := nil; FLeftBorder.Free; FLeftBorder := nil; FRightBorder.Free; FRightBorder := nil; FTopBorder.Free; FTopBorder := nil; inherited Destroy; end; procedure TOvcBorders.Assign(Source : TPersistent); var B : TOvcBorders absolute Source; begin if (Source <> nil) and (Source is TOvcBorders) then begin FBottomBorder.Assign(B.BottomBorder); FLeftBorder.Assign(B.LeftBorder); FRightBorder.Assign(B.RightBorder); FTopBorder.Assign(B.TopBorder); end else inherited Assign(Source); end; {******************************************************************************} { TOvcBorderParent } {******************************************************************************} procedure TOvcBorderParent.BorderChanged(ABorder : TObject); begin PaintBorders; end; procedure TOvcBorderParent.CMVisibleChanged(var Msg : TMessage); begin inherited; if csLoading in ComponentState then Exit; if LabelInfo.Visible then AttachedLabel.Visible := Visible; end; constructor TOvcBorderParent.Create(AOwner : TComponent); begin inherited Create(AOwner); Parent := TWinControl(AOwner); Height := 21; Width := 121; FOrgHeight := 21; ControlStyle := ControlStyle - [csSetCaption]; ParentColor := True; Ctl3D := False; {set default position and reference point} DefaultLabelPosition := lpTopLeft; FLabelInfo := TOvcLabelInfo.Create; FLabelInfo.OnChange := LabelChange; FLabelInfo.OnAttach := LabelAttach; {create borders class and assign notifications} FBorders := TOvcBorders.Create; FBorders.LeftBorder.OnChange := BorderChanged; FBorders.RightBorder.OnChange := BorderChanged; FBorders.TopBorder.OnChange := BorderChanged; FBorders.BottomBorder.OnChange := BorderChanged; end; destructor TOvcBorderParent.Destroy; begin {detatch and destroy label, if any} FLabelInfo.Visible := False; {dispose the borders object} FBorders.Free; FLabelInfo.Free; FBorders := nil; FLabelInfo := nil; inherited Destroy; end; function TOvcBorderParent.GetAttachedLabel : TOvcAttachedLabel; begin if not FLabelInfo.Visible then raise Exception.Create(GetOrphStr(SCLabelNotAttached)); Result := FLabelInfo.ALabel; end; procedure TOvcBorderParent.WMSetFocus(var Msg : TWMSetFocus); begin inherited; if (Assigned(FEdit)) then FEdit.SetFocus; end; procedure TOvcBorderParent.WMKillFocus(var Msg : TWMKillFocus); begin inherited; end; procedure TOvcBorderParent.LabelAttach(Sender : TObject; Value : Boolean); var {$IFDEF VERSION5} PF : TWinControl; {$ELSE} PF : TForm; {$ENDIF} S :string; begin if csLoading in ComponentState then Exit; {$IFDEF VERSION5} PF := GetImmediateParentForm(Self); {$ELSE} PF := TForm(GetParentForm(Self)); {$ENDIF} if Value then begin if Assigned(PF) then begin FLabelInfo.ALabel.Free; FLabelInfo.ALabel := TOvcAttachedLabel.CreateEx(PF, Self); FLabelInfo.ALabel.Parent := Parent; S := GenerateComponentName(PF, Name + 'Label'); FLabelInfo.ALabel.Name := S; FLabelInfo.ALabel.Caption := S; FLabelInfo.SetOffsets(0, 0); PositionLabel; FLabelInfo.ALabel.BringToFront; {turn off auto size} TLabel(FLabelInfo.ALabel).AutoSize := False; end; end else begin if Assigned(PF) then begin FLabelInfo.ALabel.Free; FLabelInfo.ALabel := nil; end; end; end; procedure TOvcBorderParent.LabelChange(Sender : TObject); begin if not (csLoading in ComponentState) then PositionLabel; end; procedure TOvcBorderParent.CreateWnd; begin inherited CreateWnd; end; procedure TOvcBorderParent.Notification(AComponent : TComponent; Operation: TOperation); var {$IFDEF VERSION5} PF : TWinControl; {$ELSE} PF : TForm; {$ENDIF} begin inherited Notification(AComponent, Operation); if Operation = opRemove then begin if Assigned(FLabelInfo) and (AComponent = FLabelInfo.ALabel) then begin {$IFDEF VERSION5} PF := GetImmediateParentForm(Self); {$ELSE} PF := TForm(GetParentForm(Self)); {$ENDIF} if Assigned(PF) and not (csDestroying in PF.ComponentState) then begin FLabelInfo.FVisible := False; FLabelInfo.ALabel := nil; end end; end; end; procedure TOvcBorderParent.OrAssignLabel(var Msg : TMessage); begin FLabelInfo.ALabel := TOvcAttachedLabel(Msg.lParam); end; procedure TOvcBorderParent.OrPositionLabel(var Msg : TMessage); const DX : Integer = 0; DY : Integer = 0; begin if FLabelInfo.Visible and Assigned(FLabelInfo.ALabel) and (FLabelInfo.ALabel.Parent <> nil) and not (csLoading in ComponentState) then begin if DefaultLabelPosition = lpTopLeft then begin DX := FLabelInfo.ALabel.Left - Left; DY := FLabelInfo.ALabel.Top + FLabelInfo.ALabel.Height - Top; end else begin DX := FLabelInfo.ALabel.Left - Left; DY := FLabelInfo.ALabel.Top - Top - Height; end; if (DX <> FLabelInfo.OffsetX) or (DY <> FLabelInfo.OffsetY) then PositionLabel; end; end; procedure TOvcBorderParent.OrRecordLabelPosition(var Msg : TMessage); begin if Assigned(FLabelInfo.ALabel) and (FLabelInfo.ALabel.Parent <> nil) then begin {if the label was cut and then pasted, this will complete the reattachment} FLabelInfo.FVisible := True; if DefaultLabelPosition = lpTopLeft then FLabelInfo.SetOffsets(FLabelInfo.ALabel.Left - Left, FLabelInfo.ALabel.Top + FLabelInfo.ALabel.Height - Top) else FLabelInfo.SetOffsets(FLabelInfo.ALabel.Left - Left, FLabelInfo.ALabel.Top - Top - Height); end; end; procedure TOvcBorderParent.PositionLabel; begin if FLabelInfo.Visible and Assigned(FLabelInfo.ALabel) and (FLabelInfo.ALabel.Parent <> nil) and not (csLoading in ComponentState) then begin if DefaultLabelPosition = lpTopLeft then begin FLabelInfo.ALabel.SetBounds(Left + FLabelInfo.OffsetX, FLabelInfo.OffsetY - FLabelInfo.ALabel.Height + Top, FLabelInfo.ALabel.Width, FLabelInfo.ALabel.Height); end else begin FLabelInfo.ALabel.SetBounds(Left + FLabelInfo.OffsetX, FLabelInfo.OffsetY + Top + Height, FLabelInfo.ALabel.Width, FLabelInfo.ALabel.Height); end; end; end; procedure TOvcBorderParent.SetBounds(ALeft, ATop, AWidth, AHeight : Integer); begin inherited SetBounds(ALeft, ATop, AWidth, AHeight); if not HandleAllocated then Exit; if HandleAllocated then PostMessage(Handle, OM_POSITIONLABEL, 0, 0); end; procedure TOvcBorderParent.SetEditControl(EC : TOvcCustomEdit); begin FEdit := EC; end; procedure TOvcBorderParent.Paint; begin PaintBorders; end; procedure TOvcBorderParent.PaintBorders; var R : TRect; C : TCanvas; W : integer; BW : integer; begin Height := FOrgHeight; C := Canvas; if DoShowButton then W := ButtonWidth + 4 else W := 0; if (FBorders.LeftBorder.Enabled) then FEdit.Left := FBorders.LeftBorder.PenWidth else FEdit.Left := 0; if (FBorders.TopBorder.Enabled) then FEdit.Top := FBorders.TopBorder.PenWidth else FEdit.Top := 0; if (not (FBorders.LeftBorder.Enabled or FBorders.RightBorder.Enabled)) then FEdit.Width := Width else begin BW := W; if (FBorders.LeftBorder.Enabled) then BW := FBorders.LeftBorder.PenWidth; if (FBorders.RightBorder.Enabled) then BW := BW + FBorders.RightBorder.PenWidth; FEdit.Width := Width - BW; end; if (not (FBorders.TopBorder.Enabled or FBorders.BottomBorder.Enabled)) then { Height := FEdit.Height} FEdit.Height := Height else begin BW := 0; if (FBorders.TopBorder.Enabled) then BW := FBorders.TopBorder.PenWidth; if (FBorders.BottomBorder.Enabled) then BW := BW + FBorders.BottomBorder.PenWidth; FEdit.Height := Height - BW; end; R.Left := 0; R.Top := 0; R.Right := Width; R.Bottom := Height; if (Assigned(FBorders.FLeftBorder)) then begin if (FBorders.LeftBorder.Enabled) then begin C.Pen.Color := FBorders.LeftBorder.PenColor; C.Pen.Width := FBorders.LeftBorder.PenWidth; C.Pen.Style := FBorders.LeftBorder.PenStyle; C.MoveTo(R.Left + (FBorders.LeftBorder.PenWidth div 2), R.Top); C.LineTo(R.Left + (FBorders.LeftBorder.PenWidth div 2), R.Bottom); end; end; if (Assigned(FBorders.FRightBorder)) then begin if (FBorders.RightBorder.Enabled) then begin C.Pen.Color := FBorders.RightBorder.PenColor; C.Pen.Width := FBorders.RightBorder.PenWidth; C.Pen.Style := FBorders.RightBorder.PenStyle; if ((FBorders.RightBorder.PenWidth mod 2) = 0) then begin C.MoveTo(R.Right - (FBorders.RightBorder.PenWidth div 2), R.Top); C.LineTo(R.Right - (FBorders.RightBorder.PenWidth div 2), R.Bottom); end else begin C.MoveTo(R.Right - (FBorders.RightBorder.PenWidth div 2) - 1, R.Top); C.LineTo(R.Right - (FBorders.RightBorder.PenWidth div 2) - 1, R.Bottom); end; end; end; if (Assigned(FBorders.FTopBorder)) then begin if (FBorders.TopBorder.Enabled) then begin C.Pen.Color := FBorders.TopBorder.PenColor; C.Pen.Width := FBorders.TopBorder.PenWidth; C.Pen.Style := FBorders.TopBorder.PenStyle; C.MoveTo(R.Left, R.Top + (FBorders.TopBorder.PenWidth div 2)); C.LineTo(R.Right, R.Top + (FBorders.TopBorder.PenWidth div 2)); end; end; if (Assigned(FBorders.FBottomBorder)) then begin if (FBorders.BottomBorder.Enabled) then begin C.Pen.Color := FBorders.BottomBorder.PenColor; C.Pen.Width := FBorders.BottomBorder.PenWidth; C.Pen.Style := FBorders.BottomBorder.PenStyle; if ((FBorders.BottomBorder.PenWidth mod 2) = 0) then begin C.MoveTo(R.Left, R.Bottom - (FBorders.BottomBorder.PenWidth div 2)); C.LineTo(R.Right - (FBorders.BottomBorder.PenWidth div 2), R.Bottom - (FBorders.BottomBorder.PenWidth div 2)); end else begin C.MoveTo(R.Left, R.Bottom - (FBorders.BottomBorder.PenWidth div 2) - 1); C.LineTo(R.Right, R.Bottom - (FBorders.BottomBorder.PenWidth div 2) - 1); end; end; end; if (Assigned(FEdit)) then FEdit.Refresh; ValidateRect(Handle, @R); end; end.