home *** CD-ROM | disk | FTP | other *** search
-
- {*******************************************************}
- { }
- { Turbo Pascal Version 7.0 }
- { Turbo Vision Unit }
- { }
- { Copyright (c) 1992 Borland International }
- { }
- {*******************************************************}
-
- unit Dialogs;
-
- {$O+,F+,X+,I-,S-}
-
- interface
-
- uses Objects, Drivers, Views, Validate;
-
- const
-
- { Color palettes }
-
- CGrayDialog = #32#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47 +
- #48#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63;
- CBlueDialog = #64#65#66#67#68#69#70#71#72#73#74#75#76#77#78#79 +
- #80#81#82#83#84#85#86#87#88#89#90#91#92#92#94#95;
- CCyanDialog = #96#97#98#99#100#101#102#103#104#105#106#107#108 +
- #109#110#111#112#113#114#115#116#117#118#119#120 +
- #121#122#123#124#125#126#127;
-
- CDialog = CGrayDialog;
-
- CStaticText = #6;
- CLabel = #7#8#9#9;
- CButton = #10#11#12#13#14#14#14#15;
- CCluster = #16#17#18#18#31;
- CInputLine = #19#19#20#21;
- CHistory = #22#23;
- CHistoryWindow = #19#19#21#24#25#19#20;
- CHistoryViewer = #6#6#7#6#6;
-
- { TDialog palette entires }
-
- dpBlueDialog = 0;
- dpCyanDialog = 1;
- dpGrayDialog = 2;
-
- { TButton flags }
-
- bfNormal = $00;
- bfDefault = $01;
- bfLeftJust = $02;
- bfBroadcast = $04;
- bfGrabFocus = $08;
-
- { TMultiCheckboxes flags }
- { hibyte = number of bits }
- { lobyte = bit mask }
-
- cfOneBit = $0101;
- cfTwoBits = $0203;
- cfFourBits = $040F;
- cfEightBits = $08FF;
-
- type
-
- { TDialog object }
-
- { Palette layout }
- { 1 = Frame passive }
- { 2 = Frame active }
- { 3 = Frame icon }
- { 4 = ScrollBar page area }
- { 5 = ScrollBar controls }
- { 6 = StaticText }
- { 7 = Label normal }
- { 8 = Label selected }
- { 9 = Label shortcut }
- { 10 = Button normal }
- { 11 = Button default }
- { 12 = Button selected }
- { 13 = Button disabled }
- { 14 = Button shortcut }
- { 15 = Button shadow }
- { 16 = Cluster normal }
- { 17 = Cluster selected }
- { 18 = Cluster shortcut }
- { 19 = InputLine normal text }
- { 20 = InputLine selected text }
- { 21 = InputLine arrows }
- { 22 = History arrow }
- { 23 = History sides }
- { 24 = HistoryWindow scrollbar page area }
- { 25 = HistoryWindow scrollbar controls }
- { 26 = ListViewer normal }
- { 27 = ListViewer focused }
- { 28 = ListViewer selected }
- { 29 = ListViewer divider }
- { 30 = InfoPane }
- { 31 = Cluster disabled }
- { 32 = Reserved }
-
- PDialog = ^TDialog;
- TDialog = object(TWindow)
- constructor Init(var Bounds: TRect; ATitle: TTitleStr);
- constructor Load(var S: TStream);
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- function Valid(Command: Word): Boolean; virtual;
- end;
-
- { TSItem }
-
- PSItem = ^TSItem;
- TSItem = record
- Value: PString;
- Next: PSItem;
- end;
-
- { TInputLine object }
-
- { Palette layout }
- { 1 = Passive }
- { 2 = Active }
- { 3 = Selected }
- { 4 = Arrows }
-
- PInputLine = ^TInputLine;
- TInputLine = object(TView)
- Data: PString;
- MaxLen: Integer;
- CurPos: Integer;
- FirstPos: Integer;
- SelStart: Integer;
- SelEnd: Integer;
- Validator: PValidator;
- constructor Init(var Bounds: TRect; AMaxLen: Integer);
- constructor Load(var S: TStream);
- destructor Done; virtual;
- function DataSize: Word; virtual;
- procedure Draw; virtual;
- procedure GetData(var Rec); virtual;
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- procedure SelectAll(Enable: Boolean);
- procedure SetData(var Rec); virtual;
- procedure SetState(AState: Word; Enable: Boolean); virtual;
- procedure SetValidator(AValid: PValidator);
- procedure Store(var S: TStream);
- function Valid(Command: Word): Boolean; virtual;
- private
- function CanScroll(Delta: Integer): Boolean;
- end;
-
- { TButton object }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Default text }
- { 3 = Selected text }
- { 4 = Disabled text }
- { 5 = Normal shortcut }
- { 6 = Default shortcut }
- { 7 = Selected shortcut }
- { 8 = Shadow }
-
- PButton = ^TButton;
- TButton = object(TView)
- Title: PString;
- Command: Word;
- Flags: Byte;
- AmDefault: Boolean;
- constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACommand: Word;
- AFlags: Word);
- constructor Load(var S: TStream);
- destructor Done; virtual;
- procedure Draw; virtual;
- procedure DrawState(Down: Boolean);
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- procedure MakeDefault(Enable: Boolean);
- procedure Press; virtual;
- procedure SetState(AState: Word; Enable: Boolean); virtual;
- procedure Store(var S: TStream);
- end;
-
- { TCluster }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Selected text }
- { 3 = Normal shortcut }
- { 4 = Selected shortcut }
- { 5 = Disabled text }
-
- PCluster = ^TCluster;
- TCluster = object(TView)
- Value: LongInt;
- Sel: Integer;
- EnableMask: LongInt;
- Strings: TStringCollection;
- constructor Init(var Bounds: TRect; AStrings: PSItem);
- constructor Load(var S: TStream);
- destructor Done; virtual;
- function ButtonState(Item: Integer): Boolean;
- function DataSize: Word; virtual;
- procedure DrawBox(const Icon: String; Marker: Char);
- procedure DrawMultiBox(const Icon, Marker: String);
- procedure GetData(var Rec); virtual;
- function GetHelpCtx: Word; virtual;
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- function Mark(Item: Integer): Boolean; virtual;
- function MultiMark(Item: Integer): Byte; virtual;
- procedure Press(Item: Integer); virtual;
- procedure MovedTo(Item: Integer); virtual;
- procedure SetButtonState(AMask: Longint; Enable: Boolean);
- procedure SetData(var Rec); virtual;
- procedure SetState(AState: Word; Enable: Boolean); virtual;
- procedure Store(var S: TStream);
- private
- function Column(Item: Integer): Integer;
- function FindSel(P: TPoint): Integer;
- function Row(Item: Integer): Integer;
- end;
-
- { TRadioButtons }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Selected text }
- { 3 = Normal shortcut }
- { 4 = Selected shortcut }
-
- PRadioButtons = ^TRadioButtons;
- TRadioButtons = object(TCluster)
- procedure Draw; virtual;
- function Mark(Item: Integer): Boolean; virtual;
- procedure MovedTo(Item: Integer); virtual;
- procedure Press(Item: Integer); virtual;
- procedure SetData(var Rec); virtual;
- end;
-
- { TCheckBoxes }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Selected text }
- { 3 = Normal shortcut }
- { 4 = Selected shortcut }
-
- PCheckBoxes = ^TCheckBoxes;
- TCheckBoxes = object(TCluster)
- procedure Draw; virtual;
- function Mark(Item: Integer): Boolean; virtual;
- procedure Press(Item: Integer); virtual;
- end;
-
- { TMultiCheckBoxes }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Selected text }
- { 3 = Normal shortcut }
- { 4 = Selected shortcut }
-
- PMultiCheckBoxes = ^TMultiCheckBoxes;
- TMultiCheckBoxes = object(TCluster)
- SelRange: Byte;
- Flags: Word;
- States: PString;
- constructor Init(var Bounds: TRect; AStrings: PSItem;
- ASelRange: Byte; AFlags: Word; const AStates: String);
- constructor Load(var S: TStream);
- destructor Done; virtual;
- function DataSize: Word; virtual;
- procedure Draw; virtual;
- procedure GetData(var Rec); virtual;
- function MultiMark(Item: Integer): Byte; virtual;
- procedure Press(Item: Integer); virtual;
- procedure SetData(var Rec); virtual;
- procedure Store(var S: TStream);
- end;
-
- { TListBox }
-
- { Palette layout }
- { 1 = Active }
- { 2 = Inactive }
- { 3 = Focused }
- { 4 = Selected }
- { 5 = Divider }
-
- PListBox = ^TListBox;
- TListBox = object(TListViewer)
- List: PCollection;
- constructor Init(var Bounds: TRect; ANumCols: Word;
- AScrollBar: PScrollBar);
- constructor Load(var S: TStream);
- function DataSize: Word; virtual;
- procedure GetData(var Rec); virtual;
- function GetText(Item: Integer; MaxLen: Integer): String; virtual;
- procedure NewList(AList: PCollection); virtual;
- procedure SetData(var Rec); virtual;
- procedure Store(var S: TStream);
- end;
-
- { TStaticText }
-
- { Palette layout }
- { 1 = Text }
-
- PStaticText = ^TStaticText;
- TStaticText = object(TView)
- Text: PString;
- constructor Init(var Bounds: TRect; const AText: String);
- constructor Load(var S: TStream);
- destructor Done; virtual;
- procedure Draw; virtual;
- function GetPalette: PPalette; virtual;
- procedure GetText(var S: String); virtual;
- procedure Store(var S: TStream);
- end;
-
- { TParamText }
-
- { Palette layout }
- { 1 = Text }
-
- PParamText = ^TParamText;
- TParamText = object(TStaticText)
- ParamCount: Integer;
- ParamList: Pointer;
- constructor Init(var Bounds: TRect; const AText: String;
- AParamCount: Integer);
- constructor Load(var S: TStream);
- function DataSize: Word; virtual;
- procedure GetText(var S: String); virtual;
- procedure SetData(var Rec); virtual;
- procedure Store(var S: TStream);
- end;
-
- { TLabel }
-
- { Palette layout }
- { 1 = Normal text }
- { 2 = Selected text }
- { 3 = Normal shortcut }
- { 4 = Selected shortcut }
-
- PLabel = ^TLabel;
- TLabel = object(TStaticText)
- Link: PView;
- Light: Boolean;
- constructor Init(var Bounds: TRect; const AText: String; ALink: PView);
- constructor Load(var S: TStream);
- procedure Draw; virtual;
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- procedure Store(var S: TStream);
- end;
-
- { THistoryViewer }
-
- { Palette layout }
- { 1 = Active }
- { 2 = Inactive }
- { 3 = Focused }
- { 4 = Selected }
- { 5 = Divider }
-
- PHistoryViewer = ^THistoryViewer;
- THistoryViewer = object(TListViewer)
- HistoryId: Word;
- constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
- AHistoryId: Word);
- function GetPalette: PPalette; virtual;
- function GetText(Item: Integer; MaxLen: Integer): String; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- function HistoryWidth: Integer;
- end;
-
- { THistoryWindow }
-
- { Palette layout }
- { 1 = Frame passive }
- { 2 = Frame active }
- { 3 = Frame icon }
- { 4 = ScrollBar page area }
- { 5 = ScrollBar controls }
- { 6 = HistoryViewer normal text }
- { 7 = HistoryViewer selected text }
-
- PHistoryWindow = ^THistoryWindow;
- THistoryWindow = object(TWindow)
- Viewer: PListViewer;
- constructor Init(var Bounds: TRect; HistoryId: Word);
- function GetPalette: PPalette; virtual;
- function GetSelection: String; virtual;
- procedure InitViewer(HistoryId: Word); virtual;
- end;
-
- { THistory }
-
- { Palette layout }
- { 1 = Arrow }
- { 2 = Sides }
-
- PHistory = ^THistory;
- THistory = object(TView)
- Link: PInputLine;
- HistoryId: Word;
- constructor Init(var Bounds: TRect; ALink: PInputLine; AHistoryId: Word);
- constructor Load(var S: TStream);
- procedure Draw; virtual;
- function GetPalette: PPalette; virtual;
- procedure HandleEvent(var Event: TEvent); virtual;
- function InitHistoryWindow(var Bounds: TRect): PHistoryWindow; virtual;
- procedure RecordHistory(const S: String); virtual;
- procedure Store(var S: TStream);
- end;
-
- { SItem routines }
-
- function NewSItem(const Str: String; ANext: PSItem): PSItem;
-
- { Dialogs registration procedure }
-
- procedure RegisterDialogs;
-
- { Stream Registration Records }
-
- const
- RDialog: TStreamRec = (
- ObjType: 10;
- VmtLink: Ofs(TypeOf(TDialog)^);
- Load: @TDialog.Load;
- Store: @TDialog.Store
- );
-
- const
- RInputLine: TStreamRec = (
- ObjType: 11;
- VmtLink: Ofs(TypeOf(TInputLine)^);
- Load: @TInputLine.Load;
- Store: @TInputLine.Store
- );
-
- const
- RButton: TStreamRec = (
- ObjType: 12;
- VmtLink: Ofs(TypeOf(TButton)^);
- Load: @TButton.Load;
- Store: @TButton.Store
- );
-
- const
- RCluster: TStreamRec = (
- ObjType: 13;
- VmtLink: Ofs(TypeOf(TCluster)^);
- Load: @TCluster.Load;
- Store: @TCluster.Store
- );
-
- const
- RRadioButtons: TStreamRec = (
- ObjType: 14;
- VmtLink: Ofs(TypeOf(TRadioButtons)^);
- Load: @TRadioButtons.Load;
- Store: @TRadioButtons.Store
- );
-
- const
- RCheckBoxes: TStreamRec = (
- ObjType: 15;
- VmtLink: Ofs(TypeOf(TCheckBoxes)^);
- Load: @TCheckBoxes.Load;
- Store: @TCheckBoxes.Store
- );
-
- const
- RMultiCheckBoxes: TStreamRec = (
- ObjType: 27;
- VmtLink: Ofs(TypeOf(TMultiCheckBoxes)^);
- Load: @TMultiCheckBoxes.Load;
- Store: @TMultiCheckBoxes.Store
- );
-
- const
- RListBox: TStreamRec = (
- ObjType: 16;
- VmtLink: Ofs(TypeOf(TListBox)^);
- Load: @TListBox.Load;
- Store: @TListBox.Store
- );
-
- const
- RStaticText: TStreamRec = (
- ObjType: 17;
- VmtLink: Ofs(TypeOf(TStaticText)^);
- Load: @TStaticText.Load;
- Store: @TStaticText.Store
- );
-
- const
- RLabel: TStreamRec = (
- ObjType: 18;
- VmtLink: Ofs(TypeOf(TLabel)^);
- Load: @TLabel.Load;
- Store: @TLabel.Store
- );
-
- const
- RHistory: TStreamRec = (
- ObjType: 19;
- VmtLink: Ofs(TypeOf(THistory)^);
- Load: @THistory.Load;
- Store: @THistory.Store
- );
-
- const
- RParamText: TStreamRec = (
- ObjType: 20;
- VmtLink: Ofs(TypeOf(TParamText)^);
- Load: @TParamText.Load;
- Store: @TParamText.Store
- );
-
- const
-
- { Dialog broadcast commands }
-
- cmRecordHistory = 60;
-
- implementation
-
- uses HistList;
-
- const
-
- { TButton messages }
-
- cmGrabDefault = 61;
- cmReleaseDefault = 62;
-
- { Utility functions }
-
- function IsBlank(Ch: Char): Boolean;
- begin
- IsBlank := (Ch = ' ') or (Ch = #13) or (Ch = #10);
- end;
-
- { TDialog }
-
- constructor TDialog.Init(var Bounds: TRect; ATitle: TTitleStr);
- begin
- inherited Init(Bounds, ATitle, wnNoNumber);
- Options := Options or ofVersion20;
- GrowMode := 0;
- Flags := wfMove + wfClose;
- Palette := dpGrayDialog;
- end;
-
- constructor TDialog.Load(var S: TStream);
- begin
- inherited Load(S);
- if Options and ofVersion = ofVersion10 then
- begin
- Palette := dpGrayDialog;
- Inc(Options, ofVersion20);
- end;
- end;
-
- function TDialog.GetPalette: PPalette;
- const
- P: array[dpBlueDialog..dpGrayDialog] of string[Length(CBlueDialog)] =
- (CBlueDialog, CCyanDialog, CGrayDialog);
- begin
- GetPalette := @P[Palette];
- end;
-
- procedure TDialog.HandleEvent(var Event: TEvent);
- begin
- TWindow.HandleEvent(Event);
- case Event.What of
- evKeyDown:
- case Event.KeyCode of
- kbEsc:
- begin
- Event.What := evCommand;
- Event.Command := cmCancel;
- Event.InfoPtr := nil;
- PutEvent(Event);
- ClearEvent(Event);
- end;
- kbEnter:
- begin
- Event.What := evBroadcast;
- Event.Command := cmDefault;
- Event.InfoPtr := nil;
- PutEvent(Event);
- ClearEvent(Event);
- end;
- end;
- evCommand:
- case Event.Command of
- cmOk, cmCancel, cmYes, cmNo:
- if State and sfModal <> 0 then
- begin
- EndModal(Event.Command);
- ClearEvent(Event);
- end;
- end;
- end;
- end;
-
- function TDialog.Valid(Command: Word): Boolean;
- begin
- if Command = cmCancel then Valid := True
- else Valid := TGroup.Valid(Command);
- end;
-
- function NewSItem(const Str: String; ANext: PSItem): PSItem;
- var
- Item: PSItem;
- begin
- New(Item);
- Item^.Value := NewStr(Str);
- Item^.Next := ANext;
- NewSItem := Item;
- end;
-
- function Max(A, B: Integer): Integer;
- inline(
- $58/ {pop ax }
- $5B/ {pop bx }
- $3B/$C3/ {cmp ax,bx}
- $7F/$01/ {jg @@1 }
- $93); {xchg ax,bx}
- {@@1: }
-
- function HotKey(const S: String): Char;
- var
- P: Word;
- begin
- P := Pos('~',S);
- if P <> 0 then HotKey := UpCase(S[P+1])
- else HotKey := #0;
- end;
-
- { TInputLine }
-
- constructor TInputLine.Init(var Bounds: TRect; AMaxLen: Integer);
- begin
- TView.Init(Bounds);
- State := State or sfCursorVis;
- Options := Options or (ofSelectable + ofFirstClick + ofVersion20);
- GetMem(Data, AMaxLen + 1);
- Data^ := '';
- MaxLen := AMaxLen;
- end;
-
- constructor TInputLine.Load(var S: TStream);
- begin
- TView.Load(S);
- S.Read(MaxLen, SizeOf(Integer) * 5);
- GetMem(Data, MaxLen + 1);
- S.Read(Data^[0], 1);
- S.Read(Data^[1], Length(Data^));
- if Options and ofVersion >= ofVersion20 then
- Validator := PValidator(S.Get);
- Options := Options or ofVersion20;
- end;
-
- destructor TInputLine.Done;
- begin
- FreeMem(Data, MaxLen + 1);
- SetValidator(nil);
- TView.Done;
- end;
-
- function TInputLine.CanScroll(Delta: Integer): Boolean;
- begin
- if Delta < 0 then
- CanScroll := FirstPos > 0 else
- if Delta > 0 then
- CanScroll := Length(Data^) - FirstPos + 2 > Size.X else
- CanScroll := False;
- end;
-
- function TInputLine.DataSize: Word;
- var
- DSize: Word;
- begin
- DSize := 0;
-
- if Validator <> nil then
- DSize := Validator^.Transfer(Data^, nil, vtDataSize);
-
- if DSize <> 0 then
- DataSize := DSize
- else
- DataSize := MaxLen + 1;
- end;
-
- procedure TInputLine.Draw;
- var
- Color: Byte;
- L, R: Integer;
- B: TDrawBuffer;
- begin
- if State and sfFocused = 0 then
- Color := GetColor(1) else
- Color := GetColor(2);
- MoveChar(B, ' ', Color, Size.X);
- MoveStr(B[1], Copy(Data^, FirstPos + 1, Size.X - 2), Color);
- if CanScroll(1) then MoveChar(B[Size.X - 1], #16, GetColor(4), 1);
- if State and sfFocused <> 0 then
- begin
- if CanScroll(-1) then MoveChar(B[0], #17, GetColor(4), 1);
- L := SelStart - FirstPos;
- R := SelEnd - FirstPos;
- if L < 0 then L := 0;
- if R > Size.X - 2 then R := Size.X - 2;
- if L < R then MoveChar(B[L + 1], #0, GetColor(3), R - L);
- end;
- WriteLine(0, 0, Size.X, Size.Y, B);
- SetCursor(CurPos - FirstPos + 1, 0);
- end;
-
- procedure TInputLine.GetData(var Rec);
- begin
- if (Validator = nil) or
- (Validator^.Transfer(Data^, @Rec, vtGetData) = 0) then
- begin
- FillChar(Rec, DataSize, #0);
- Move(Data^, Rec, Length(Data^) + 1);
- end;
- end;
-
- function TInputLine.GetPalette: PPalette;
- const
- P: String[Length(CInputLine)] = CInputLine;
- begin
- GetPalette := @P;
- end;
-
- procedure TInputLine.HandleEvent(var Event: TEvent);
- const
- PadKeys = [$47, $4B, $4D, $4F, $73, $74];
- var
- Delta, Anchor, I: Integer;
- ExtendBlock: Boolean;
- OldData: string;
- OldCurPos, OldFirstPos,
- OldSelStart, OldSelEnd: Integer;
- WasAppending: Boolean;
-
- function MouseDelta: Integer;
- var
- Mouse: TPoint;
- begin
- MakeLocal(Event.Where, Mouse);
- if Mouse.X <= 0 then MouseDelta := -1 else
- if Mouse.X >= Size.X - 1 then MouseDelta := 1 else
- MouseDelta := 0;
- end;
-
- function MousePos: Integer;
- var
- Pos: Integer;
- Mouse: TPoint;
- begin
- MakeLocal(Event.Where, Mouse);
- if Mouse.X < 1 then Mouse.X := 1;
- Pos := Mouse.X + FirstPos - 1;
- if Pos < 0 then Pos := 0;
- if Pos > Length(Data^) then Pos := Length(Data^);
- MousePos := Pos;
- end;
-
- procedure DeleteSelect;
- begin
- if SelStart <> SelEnd then
- begin
- Delete(Data^, SelStart + 1, SelEnd - SelStart);
- CurPos := SelStart;
- end;
- end;
-
- procedure AdjustSelectBlock;
- begin
- if CurPos < Anchor then
- begin
- SelStart := CurPos;
- SelEnd := Anchor;
- end else
- begin
- SelStart := Anchor;
- SelEnd := CurPos;
- end;
- end;
-
- procedure SaveState;
- begin
- if Validator <> nil then
- begin
- OldData := Data^;
- OldCurPos := CurPos;
- OldFirstPos := FirstPos;
- OldSelStart := SelStart;
- OldSelEnd := SelEnd;
- WasAppending := Length(Data^) = CurPos;
- end;
- end;
-
- procedure RestoreState;
- begin
- if Validator <> nil then
- begin
- Data^ := OldData;
- CurPos := OldCurPos;
- FirstPos := OldFirstPos;
- SelStart := OldSelStart;
- SelEnd := OldSelEnd;
- end;
- end;
-
- function CheckValid(NoAutoFill: Boolean): Boolean;
- var
- OldLen: Integer;
- NewData: String;
- begin
- if Validator <> nil then
- begin
- CheckValid := False;
- OldLen := Length(Data^);
- if (Validator^.Options and voOnAppend = 0) or
- (WasAppending and (CurPos = OldLen)) then
- begin
- NewData := Data^;
- if not Validator^.IsValidInput(NewData, NoAutoFill) then
- RestoreState
- else
- begin
- if Length(NewData) > MaxLen then NewData[0] := Char(MaxLen);
- Data^ := NewData;
- if (CurPos >= OldLen) and (Length(Data^) > OldLen) then
- CurPos := Length(Data^);
- CheckValid := True;
- end;
- end
- else
- begin
- CheckValid := True;
- if CurPos = OldLen then
- if not Validator^.IsValidInput(Data^, False) then
- begin
- Validator^.Error;
- CheckValid := False;
- end;
- end;
- end
- else
- CheckValid := True;
- end;
-
- begin
- TView.HandleEvent(Event);
- if State and sfSelected <> 0 then
- begin
- case Event.What of
- evMouseDown:
- begin
- Delta := MouseDelta;
- if CanScroll(Delta) then
- begin
- repeat
- if CanScroll(Delta) then
- begin
- Inc(FirstPos, Delta);
- DrawView;
- end;
- until not MouseEvent(Event, evMouseAuto);
- end else
- if Event.Double then SelectAll(True) else
- begin
- Anchor := MousePos;
- repeat
- if Event.What = evMouseAuto then
- begin
- Delta := MouseDelta;
- if CanScroll(Delta) then Inc(FirstPos, Delta);
- end;
- CurPos := MousePos;
- AdjustSelectBlock;
- DrawView;
- until not MouseEvent(Event, evMouseMove + evMouseAuto);
- end;
- ClearEvent(Event);
- end;
- evKeyDown:
- begin
- SaveState;
- Event.KeyCode := CtrlToArrow(Event.KeyCode);
- if (Event.ScanCode in PadKeys) and
- (GetShiftState and $03 <> 0) then
- begin
- Event.CharCode := #0;
- if CurPos = SelEnd then Anchor := SelStart
- else Anchor := SelEnd;
- ExtendBlock := True;
- end
- else
- ExtendBlock := False;
- case Event.KeyCode of
- kbLeft:
- if CurPos > 0 then Dec(CurPos);
- kbRight:
- if CurPos < Length(Data^) then
- begin
- Inc(CurPos);
- CheckValid(True);
- end;
- kbHome:
- CurPos := 0;
- kbEnd:
- begin
- CurPos := Length(Data^);
- CheckValid(True);
- end;
- kbBack:
- if CurPos > 0 then
- begin
- Delete(Data^, CurPos, 1);
- Dec(CurPos);
- if FirstPos > 0 then Dec(FirstPos);
- CheckValid(True);
- end;
- kbDel:
- begin
- if SelStart = SelEnd then
- if CurPos < Length(Data^) then
- begin
- SelStart := CurPos;
- SelEnd := CurPos + 1;
- end;
- DeleteSelect;
- CheckValid(True);
- end;
- kbIns:
- SetState(sfCursorIns, State and sfCursorIns = 0);
- else
- case Event.CharCode of
- ' '..#255:
- begin
- if State and sfCursorIns <> 0 then
- Delete(Data^, CurPos + 1, 1) else DeleteSelect;
- if CheckValid(True) then
- begin
- if Length(Data^) < MaxLen then
- begin
- if FirstPos > CurPos then FirstPos := CurPos;
- Inc(CurPos);
- Insert(Event.CharCode, Data^, CurPos);
- end;
- CheckValid(False);
- end;
- end;
- ^Y:
- begin
- Data^ := '';
- CurPos := 0;
- end;
- else
- Exit;
- end
- end;
- if ExtendBlock then
- AdjustSelectBlock
- else
- begin
- SelStart := CurPos;
- SelEnd := CurPos;
- end;
- if FirstPos > CurPos then FirstPos := CurPos;
- I := CurPos - Size.X + 2;
- if FirstPos < I then FirstPos := I;
- DrawView;
- ClearEvent(Event);
- end;
- end;
- end;
- end;
-
- procedure TInputLine.SelectAll(Enable: Boolean);
- begin
- CurPos := 0;
- FirstPos := 0;
- SelStart := 0;
- if Enable then SelEnd := Length(Data^) else SelEnd := 0;
- DrawView;
- end;
-
- procedure TInputLine.SetData(var Rec);
- begin
- if (Validator = nil) or
- (Validator^.Transfer(Data^, @Rec, vtSetData) = 0) then
- Move(Rec, Data^[0], DataSize);
-
- SelectAll(True);
- end;
-
- procedure TInputLine.SetState(AState: Word; Enable: Boolean);
- begin
- TView.SetState(AState, Enable);
- if (AState = sfSelected) or ((AState = sfActive) and
- (State and sfSelected <> 0)) then
- SelectAll(Enable)
- else if AState = sfFocused then
- DrawView;
- end;
-
- procedure TInputLine.SetValidator(AValid: PValidator);
- begin
- if Validator <> nil then Validator^.Free;
- Validator := AValid;
- end;
-
- procedure TInputLine.Store(var S: TStream);
- begin
- TView.Store(S);
- S.Write(MaxLen, SizeOf(Integer) * 5);
- S.WriteStr(Data);
- S.Put(Validator);
- end;
-
- function TInputLine.Valid(Command: Word): Boolean;
- begin
- Valid := inherited Valid(Command);
- if (Validator <> nil) and (State and sfDisabled = 0) then
- if Command = cmValid then
- Valid := Validator^.Status = vsOk
- else if Command <> cmCancel then
- if not Validator^.Valid(Data^) then
- begin
- Select;
- Valid := False;
- end;
- end;
-
- { TButton }
-
- constructor TButton.Init(var Bounds: TRect; ATitle: TTitleStr;
- ACommand: Word; AFlags: Word);
- begin
- TView.Init(Bounds);
- Options := Options or (ofSelectable + ofFirstClick +
- ofPreProcess + ofPostProcess);
- EventMask := EventMask or evBroadcast;
- if not CommandEnabled(ACommand) then State := State or sfDisabled;
- Flags := AFlags;
- if AFlags and bfDefault <> 0 then AmDefault := True
- else AmDefault := False;
- Title := NewStr(ATitle);
- Command := ACommand;
- end;
-
- constructor TButton.Load(var S: TStream);
- begin
- TView.Load(S);
- Title := S.ReadStr;
- S.Read(Command, SizeOf(Word) + SizeOf(Byte) + SizeOf(Boolean));
- if not CommandEnabled(Command) then State := State or sfDisabled
- else State := State and not sfDisabled;
- end;
-
- destructor TButton.Done;
- begin
- DisposeStr(Title);
- TView.Done;
- end;
-
- procedure TButton.Draw;
- begin
- DrawState(False);
- end;
-
- procedure TButton.DrawState(Down: Boolean);
- var
- CButton, CShadow: Word;
- Ch: Char;
- I, S, Y, T: Integer;
- B: TDrawBuffer;
-
- procedure DrawTitle;
- var
- L, SCOff: Integer;
- begin
- if Flags and bfLeftJust <> 0 then L := 1 else
- begin
- L := (S - CStrLen(Title^) - 1) div 2;
- if L < 1 then L := 1;
- end;
- MoveCStr(B[I + L], Title^, CButton);
- if ShowMarkers and not Down then
- begin
- if State and sfSelected <> 0 then SCOff := 0 else
- if AmDefault then SCOff := 2 else SCOff := 4;
- WordRec(B[0]).Lo := Byte(SpecialChars[SCOff]);
- WordRec(B[S]).Lo := Byte(SpecialChars[SCOff + 1]);
- end;
- end;
-
- begin
- if State and sfDisabled <> 0 then CButton := GetColor($0404) else
- begin
- CButton := GetColor($0501);
- if State and sfActive <> 0 then
- if State and sfSelected <> 0 then CButton := GetColor($0703) else
- if AmDefault then CButton := GetColor($0602);
- end;
- CShadow := GetColor(8);
- S := Size.X - 1;
- T := Size.Y div 2 - 1;
- for Y := 0 to Size.Y - 2 do
- begin
- MoveChar(B, ' ', Byte(CButton), Size.X);
- WordRec(B[0]).Hi := CShadow;
- if Down then
- begin
- WordRec(B[1]).Hi := CShadow;
- Ch := ' ';
- I := 2;
- end else
- begin
- WordRec(B[S]).Hi := Byte(CShadow);
- if ShowMarkers then Ch := ' ' else
- begin
- if Y = 0 then
- WordRec(B[S]).Lo := Byte('▄') else
- WordRec(B[S]).Lo := Byte('█');
- Ch := '▀';
- end;
- I := 1;
- end;
- if (Y = T) and (Title <> nil) then DrawTitle;
- if ShowMarkers and not Down then
- begin
- WordRec(B[1]).Lo := Byte('[');
- WordRec(B[S - 1]).Lo := Byte(']');
- end;
- WriteLine(0, Y, Size.X, 1, B);
- end;
- MoveChar(B[0], ' ', Byte(CShadow), 2);
- MoveChar(B[2], Ch, Byte(CShadow), S - 1);
- WriteLine(0, Size.Y - 1, Size.X, 1, B);
- end;
-
- function TButton.GetPalette: PPalette;
- const
- P: String[Length(CButton)] = CButton;
- begin
- GetPalette := @P;
- end;
-
- procedure TButton.HandleEvent(var Event: TEvent);
- var
- Down: Boolean;
- C: Char;
- Mouse: TPoint;
- ClickRect: TRect;
- begin
- GetExtent(ClickRect);
- Inc(ClickRect.A.X);
- Dec(ClickRect.B.X);
- Dec(ClickRect.B.Y);
- if Event.What = evMouseDown then
- begin
- MakeLocal(Event.Where, Mouse);
- if not ClickRect.Contains(Mouse) then ClearEvent(Event);
- end;
- if Flags and bfGrabFocus <> 0 then
- TView.HandleEvent(Event);
- case Event.What of
- evMouseDown:
- begin
- if State and sfDisabled = 0 then
- begin
- Inc(ClickRect.B.X);
- Down := False;
- repeat
- MakeLocal(Event.Where, Mouse);
- if Down <> ClickRect.Contains(Mouse) then
- begin
- Down := not Down;
- DrawState(Down);
- end;
- until not MouseEvent(Event, evMouseMove);
- if Down then
- begin
- Press;
- DrawState(False);
- end;
- end;
- ClearEvent(Event);
- end;
- evKeyDown:
- begin
- C := HotKey(Title^);
- if (Event.KeyCode = GetAltCode(C)) or
- (Owner^.Phase = phPostProcess) and (C <> #0) and
- (Upcase(Event.CharCode) = C) or
- (State and sfFocused <> 0) and (Event.CharCode = ' ') then
- begin
- Press;
- ClearEvent(Event);
- end;
- end;
- evBroadcast:
- case Event.Command of
- cmDefault:
- if AmDefault then
- begin
- Press;
- ClearEvent(Event);
- end;
- cmGrabDefault, cmReleaseDefault:
- if Flags and bfDefault <> 0 then
- begin
- AmDefault := Event.Command = cmReleaseDefault;
- DrawView;
- end;
- cmCommandSetChanged:
- begin
- SetState(sfDisabled, not CommandEnabled(Command));
- DrawView;
- end;
- end;
- end;
- end;
-
- procedure TButton.MakeDefault(Enable: Boolean);
- var
- C: Word;
- begin
- if Flags and bfDefault = 0 then
- begin
- if Enable then C := cmGrabDefault else C := cmReleaseDefault;
- Message(Owner, evBroadcast, C, @Self);
- AmDefault := Enable;
- DrawView;
- end;
- end;
-
- procedure TButton.Press;
- var
- E: TEvent;
- begin
- Message(Owner, evBroadcast, cmRecordHistory, nil);
- if Flags and bfBroadcast <> 0 then
- Message(Owner, evBroadcast, Command, @Self) else
- begin
- E.What := evCommand;
- E.Command := Command;
- E.InfoPtr := @Self;
- PutEvent(E);
- end;
- end;
-
- procedure TButton.SetState(AState: Word; Enable: Boolean);
- begin
- TView.SetState(AState, Enable);
- if AState and (sfSelected + sfActive) <> 0 then DrawView;
- if AState and sfFocused <> 0 then MakeDefault(Enable);
- end;
-
- procedure TButton.Store(var S: TStream);
- begin
- TView.Store(S);
- S.WriteStr(Title);
- S.Write(Command, SizeOf(Word) + SizeOf(Byte) + SizeOf(Boolean));
- end;
-
- { TCluster }
-
- constructor TCluster.Init(var Bounds: TRect; AStrings: PSItem);
- var
- I: Integer;
- P: PSItem;
- begin
- TView.Init(Bounds);
- Options := Options or (ofSelectable + ofFirstClick + ofPreProcess +
- ofPostProcess + ofVersion20);
- I := 0;
- P := AStrings;
- while P <> nil do
- begin
- Inc(I);
- P := P^.Next;
- end;
- Strings.Init(I,0);
- while AStrings <> nil do
- begin
- P := AStrings;
- Strings.AtInsert(Strings.Count, AStrings^.Value);
- AStrings := AStrings^.Next;
- Dispose(P);
- end;
- Value := 0;
- Sel := 0;
- SetCursor(2,0);
- ShowCursor;
- EnableMask := $FFFFFFFF;
- end;
-
- constructor TCluster.Load(var S: TStream);
- begin
- TView.Load(S);
- if (Options and ofVersion) >= ofVersion20 then
- begin
- S.Read(Value, SizeOf(Longint) * 2 + SizeOf(Integer));
- end
- else
- begin
- S.Read(Value, SizeOf(Word));
- S.Read(Sel, SizeOf(Integer));
- EnableMask := $FFFFFFFF;
- Options := Options or ofVersion20;
- end;
- Strings.Load(S);
- SetButtonState(0, True);
- end;
-
- destructor TCluster.Done;
- begin
- Strings.Done;
- TView.Done;
- end;
-
- function TCluster.ButtonState(Item: Integer): Boolean; assembler;
- asm
- XOR AL,AL
- MOV CX,Item
- CMP CX,31
- JA @@3
- MOV AX,1
- XOR DX,DX
- JCXZ @@2
- @@1: SHL AX,1
- RCL DX,1
- LOOP @@1
- @@2: LES DI,Self
- AND AX,ES:[DI].TCluster.EnableMask.Word[0]
- AND DX,ES:[DI].TCluster.EnableMask.Word[2]
- OR AX,DX
- JZ @@3
- MOV AL,1
- @@3:
- end;
-
- function TCluster.DataSize: Word;
- begin
- DataSize := SizeOf(Word);
- end;
-
- procedure TCluster.DrawBox(const Icon: String; Marker: Char);
- begin
- DrawMultiBox(Icon, ' '+Marker);
- end;
-
- procedure TCluster.DrawMultiBox(const Icon, Marker: String);
- var
- I,J,Cur,Col: Integer;
- CNorm, CSel, CDis, Color: Word;
- B: TDrawBuffer;
- SCOff: Byte;
- begin
- CNorm := GetColor($0301);
- CSel := GetColor($0402);
- CDis := GetColor($0505);
- for I := 0 to Size.Y do
- begin
- MoveChar(B, ' ', Byte(CNorm), Size.X);
- for J := 0 to (Strings.Count - 1) div Size.Y + 1 do
- begin
- Cur := J*Size.Y + I;
- if Cur < Strings.Count then
- begin
- Col := Column(Cur);
- if (Col + CStrLen(PString(Strings.At(Cur))^) + 5 <
- Sizeof(TDrawBuffer) div SizeOf(Word)) and (Col < Size.X) then
- begin
- if not ButtonState(Cur) then
- Color := CDis
- else if (Cur = Sel) and (State and sfFocused <> 0) then
- Color := CSel
- else
- Color := CNorm;
- MoveChar(B[Col], ' ', Byte(Color), Size.X - Col);
- MoveStr(B[Col], Icon, Byte(Color));
- WordRec(B[Col+2]).Lo := Byte(Marker[MultiMark(Cur) + 1]);
- MoveCStr(B[Col+5], PString(Strings.At(Cur))^, Color);
- if ShowMarkers and (State and sfFocused <> 0) and (Cur = Sel) then
- begin
- WordRec(B[Col]).Lo := Byte(SpecialChars[0]);
- WordRec(B[Column(Cur+Size.Y)-1]).Lo := Byte(SpecialChars[1]);
- end;
- end;
- end;
- end;
- WriteBuf(0, I, Size.X, 1, B);
- end;
- SetCursor(Column(Sel)+2,Row(Sel));
- end;
-
- procedure TCluster.GetData(var Rec);
- begin
- Word(Rec) := Value;
- end;
-
- function TCluster.GetHelpCtx: Word;
- begin
- if HelpCtx = hcNoContext then GetHelpCtx := hcNoContext
- else GetHelpCtx := HelpCtx + Sel;
- end;
-
- function TCluster.GetPalette: PPalette;
- const
- P: String[Length(CCluster)] = CCluster;
- begin
- GetPalette := @P;
- end;
-
- procedure TCluster.HandleEvent(var Event: TEvent);
- var
- Mouse: TPoint;
- I, S: Integer;
- C: Char;
-
- procedure MoveSel;
- begin
- if I <= Strings.Count then
- begin
- Sel := S;
- MovedTo(Sel);
- DrawView;
- end;
- end;
-
- begin
- TView.HandleEvent(Event);
- if (Options and ofSelectable) = 0 then Exit;
- if Event.What = evMouseDown then
- begin
- MakeLocal(Event.Where, Mouse);
- I := FindSel(Mouse);
- if I <> -1 then if ButtonState(I) then Sel := I;
- DrawView;
- repeat
- MakeLocal(Event.Where, Mouse);
- if FindSel(Mouse) = Sel then
- ShowCursor else
- HideCursor;
- until not MouseEvent(Event,evMouseMove); {Wait for mouse up}
- ShowCursor;
- MakeLocal(Event.Where, Mouse);
- if (FindSel(Mouse) = Sel) and ButtonState(Sel) then
- begin
- Press(Sel);
- DrawView;
- end;
- ClearEvent(Event);
- end else if Event.What = evKeyDown then
- begin
- S := Sel;
- case CtrlToArrow(Event.KeyCode) of
- kbUp:
- if State and sfFocused <> 0 then
- begin
- I := 0;
- repeat
- Inc(I);
- Dec(S);
- if S < 0 then S := Strings.Count - 1;
- until ButtonState(S) or (I > Strings.Count);
- MoveSel;
- ClearEvent(Event);
- end;
- kbDown:
- if State and sfFocused <> 0 then
- begin
- I := 0;
- repeat
- Inc(I);
- Inc(S);
- if S >= Strings.Count then S := 0;
- until ButtonState(S) or (I > Strings.Count);
- MoveSel;
- ClearEvent(Event);
- end;
- kbRight:
- if State and sfFocused <> 0 then
- begin
- I := 0;
- repeat
- Inc(I);
- Inc(S,Size.Y);
- if S >= Strings.Count then
- begin
- S := (S+1) mod Size.Y;
- if S >= Strings.Count then S := 0;
- end;
- until ButtonState(S) or (I > Strings.Count);
- MoveSel;
- ClearEvent(Event);
- end;
- kbLeft:
- if State and sfFocused <> 0 then
- begin
- I := 0;
- repeat
- Inc(I);
- if S > 0 then
- begin
- Dec(S, Size.Y);
- if S < 0 then
- begin
- S := ((Strings.Count + Size.Y - 1) div Size.Y)*Size.Y + S - 1;
- if S >= Strings.Count then S := Strings.Count-1;
- end;
- end else S := Strings.Count-1;
- until ButtonState(S) or (I > Strings.Count);
- MoveSel;
- ClearEvent(Event);
- end;
- else
- begin
- for I := 0 to Strings.Count-1 do
- begin
- C := HotKey(PString(Strings.At(I))^);
- if (GetAltCode(C) = Event.KeyCode) or
- (((Owner^.Phase = phPostProcess) or (State and sfFocused <> 0))
- and (C <> #0) and (UpCase(Event.CharCode) = C)) then
- begin
- if ButtonState(I) then
- begin
- if Focus then
- begin
- Sel := I;
- MovedTo(Sel);
- Press(Sel);
- DrawView;
- end;
- ClearEvent(Event);
- end;
- Exit;
- end;
- end;
- if (Event.CharCode = ' ') and (State and sfFocused <> 0)
- and ButtonState(Sel)then
- begin
- Press(Sel);
- DrawView;
- ClearEvent(Event);
- end;
- end
- end
- end;
- end;
-
- procedure TCluster.SetButtonState(AMask: Longint; Enable: Boolean); assembler;
- asm
- LES DI,Self
- MOV AX,AMask.Word[0]
- MOV DX,AMask.Word[2]
- TEST Enable,0FFH
- JNZ @@1
- NOT AX
- NOT DX
- AND ES:[DI].TCluster.EnableMask.Word[0],AX
- AND ES:[DI].TCluster.EnableMask.Word[2],DX
- JMP @@2
- @@1: OR ES:[DI].TCluster.EnableMask.Word[0],AX
- OR ES:[DI].TCluster.EnableMask.Word[2],DX
- @@2: MOV CX,ES:[DI].Strings.TCollection.Count
- CMP CX,32
- JA @@6
- MOV BX,ES:[DI].TCluster.Options
- AND BX,not ofSelectable
- MOV AX,ES:[DI].TCluster.EnableMask.Word[0]
- MOV DX,ES:[DI].TCluster.EnableMask.Word[2]
- @@3: SHR DX,1
- RCR AX,1
- JC @@4
- LOOP @@3
- JMP @@5
- @@4: OR BX,ofSelectable
- @@5: MOV ES:[DI].TCluster.Options,BX
- @@6:
- end;
-
- procedure TCluster.SetData(var Rec);
- begin
- Value := Word(Rec);
- DrawView;
- end;
-
- procedure TCluster.SetState(AState: Word; Enable: Boolean);
- begin
- TView.SetState(AState, Enable);
- if AState = sfFocused then DrawView;
- end;
-
- function TCluster.Mark(Item: Integer): Boolean;
- begin
- Mark := False;
- end;
-
- function TCluster.MultiMark(Item: Integer): Byte;
- begin
- MultiMark := Byte(Mark(Item) = True);
- end;
-
- procedure TCluster.MovedTo(Item: Integer);
- begin
- end;
-
- procedure TCluster.Press(Item: Integer);
- begin
- end;
-
- procedure TCluster.Store(var S: TStream);
- begin
- TView.Store(S);
- S.Write(Value, SizeOf(Longint) * 2 + SizeOf(Integer));
- Strings.Store(S);
- end;
-
- function TCluster.Column(Item: Integer): Integer;
- var
- I, Col, Width, L: Integer;
- begin
- if Item < Size.Y then Column := 0
- else
- begin
- Width := 0;
- Col := -6;
- for I := 0 to Item do
- begin
- if I mod Size.Y = 0 then
- begin
- Inc(Col, Width + 6);
- Width := 0;
- end;
- if I < Strings.Count then
- L := CStrLen(PString(Strings.At(I))^);
- if L > Width then Width := L;
- end;
- Column := Col;
- end;
- end;
-
- function TCluster.FindSel(P: TPoint): Integer;
- var
- I, S: Integer;
- R: TRect;
- begin
- GetExtent(R);
- if not R.Contains(P) then FindSel := -1
- else
- begin
- I := 0;
- while P.X >= Column(I+Size.Y) do
- Inc(I, Size.Y);
- S := I + P.Y;
- if S >= Strings.Count then
- FindSel := -1 else
- FindSel := S;
- end;
- end;
-
- function TCluster.Row(Item: Integer): Integer;
- begin
- Row := Item mod Size.Y;
- end;
-
- { TRadioButtons }
-
- procedure TRadioButtons.Draw;
- const
- Button = ' ( ) ';
- begin
- DrawMultiBox(Button, #32#7);
- end;
-
- function TRadioButtons.Mark(Item: Integer): Boolean;
- begin
- Mark := Item = Value;
- end;
-
- procedure TRadioButtons.Press(Item: Integer);
- begin
- Value := Item;
- end;
-
- procedure TRadioButtons.MovedTo(Item: Integer);
- begin
- Value := Item;
- end;
-
- procedure TRadioButtons.SetData(var Rec);
- begin
- TCluster.SetData(Rec);
- Sel := Integer(Value);
- end;
-
- { TCheckBoxes }
-
- procedure TCheckBoxes.Draw;
- const
- Button = ' [ ] ';
- begin
- DrawMultiBox(Button, ' X');
- end;
-
- function TCheckBoxes.Mark(Item: Integer): Boolean;
- begin
- Mark := Value and (1 shl Item) <> 0;
- end;
-
- procedure TCheckBoxes.Press(Item: Integer);
- begin
- Value := Value xor (1 shl Item);
- end;
-
- { TMultiCheckBoxes }
-
- constructor TMultiCheckBoxes.Init(var Bounds: TRect; AStrings: PSItem;
- ASelRange: Byte; AFlags: Word; const AStates: String);
- begin
- Inherited Init(Bounds, AStrings);
- SelRange := ASelRange;
- Flags := AFlags;
- States := NewStr(AStates);
- end;
-
- constructor TMultiCheckBoxes.Load(var S: TStream);
- begin
- TCluster.Load(S);
- S.Read(SelRange, SizeOf(Byte));
- S.Read(Flags, SizeOf(Word));
- States := S.ReadStr;
- end;
-
- destructor TMultiCheckBoxes.Done;
- begin
- DisposeStr(States);
- TCluster.Done;
- end;
-
- procedure TMultiCheckBoxes.Draw;
- const
- Button = ' [ ] ';
- begin
- DrawMultiBox(Button, States^);
- end;
-
- function TMultiCheckBoxes.DataSize: Word;
- begin
- DataSize := SizeOf(Longint);
- end;
-
- function TMultiCheckBoxes.MultiMark(Item: Integer): Byte;
- begin
- MultiMark := (Value shr (Word(Item) * WordRec(Flags).Hi))
- and WordRec(Flags).Lo;
- end;
-
- procedure TMultiCheckBoxes.GetData(var Rec);
- begin
- Longint(Rec) := Value;
- end;
-
- procedure TMultiCheckBoxes.Press(Item: Integer);
- var
- CurState: ShortInt;
- begin
- CurState := (Value shr (Word(Item) * WordRec(Flags).Hi))
- and WordRec(Flags).Lo;
-
- Dec(CurState);
- if (CurState >= SelRange) or (CurState < 0) then
- CurState := SelRange - 1;
- Value := (Value and not (LongInt(WordRec(Flags).Lo)
- shl (Word(Item) * WordRec(Flags).Hi))) or
- (LongInt(CurState) shl (Word(Item) * WordRec(Flags).Hi));
- end;
-
- procedure TMultiCheckBoxes.SetData(var Rec);
- begin
- Value := Longint(Rec);
- DrawView;
- end;
-
- procedure TMultiCheckBoxes.Store(var S: TStream);
- begin
- TCluster.Store(S);
- S.Write(SelRange, SizeOf(Byte));
- S.Write(Flags, SizeOf(Word));
- S.WriteStr(States);
- end;
-
- { TListBox }
-
- type
- TListBoxRec = record
- List: PCollection;
- Selection: Word;
- end;
-
- constructor TListBox.Init(var Bounds: TRect; ANumCols: Word;
- AScrollBar: PScrollBar);
- begin
- TListViewer.Init(Bounds, ANumCols, nil, AScrollBar);
- List := nil;
- SetRange(0);
- end;
-
- constructor TListBox.Load(var S: TStream);
- begin
- TListViewer.Load(S);
- List := PCollection(S.Get);
- end;
-
- function TListBox.DataSize: Word;
- begin
- DataSize := SizeOf(TListBoxRec);
- end;
-
- procedure TListBox.GetData(var Rec);
- begin
- TListBoxRec(Rec).List := List;
- TListBoxRec(Rec).Selection := Focused;
- end;
-
- function TListBox.GetText(Item: Integer; MaxLen: Integer): String;
- begin
- if List <> nil then GetText := PString(List^.At(Item))^
- else GetText := '';
- end;
-
- procedure TListBox.NewList(AList: PCollection);
- begin
- if List <> nil then Dispose(List, Done);
- List := AList;
- if AList <> nil then SetRange(AList^.Count)
- else SetRange(0);
- if Range > 0 then FocusItem(0);
- DrawView;
- end;
-
- procedure TListBox.SetData(var Rec);
- begin
- NewList(TListBoxRec(Rec).List);
- FocusItem(TListBoxRec(Rec).Selection);
- DrawView;
- end;
-
- procedure TListBox.Store(var S: TStream);
- begin
- TListViewer.Store(S);
- S.Put(List);
- end;
-
- { TStaticText }
-
- constructor TStaticText.Init(var Bounds: TRect; const AText: String);
- begin
- TView.Init(Bounds);
- Text := NewStr(AText);
- end;
-
- constructor TStaticText.Load(var S: TStream);
- begin
- TView.Load(S);
- Text := S.ReadStr;
- end;
-
- destructor TStaticText.Done;
- begin
- DisposeStr(Text);
- TView.Done;
- end;
-
- procedure TStaticText.Draw;
- var
- Color: Byte;
- Center: Boolean;
- I, J, L, P, Y: Integer;
- B: TDrawBuffer;
- S: String;
- begin
- Color := GetColor(1);
- GetText(S);
- L := Length(S);
- P := 1;
- Y := 0;
- Center := False;
- while Y < Size.Y do
- begin
- MoveChar(B, ' ', Color, Size.X);
- if P <= L then
- begin
- if S[P] = #3 then
- begin
- Center := True;
- Inc(P);
- end;
- I := P;
- repeat
- J := P;
- while (P <= L) and (S[P] = ' ') do Inc(P);
- while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
- until (P > L) or (P >= I + Size.X) or (S[P] = #13);
- if P > I + Size.X then
- if J > I then P := J else P := I + Size.X;
- if Center then J := (Size.X - P + I) div 2 else J := 0;
- MoveBuf(B[J], S[I], Color, P - I);
- while (P <= L) and (S[P] = ' ') do Inc(P);
- if (P <= L) and (S[P] = #13) then
- begin
- Center := False;
- Inc(P);
- if (P <= L) and (S[P] = #10) then Inc(P);
- end;
- end;
- WriteLine(0, Y, Size.X, 1, B);
- Inc(Y);
- end;
- end;
-
- function TStaticText.GetPalette: PPalette;
- const
- P: String[Length(CStaticText)] = CStaticText;
- begin
- GetPalette := @P;
- end;
-
- procedure TStaticText.GetText(var S: String);
- begin
- if Text <> nil then S := Text^
- else S := '';
- end;
-
- procedure TStaticText.Store(var S: TStream);
- begin
- TView.Store(S);
- S.WriteStr(Text);
- end;
-
- { TParamText }
-
- constructor TParamText.Init(var Bounds: TRect; const AText: String;
- AParamCount: Integer);
- begin
- TStaticText.Init(Bounds, AText);
- ParamCount := AParamCount;
- end;
-
- constructor TParamText.Load(var S: TStream);
- begin
- TStaticText.Load(S);
- S.Read(ParamCount, SizeOf(Integer));
- end;
-
- function TParamText.DataSize: Word;
- begin
- DataSize := ParamCount * SizeOf(Longint);
- end;
-
- procedure TParamText.GetText(var S: String);
- begin
- if Text <> nil then FormatStr(S, Text^, ParamList^)
- else S := '';
- end;
-
- procedure TParamText.SetData(var Rec);
- begin
- ParamList := @Rec;
- DrawView;
- end;
-
- procedure TParamText.Store(var S: TStream);
- begin
- TStaticText.Store(S);
- S.Write(ParamCount, SizeOf(Integer));
- end;
-
- { TLabel }
-
- constructor TLabel.Init(var Bounds: TRect; const AText: String; ALink: PView);
- begin
- TStaticText.Init(Bounds, AText);
- Link := ALink;
- Options := Options or (ofPreProcess + ofPostProcess);
- EventMask := EventMask or evBroadcast;
- end;
-
- constructor TLabel.Load(var S: TStream);
- begin
- TStaticText.Load(S);
- GetPeerViewPtr(S, Link);
- end;
-
- procedure TLabel.Draw;
- var
- Color: Word;
- B: TDrawBuffer;
- SCOff: Byte;
- begin
- if Light then
- begin
- Color := GetColor($0402);
- SCOff := 0;
- end
- else
- begin
- Color := GetColor($0301);
- SCOff := 4;
- end;
- MoveChar(B[0], ' ', Byte(Color), Size.X);
- if Text <> nil then MoveCStr(B[1], Text^, Color);
- if ShowMarkers then WordRec(B[0]).Lo := Byte(SpecialChars[SCOff]);
- WriteLine(0, 0, Size.X, 1, B);
- end;
-
- function TLabel.GetPalette: PPalette;
- const
- P: String[Length(CLabel)] = CLabel;
- begin
- GetPalette := @P;
- end;
-
- procedure TLabel.HandleEvent(var Event: TEvent);
- var
- C: Char;
-
- procedure FocusLink;
- begin
- if (Link <> nil) and (Link^.Options and ofSelectable <> 0) then
- Link^.Focus;
- ClearEvent(Event);
- end;
-
- begin
- TStaticText.HandleEvent(Event);
- if Event.What = evMouseDown then FocusLink
- else if Event.What = evKeyDown then
- begin
- C := HotKey(Text^);
- if (GetAltCode(C) = Event.KeyCode) or
- ((C <> #0) and (Owner^.Phase = phPostProcess) and
- (UpCase(Event.CharCode) = C)) then FocusLink
- end
- else if Event.What = evBroadcast then
- if ((Event.Command = cmReceivedFocus) or
- (Event.Command = cmReleasedFocus)) and
- (Link <> nil) then
- begin
- Light := Link^.State and sfFocused <> 0;
- DrawView;
- end;
- end;
-
- procedure TLabel.Store(var S: TStream);
- begin
- TStaticText.Store(S);
- PutPeerViewPtr(S, Link);
- end;
-
- { THistoryViewer }
-
- constructor THistoryViewer.Init(var Bounds: TRect; AHScrollBar,
- AVScrollBar: PScrollBar; AHistoryId: Word);
- begin
- TListViewer.Init(Bounds, 1, AHScrollBar, AVScrollBar);
- HistoryId := AHistoryId;
- SetRange(HistoryCount(AHistoryId));
- if Range > 1 then FocusItem(1);
- HScrollBar^.SetRange(1, HistoryWidth-Size.X + 3);
- end;
-
- function THistoryViewer.GetPalette: PPalette;
- const
- P: String[Length(CHistoryViewer)] = CHistoryViewer;
- begin
- GetPalette := @P;
- end;
-
- function THistoryViewer.GetText(Item: Integer; MaxLen: Integer): String;
- begin
- GetText := HistoryStr(HistoryId, Item);
- end;
-
- procedure THistoryViewer.HandleEvent(var Event: TEvent);
- begin
- if ((Event.What = evMouseDown) and (Event.Double)) or
- ((Event.What = evKeyDown) and (Event.KeyCode = kbEnter)) then
- begin
- EndModal(cmOk);
- ClearEvent(Event);
- end else if ((Event.What = evKeyDown) and (Event.KeyCode = kbEsc)) or
- ((Event.What = evCommand) and (Event.Command = cmCancel)) then
- begin
- EndModal(cmCancel);
- ClearEvent(Event);
- end else TListViewer.HandleEvent(Event);
- end;
-
- function THistoryViewer.HistoryWidth: Integer;
- var
- Width, T, Count, I: Integer;
- begin
- Width := 0;
- Count := HistoryCount(HistoryId);
- for I := 0 to Count-1 do
- begin
- T := Length(HistoryStr(HistoryId, I));
- if T > Width then Width := T;
- end;
- HistoryWidth := Width;
- end;
-
- { THistoryWindow }
-
- constructor THistoryWindow.Init(var Bounds: TRect; HistoryId: Word);
- begin
- TWindow.Init(Bounds, '', wnNoNumber);
- Flags := wfClose;
- InitViewer(HistoryId);
- end;
-
- function THistoryWindow.GetPalette: PPalette;
- const
- P: String[Length(CHistoryWindow)] = CHistoryWindow;
- begin
- GetPalette := @P;
- end;
-
- function THistoryWindow.GetSelection: String;
- begin
- GetSelection := Viewer^.GetText(Viewer^.Focused,255);
- end;
-
- procedure THistoryWindow.InitViewer(HistoryId: Word);
- var
- R: TRect;
- begin
- GetExtent(R);
- R.Grow(-1,-1);
- Viewer := New(PHistoryViewer, Init(R,
- StandardScrollBar(sbHorizontal + sbHandleKeyboard),
- StandardScrollBar(sbVertical + sbHandleKeyboard),
- HistoryId));
- Insert(Viewer);
- end;
-
- { THistory }
-
- constructor THistory.Init(var Bounds: TRect; ALink: PInputLine;
- AHistoryId: Word);
- begin
- TView.Init(Bounds);
- Options := Options or ofPostProcess;
- EventMask := EventMask or evBroadcast;
- Link := ALink;
- HistoryId := AHistoryId;
- end;
-
- constructor THistory.Load(var S: TStream);
- begin
- TView.Load(S);
- GetPeerViewPtr(S, Link);
- S.Read(HistoryId, SizeOf(Word));
- end;
-
- procedure THistory.Draw;
- var
- B: TDrawBuffer;
- begin
- MoveCStr(B, #222'~'#25'~'#221, GetColor($0102));
- WriteLine(0, 0, Size.X, Size.Y, B);
- end;
-
- function THistory.GetPalette: PPalette;
- const
- P: String[Length(CHistory)] = CHistory;
- begin
- GetPalette := @P;
- end;
-
- procedure THistory.HandleEvent(var Event: TEvent);
- var
- HistoryWindow: PHistoryWindow;
- R,P: TRect;
- C: Word;
- Rslt: String;
- begin
- TView.HandleEvent(Event);
- if (Event.What = evMouseDown) or
- ((Event.What = evKeyDown) and (CtrlToArrow(Event.KeyCode) = kbDown) and
- (Link^.State and sfFocused <> 0)) then
- begin
- if not Link^.Focus then
- begin
- ClearEvent(Event);
- Exit;
- end;
- RecordHistory(Link^.Data^);
- Link^.GetBounds(R);
- Dec(R.A.X); Inc(R.B.X); Inc(R.B.Y,7); Dec(R.A.Y,1);
- Owner^.GetExtent(P);
- R.Intersect(P);
- Dec(R.B.Y,1);
- HistoryWindow := InitHistoryWindow(R);
- if HistoryWindow <> nil then
- begin
- C := Owner^.ExecView(HistoryWindow);
- if C = cmOk then
- begin
- Rslt := HistoryWindow^.GetSelection;
- if Length(Rslt) > Link^.MaxLen then Rslt[0] := Char(Link^.MaxLen);
- Link^.Data^ := Rslt;
- Link^.SelectAll(True);
- Link^.DrawView;
- end;
- Dispose(HistoryWindow, Done);
- end;
- ClearEvent(Event);
- end
- else if (Event.What = evBroadcast) then
- if ((Event.Command = cmReleasedFocus) and (Event.InfoPtr = Link))
- or (Event.Command = cmRecordHistory) then
- RecordHistory(Link^.Data^);
- end;
-
- function THistory.InitHistoryWindow(var Bounds: TRect): PHistoryWindow;
- var
- P: PHistoryWindow;
- begin
- P := New(PHistoryWindow, Init(Bounds, HistoryId));
- P^.HelpCtx := Link^.HelpCtx;
- InitHistoryWindow := P;
- end;
-
- procedure THistory.RecordHistory(const S: String);
- begin
- HistoryAdd(HistoryId, S);
- end;
-
- procedure THistory.Store(var S: TStream);
- begin
- TView.Store(S);
- PutPeerViewPtr(S, Link);
- S.Write(HistoryId, SizeOf(Word));
- end;
-
- { Dialogs registration procedure }
-
- procedure RegisterDialogs;
- begin
- RegisterType(RDialog);
- RegisterType(RInputLine);
- RegisterType(RButton);
- RegisterType(RCluster);
- RegisterType(RRadioButtons);
- RegisterType(RCheckBoxes);
- RegisterType(RMultiCheckBoxes);
- RegisterType(RListBox);
- RegisterType(RStaticText);
- RegisterType(RLabel);
- RegisterType(RHistory);
- RegisterType(RParamText);
- end;
-
- end.
-