home *** CD-ROM | disk | FTP | other *** search
- unit Isamnav;
- {copyright 1995 by Norbert Stellberg GmbH}
- interface
-
- Uses Classes, WinProcs, WinTypes, ExtCtrls, Controls,
- IsamBrow, DbCtrls, Messages, Buttons;
-
- Type
- TIsamNavButton = class;
- TIsamNavigateBtn = (nbFirst, nbPrior, nbNext, nbLast,
- nbInsert, nbDelete);
- TIsamButtonSet = set of TIsamNavigateBtn;
-
- { tIsamNavigator }
-
- TIsamNavigator = class (TCustomPanel)
- {NAVIGATOR for isamtables, compatible with NAVIGATORS
- for IDAPI-driven tables.}
- private
- FBrowser: TIsamBrowser;
- FVisibleButtons: TIsamButtonSet;
- FHints: TStrings;
- ButtonWidth: Integer;
- MinBtnSize: TPoint;
- FOnNavClick: ENavClick;
- FocusedButton: TIsamNavigateBtn;
- FConfirmDelete: Boolean;
- procedure SetBrowser(Value: TIsamBrowser);
- procedure InitButtons;
- procedure InitHints;
- procedure Click(Sender: TObject);
- procedure BtnMouseDown (Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure SetVisible(Value: TIsamButtonSet);
- procedure AdjustSize (var W: Integer; var H: Integer);
- procedure SetHints(Value: TStrings);
- procedure WMSize(var Message: TWMSize); message WM_SIZE;
- procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
- procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
- procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
- procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
- protected
- Buttons: array[TIsamNavigateBtn] of tIsamNavButton;
- procedure DataChanged;
- procedure EditingChanged;
- procedure ActiveChanged;
- procedure Loaded; override;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure Notification(AComponent: TComponent;
- Operation: TOperation); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
- procedure BtnClick(Index: tIsamNavigateBtn);
- published
- property Browser: TIsamBrowser read FBrowser write SetBrowser;
- property VisibleButtons: TIsamButtonSet read FVisibleButtons write SetVisible
- default [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete];
- property Align;
- property DragCursor;
- property DragMode;
- property Enabled;
- property Ctl3D;
- property Hints: TStrings read FHints write SetHints;
- property ParentCtl3D;
- property ParentShowHint;
- property ConfirmDelete: Boolean read FConfirmDelete write FConfirmDelete default True;
- property ShowHint;
- property TabOrder;
- property TabStop;
- property Visible;
- property OnClick: ENavClick read FOnNavClick write FOnNavClick;
- property OnDblClick;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnEnter;
- property OnExit;
- property OnResize;
- end;
-
- { tIsamNavButton }
-
- tIsamNavButton = class(TSpeedButton)
- private
- FIndex: TIsamNavigateBtn;
- FNavStyle: tNavButtonStyle;
- FRepeatTimer: TTimer;
- procedure TimerExpired(Sender: TObject);
- protected
- procedure Paint; override;
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer); override;
- procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer); override;
- public
- destructor Destroy; override;
- property NavStyle: tNavButtonStyle read FNavStyle write FNavStyle;
- property Index : TIsamNavigateBtn read FIndex write FIndex;
- end;
-
- implementation
-
- Uses DbConsts, SysUtils, Forms, Dialogs;
-
- const
- BtnStateName: array[TNavGlyph] of PChar = ('EN', 'DI');
- BtnTypeName: array[TIsamNavigateBtn] of PChar = ('FIRST', 'PRIOR', 'NEXT',
- 'LAST', 'INSERT', 'DELETE');
- BtnHintId: array[TIsamNavigateBtn] of Word = (SFirstRecord, SPriorRecord,
- SNextRecord, SLastRecord, SInsertRecord, SDeleteRecord);
-
- constructor tIsamNavigator.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] +
- [csFramed, csOpaque];
- FVisibleButtons := [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete];
- FHints := TStringList.Create;
- InitButtons;
- BevelOuter := bvNone;
- BevelInner := bvNone;
- Width := 241;
- Height := 25;
- ButtonWidth := 0;
- FocusedButton := nbFirst;
- FConfirmDelete := True;
- end;
-
- destructor tIsamNavigator.Destroy;
- begin
- {FDataLink.Free;
- FDataLink := nil;}
- FHints.Free;
- inherited Destroy;
- end;
-
- procedure tIsamNavigator.InitButtons;
- var
- I: TIsamNavigateBtn;
- Btn: tIsamNavButton;
- X: Integer;
- ResName: array[0..40] of Char;
- begin
- MinBtnSize := Point(20, 18);
- X := 0;
- for I := Low(Buttons) to High(Buttons) do
- begin
- Btn := tIsamNavButton.Create (Self);
- Btn.Index := I;
- Btn.Visible := I in FVisibleButtons;
- Btn.Enabled := True;
- Btn.SetBounds (X, 0, MinBtnSize.X, MinBtnSize.Y);
- Btn.Glyph.Handle := LoadBitmap(HInstance,
- StrFmt(ResName, 'dbn_%s', [BtnTypeName[I]]));
- Btn.NumGlyphs := 2;
- Btn.OnClick := Click;
- Btn.OnMouseDown := BtnMouseDown;
- Btn.Parent := Self;
- Buttons[I] := Btn;
- X := X + MinBtnSize.X;
- end;
- InitHints;
- Buttons[nbPrior].NavStyle := Buttons[nbPrior].NavStyle + [nsAllowTimer];
- Buttons[nbNext].NavStyle := Buttons[nbNext].NavStyle + [nsAllowTimer];
- end;
-
- procedure tIsamNavigator.InitHints;
- var
- I: Integer;
- J: TIsamNavigateBtn;
- begin
- for J := Low(Buttons) to High(Buttons) do
- Buttons[J].Hint := LoadStr (BtnHintId[J]);
- J := Low(Buttons);
- for I := 0 to (FHints.Count - 1) do
- begin
- if FHints.Strings[I] <> '' then Buttons[J].Hint := FHints.Strings[I];
- if J = High(Buttons) then Exit;
- Inc(J);
- end;
- end;
-
- procedure tIsamNavigator.SetHints(Value: TStrings);
- begin
- FHints.Assign(Value);
- InitHints;
- end;
-
- procedure tIsamNavigator.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- {if (Operation = opRemove) and (FDataLink <> nil) and
- (AComponent = DataSource) then DataSource := nil;}
- end;
-
- procedure tIsamNavigator.DataChanged;
- begin
- end;
-
- procedure tIsamNavigator.EditingChanged;
- begin
- end;
-
- procedure tIsamNavigator.SetVisible(Value: TIsamButtonSet);
- var
- I: tIsamNavigateBtn;
- W, H: Integer;
- begin
- W := Width;
- H := Height;
- FVisibleButtons := Value;
- for I := Low(Buttons) to High(Buttons) do
- Buttons[I].Visible := I in FVisibleButtons;
- AdjustSize (W, H);
- if (W <> Width) or (H <> Height) then
- inherited SetBounds (Left, Top, W, H);
- Invalidate;
- end;
-
- procedure tIsamNavigator.AdjustSize (var W: Integer; var H: Integer);
- var
- Count: Integer;
- MinW: Integer;
- I: tIsamNavigateBtn;
- LastBtn: tIsamNavigateBtn;
- Space, Temp, Remain: Integer;
- X: Integer;
- begin
- if (csLoading in ComponentState) then Exit;
- if Buttons[nbFirst] = nil then Exit;
-
- Count := 0;
- LastBtn := High(Buttons);
- for I := Low(Buttons) to High(Buttons) do
- begin
- if Buttons[I].Visible then
- begin
- Inc(Count);
- LastBtn := I;
- end;
- end;
- if Count = 0 then Inc(Count);
-
- MinW := Count * (MinBtnSize.X - 1) + 1;
- if W < MinW then
- W := MinW;
- if H < MinBtnSize.Y then
- H := MinBtnSize.Y;
-
- ButtonWidth := ((W - 1) div Count) + 1;
- Temp := Count * (ButtonWidth - 1) + 1;
- if Align = alNone then
- W := Temp;
-
- X := 0;
- Remain := W - Temp;
- Temp := Count div 2;
- for I := Low(Buttons) to High(Buttons) do
- begin
- if Buttons[I].Visible then
- begin
- Space := 0;
- if Remain <> 0 then
- begin
- Dec (Temp, Remain);
- if Temp < 0 then
- begin
- Inc (Temp, Count);
- Space := 1;
- end;
- end;
- Buttons[I].SetBounds (X, 0, ButtonWidth + Space, Height);
- Inc (X, ButtonWidth - 1 + Space);
- LastBtn := I;
- end
- else
- Buttons[I].SetBounds (Width + 1, 0, ButtonWidth, Height);
- end;
- end;
-
- procedure tIsamNavigator.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
- var
- W, H: Integer;
- begin
- W := AWidth;
- H := AHeight;
- AdjustSize (W, H);
- inherited SetBounds (ALeft, ATop, W, H);
- end;
-
- procedure tIsamNavigator.WMSize(var Message: TWMSize);
- var
- W, H: Integer;
- begin
- inherited;
-
- { check for minimum size }
- W := Width;
- H := Height;
- AdjustSize (W, H);
- if (W <> Width) or (H <> Height) then
- inherited SetBounds(Left, Top, W, H);
- Message.Result := 0;
- end;
-
- procedure tIsamNavigator.Click(Sender: TObject);
- begin
- BtnClick (tIsamNavButton (Sender).Index);
- end;
-
- procedure tIsamNavigator.BtnMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- var
- OldFocus: tIsamNavigateBtn;
- Form: TForm;
- begin
- OldFocus := FocusedButton;
- FocusedButton := tIsamNavButton (Sender).Index;
- if TabStop and (GetFocus <> Handle) and CanFocus then
- begin
- SetFocus;
- if (GetFocus <> Handle) then
- Exit;
- end
- else if TabStop and (GetFocus = Handle) and (OldFocus <> FocusedButton) then
- begin
- Buttons[OldFocus].Invalidate;
- Buttons[FocusedButton].Invalidate;
- end;
- end;
-
- procedure tIsamNavigator.BtnClick(Index: tIsamNavigateBtn);
- begin
- if Assigned(FBrowser) then begin
- if Browser <> NIL then begin
- if Browser.Table <> NIL then with Browser do begin
- case Index of
- nbPrior: SendMessage(Browser.Handle, WM_KeyDown, vk_UP, 0);
- nbNext : SendMessage(Browser.Handle, WM_KeyDown, vk_Down, 0);
- nbFirst: SetAndupDateBrowserScreen('',0);
- nbLast : SetAndupdateBrowserScreen(#255,9999999);
- nbInsert: SendMessage(Browser.Handle, WM_KeyDown, vk_Insert, 0);
- nbDelete: begin
- if not FConfirmDelete or (MessageDlg (LoadStr(SDeleteRecordQuestion),
- mtConfirmation, mbOKCancel, 0) <> idCancel) then
- SendMessage(Browser.Handle, WM_KeyDown, vk_Delete, 0);
- end;
- end;
- end;
- end;
- end;
- if not (csDesigning in ComponentState) and Assigned(FOnNavClick) then {FOnNavClick(Self, Index)};
- end;
-
- procedure tIsamNavigator.WMSetFocus(var Message: TWMSetFocus);
- begin
- Buttons[FocusedButton].Invalidate;
- end;
-
- procedure tIsamNavigator.WMKillFocus(var Message: TWMKillFocus);
- begin
- Buttons[FocusedButton].Invalidate;
- end;
-
- procedure tIsamNavigator.KeyDown(var Key: Word; Shift: TShiftState);
- var
- NewFocus: tIsamNavigateBtn;
- OldFocus: tIsamNavigateBtn;
- begin
- OldFocus := FocusedButton;
- case Key of
- VK_RIGHT:
- begin
- NewFocus := FocusedButton;
- repeat
- if NewFocus < High(Buttons) then
- NewFocus := Succ(NewFocus);
- until (NewFocus = High(Buttons)) or (Buttons[NewFocus].Visible);
- if NewFocus <> FocusedButton then
- begin
- FocusedButton := NewFocus;
- Buttons[OldFocus].Invalidate;
- Buttons[FocusedButton].Invalidate;
- end;
- end;
- VK_LEFT:
- begin
- NewFocus := FocusedButton;
- repeat
- if NewFocus > Low(Buttons) then
- NewFocus := Pred(NewFocus);
- until (NewFocus = Low(Buttons)) or (Buttons[NewFocus].Visible);
- if NewFocus <> FocusedButton then
- begin
- FocusedButton := NewFocus;
- Buttons[OldFocus].Invalidate;
- Buttons[FocusedButton].Invalidate;
- end;
- end;
- VK_SPACE:
- begin
- if Buttons[FocusedButton].Enabled then
- Buttons[FocusedButton].Click;
- end;
- end;
- end;
-
- procedure tIsamNavigator.WMGetDlgCode(var Message: TWMGetDlgCode);
- begin
- Message.Result := DLGC_WANTARROWS;
- end;
-
- procedure tIsamNavigator.ActiveChanged;
- var
- I: tIsamNavigateBtn;
- begin
- if not (Enabled) then
- for I := Low(Buttons) to High(Buttons) do
- Buttons[I].Enabled := False
- else
- begin
- DataChanged;
- EditingChanged;
- end;
- end;
-
- procedure tIsamNavigator.CMEnabledChanged(var Message: TMessage);
- begin
- inherited;
- if not (csLoading in ComponentState) then
- ActiveChanged;
- end;
-
- procedure tIsamNavigator.Loaded;
- var
- W, H: Integer;
- begin
- inherited Loaded;
- W := Width;
- H := Height;
- AdjustSize (W, H);
- if (W <> Width) or (H <> Height) then
- inherited SetBounds (Left, Top, W, H);
- InitHints;
- ActiveChanged;
- end;
-
- Procedure tIsamNavigator.SetBrowser(Value: TIsamBrowser);
- begin
- FBrowser:= Value;
- end;
-
- {tIsamNavButton}
-
- destructor tIsamNavButton.Destroy;
- begin
- if FRepeatTimer <> nil then
- FRepeatTimer.Free;
- inherited Destroy;
- end;
-
- procedure tIsamNavButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- begin
- inherited MouseDown (Button, Shift, X, Y);
- if nsAllowTimer in FNavStyle then
- begin
- if FRepeatTimer = nil then
- FRepeatTimer := TTimer.Create(Self);
-
- FRepeatTimer.OnTimer := TimerExpired;
- FRepeatTimer.Interval := InitRepeatPause;
- FRepeatTimer.Enabled := True;
- end;
- end;
-
- procedure tIsamNavButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- begin
- inherited MouseUp (Button, Shift, X, Y);
- if FRepeatTimer <> nil then
- FRepeatTimer.Enabled := False;
- end;
-
- procedure tIsamNavButton.TimerExpired(Sender: TObject);
- begin
- FRepeatTimer.Interval := RepeatPause;
- if (FState = bsDown) and MouseCapture then
- begin
- try
- Click;
- except
- FRepeatTimer.Enabled := False;
- raise;
- end;
- end;
- end;
-
- procedure tIsamNavButton.Paint;
- var
- R: TRect;
- begin
- inherited Paint;
- if (GetFocus = Parent.Handle) and
- (FIndex = TIsamNavigator (Parent).FocusedButton) then
- begin
- R := Bounds(0, 0, Width, Height);
- InflateRect(R, -3, -3);
- if FState = bsDown then
- OffsetRect(R, 1, 1);
- DrawFocusRect(Canvas.Handle, R);
- end;
- end;
-
- end.
-