fpc/fv/views.pas

5890 lines
278 KiB
ObjectPascal
Raw Blame History

{ $Id$ }
{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
{ }
{ System independent GRAPHICAL clone of VIEWS.PAS }
{ }
{ Interface Copyright (c) 1992 Borland International }
{ }
{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
{ ldeboer@attglobal.net - primary e-mail address }
{ ldeboer@starwon.com.au - backup e-mail address }
{ }
{****************[ THIS CODE IS FREEWARE ]*****************}
{ }
{ This sourcecode is released for the purpose to }
{ promote the pascal language on all platforms. You may }
{ redistribute it and/or modify with the following }
{ DISCLAIMER. }
{ }
{ This SOURCE CODE is distributed "AS IS" WITHOUT }
{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
{ }
{*****************[ SUPPORTED PLATFORMS ]******************}
{ 16 and 32 Bit compilers }
{ DOS - Turbo Pascal 7.0 + (16 Bit) }
{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
{ - FPC 0.9912+ (GO32V2) (32 Bit) }
{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
{ - Delphi 1.0+ (16 Bit) }
{ WIN95/NT - Delphi 2.0+ (32 Bit) }
{ - Virtual Pascal 2.0+ (32 Bit) }
{ - Speedsoft Sybil 2.0+ (32 Bit) }
{ - FPC 0.9912+ (32 Bit) }
{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
{ }
{******************[ REVISION HISTORY ]********************}
{ Version Date Fix }
{ ------- --------- --------------------------------- }
{ 1.00 10 Nov 96 First multi platform release }
{ 1.10 29 Aug 97 Platform.inc sort added. }
{ 1.20 12 Sep 97 FPK pascal 0.92 conversion added. }
{ 1.30 10 Jun 98 Virtual pascal 2.0 code added. }
{ 1.40 10 Jul 99 Sybil 2.0 code added }
{ 1.41 03 Nov 99 FPC Windows support added. }
{ 1.50 26 Nov 99 Graphics stuff moved to GFVGraph }
{**********************************************************}
UNIT Views;
{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
INTERFACE
{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
{====Include file to sort compiler platform out =====================}
{$I Platform.inc}
{====================================================================}
{==== Compiler directives ===========================================}
{$X+} { Extended syntax is ok }
{$R-} { Disable range checking }
{$S-} { Disable Stack Checking }
{$I-} { Disable IO Checking }
{$Q-} { Disable Overflow Checking }
{$V-} { Turn off strict VAR strings }
{====================================================================}
USES
{$IFDEF OS_WINDOWS} { WIN/NT CODE }
Windows, { Standard unit }
{$ENDIF}
{$IFDEF OS_OS2} { OS2 CODE }
{$IFDEF PPC_FPC}
Os2Def, DosCalls, PmWin,
{$ELSE}
OS2Def, OS2Base, OS2PMAPI, { Standard units }
{$ENDIF}
{$ENDIF}
{$IFDEF GRAPH_API}
graph,
{$ENDIF GRAPH_API}
GFVGraph, { GFV standard unit }
Objects, FVCommon, Drivers; { GFV standard units }
{***************************************************************************}
{ PUBLIC CONSTANTS }
{***************************************************************************}
{---------------------------------------------------------------------------}
{ TView STATE MASKS }
{---------------------------------------------------------------------------}
CONST
sfVisible = $0001; { View visible mask }
sfCursorVis = $0002; { Cursor visible }
sfCursorIns = $0004; { Cursor insert mode }
sfShadow = $0008; { View has shadow }
sfActive = $0010; { View is active }
sfSelected = $0020; { View is selected }
sfFocused = $0040; { View is focused }
sfDragging = $0080; { View is dragging }
sfDisabled = $0100; { View is disabled }
sfModal = $0200; { View is modal }
sfDefault = $0400; { View is default }
sfExposed = $0800; { View is exposed }
sfIconised = $1000; { View is iconised }
{---------------------------------------------------------------------------}
{ TView OPTION MASKS }
{---------------------------------------------------------------------------}
CONST
ofSelectable = $0001; { View selectable }
ofTopSelect = $0002; { Top selectable }
ofFirstClick = $0004; { First click react }
ofFramed = $0008; { View is framed }
ofPreProcess = $0010; { Pre processes }
ofPostProcess = $0020; { Post processes }
ofBuffered = $0040; { View is buffered }
ofTileable = $0080; { View is tileable }
ofCenterX = $0100; { View centred on x }
ofCenterY = $0200; { View centred on y }
ofCentered = $0300; { View x,y centred }
ofValidate = $0400; { View validates }
ofVersion = $3000; { View TV version }
ofVersion10 = $0000; { TV version 1 view }
ofVersion20 = $1000; { TV version 2 view }
ofGFVModeView = $4000; { View is in GFV mode }
{---------------------------------------------------------------------------}
{ TView GROW MODE MASKS }
{---------------------------------------------------------------------------}
CONST
gfGrowLoX = $01; { Left side grow }
gfGrowLoY = $02; { Top side grow }
gfGrowHiX = $04; { Right side grow }
gfGrowHiY = $08; { Bottom side grow }
gfGrowAll = $0F; { Grow on all sides }
gfGrowRel = $10; { Grow relative }
{---------------------------------------------------------------------------}
{ TView DRAG MODE MASKS }
{---------------------------------------------------------------------------}
CONST
dmDragMove = $01; { Move view }
dmDragGrow = $02; { Grow view }
dmLimitLoX = $10; { Limit left side }
dmLimitLoY = $20; { Limit top side }
dmLimitHiX = $40; { Limit right side }
dmLimitHiY = $80; { Limit bottom side }
dmLimitAll = $F0; { Limit all sides }
{---------------------------------------------------------------------------}
{ >> NEW << TView OPTION MASKS }
{---------------------------------------------------------------------------}
CONST
goThickFramed = $0001; { Thick framed mask }
goDrawFocus = $0002; { Draw focus mask }
goTitled = $0004; { Draw titled mask }
goTabSelect = $0008; { Tab selectable }
goEveryKey = $0020; { Report every key }
goEndModal = $0040; { End modal }
goNoShadow = $0080; { Do not write shadows }
goGraphView = $1000; { Raw graphic view }
goGraphical = $2000; { Graphical view }
goNativeClass = $4000; { Native class window }
goNoDrawView = $8000; { View does not draw }
{---------------------------------------------------------------------------}
{ >> NEW << TAB OPTION MASKS }
{---------------------------------------------------------------------------}
CONST
tmTab = $01; { Tab move mask }
tmShiftTab = $02; { Shift+tab move mask }
tmEnter = $04; { Enter move mask }
tmLeft = $08; { Left arrow move mask }
tmRight = $10; { Right arrow move mask }
tmUp = $20; { Up arrow move mask }
tmDown = $40; { Down arrow move mask }
{---------------------------------------------------------------------------}
{ >> NEW << VIEW DRAW MASKS }
{---------------------------------------------------------------------------}
CONST
vdBackGnd = $01; { Draw backgound }
vdInner = $02; { Draw inner detail }
vdCursor = $04; { Draw cursor }
vdBorder = $08; { Draw view border }
vdFocus = $10; { Draw focus state }
vdNoChild = $20; { Draw no children }
vdShadow = $40;
vdAll = vdBackGnd + vdInner + vdCursor + vdBorder + vdFocus + vdShadow;
{---------------------------------------------------------------------------}
{ TView HELP CONTEXTS }
{---------------------------------------------------------------------------}
CONST
hcNoContext = 0; { No view context }
hcDragging = 1; { No drag context }
{---------------------------------------------------------------------------}
{ TWindow FLAG MASKS }
{---------------------------------------------------------------------------}
CONST
wfMove = $01; { Window can move }
wfGrow = $02; { Window can grow }
wfClose = $04; { Window can close }
wfZoom = $08; { Window can zoom }
{---------------------------------------------------------------------------}
{ TWindow PALETTES }
{---------------------------------------------------------------------------}
CONST
wpBlueWindow = 0; { Blue palette }
wpCyanWindow = 1; { Cyan palette }
wpGrayWindow = 2; { Gray palette }
{---------------------------------------------------------------------------}
{ COLOUR PALETTES }
{---------------------------------------------------------------------------}
CONST
CFrame = #1#1#2#2#3; { Frame palette }
CScrollBar = #4#5#5; { Scrollbar palette }
CScroller = #6#7; { Scroller palette }
CListViewer = #26#26#27#28#29; { Listviewer palette }
CBlueWindow = #8#9#10#11#12#13#14#15; { Blue window palette }
CCyanWindow = #16#17#18#19#20#21#22#23; { Cyan window palette }
CGrayWindow = #24#25#26#27#28#29#30#31; { Grey window palette }
{---------------------------------------------------------------------------}
{ TScrollBar PART CODES }
{---------------------------------------------------------------------------}
CONST
sbLeftArrow = 0; { Left arrow part }
sbRightArrow = 1; { Right arrow part }
sbPageLeft = 2; { Page left part }
sbPageRight = 3; { Page right part }
sbUpArrow = 4; { Up arrow part }
sbDownArrow = 5; { Down arrow part }
sbPageUp = 6; { Page up part }
sbPageDown = 7; { Page down part }
sbIndicator = 8; { Indicator part }
{---------------------------------------------------------------------------}
{ TScrollBar OPTIONS FOR TWindow.StandardScrollBar }
{---------------------------------------------------------------------------}
CONST
sbHorizontal = $0000; { Horz scrollbar }
sbVertical = $0001; { Vert scrollbar }
sbHandleKeyboard = $0002; { Handle keyboard }
{---------------------------------------------------------------------------}
{ STANDARD COMMAND CODES }
{---------------------------------------------------------------------------}
CONST
cmValid = 0; { Valid command }
cmQuit = 1; { Quit command }
cmError = 2; { Error command }
cmMenu = 3; { Menu command }
cmClose = 4; { Close command }
cmZoom = 5; { Zoom command }
cmResize = 6; { Resize command }
cmNext = 7; { Next view command }
cmPrev = 8; { Prev view command }
cmHelp = 9; { Help command }
cmOK = 10; { Okay command }
cmCancel = 11; { Cancel command }
cmYes = 12; { Yes command }
cmNo = 13; { No command }
cmDefault = 14; { Default command }
cmCut = 20; { Clipboard cut cmd }
cmCopy = 21; { Clipboard copy cmd }
cmPaste = 22; { Clipboard paste cmd }
cmUndo = 23; { Clipboard undo cmd }
cmClear = 24; { Clipboard clear cmd }
cmTile = 25; { Tile subviews cmd }
cmCascade = 26; { Cascade subviews cmd }
cmReceivedFocus = 50; { Received focus }
cmReleasedFocus = 51; { Released focus }
cmCommandSetChanged = 52; { Commands changed }
cmScrollBarChanged = 53; { Scrollbar changed }
cmScrollBarClicked = 54; { Scrollbar clicked on }
cmSelectWindowNum = 55; { Select window }
cmListItemSelected = 56; { Listview item select }
cmNotify = 27;
cmIdCommunicate = 28; { Communicate via id }
cmIdSelect = 29; { Select via id }
{---------------------------------------------------------------------------}
{ TWindow NUMBER CONSTANTS }
{---------------------------------------------------------------------------}
CONST
wnNoNumber = 0; { Window has no num }
MaxViewWidth = 132; { Max view width }
{***************************************************************************}
{ PUBLIC TYPE DEFINITIONS }
{***************************************************************************}
{---------------------------------------------------------------------------}
{ TWindow Title string }
{---------------------------------------------------------------------------}
TYPE
TTitleStr = String[80]; { Window title string }
{---------------------------------------------------------------------------}
{ COMMAND SET RECORD }
{---------------------------------------------------------------------------}
TYPE
TCommandSet = SET OF Byte; { Command set record }
PCommandSet = ^TCommandSet; { Ptr to command set }
{---------------------------------------------------------------------------}
{ PALETTE RECORD }
{---------------------------------------------------------------------------}
TYPE
TPalette = String; { Palette record }
PPalette = ^TPalette; { Pointer to palette }
{---------------------------------------------------------------------------}
{ TDrawBuffer RECORD }
{---------------------------------------------------------------------------}
TYPE
TDrawBuffer = Array [0..MaxViewWidth - 1] Of Word; { Draw buffer record }
PDrawBuffer = ^TDrawBuffer; { Ptr to draw buffer }
{---------------------------------------------------------------------------}
{ TVideoBuffer RECORD }
{---------------------------------------------------------------------------}
TYPE
TVideoBuf = ARRAY [0..3999] of Word; { Video buffer }
PVideoBuf = ^TVideoBuf; { Pointer to buffer }
{---------------------------------------------------------------------------}
{ TComplexArea RECORD }
{---------------------------------------------------------------------------}
TYPE
PComplexArea = ^TComplexArea; { Complex area }
TComplexArea = PACKED RECORD
X1, Y1 : Sw_Integer; { Top left corner }
X2, Y2 : Sw_Integer; { Lower right corner }
NextArea: PComplexArea; { Next area pointer }
END;
{***************************************************************************}
{ PUBLIC OBJECT DEFINITIONS }
{***************************************************************************}
TYPE
PGroup = ^TGroup; { Pointer to group }
{---------------------------------------------------------------------------}
{ TView OBJECT - ANCESTOR VIEW OBJECT }
{---------------------------------------------------------------------------}
PView = ^TView;
TView = OBJECT (TObject)
GrowMode : Byte; { View grow mode }
DragMode : Byte; { View drag mode }
DrawMask : Byte; { Draw masks }
TabMask : Byte; { Tab move masks }
ColourOfs: Sw_Integer; { View palette offset }
HelpCtx : Word; { View help context }
State : Word; { View state masks }
Options : Word; { View options masks }
EventMask: Word; { View event masks }
GOptions : Word; { Graphics options }
Origin : TPoint; { View origin }
Size : TPoint; { View size }
Cursor : TPoint; { Cursor position }
RawOrigin: TPoint; { View raw origin }
RawSize : TPoint; { View raw size }
Next : PView; { Next peerview }
Owner : PGroup; { Owner group }
HoldLimit: PComplexArea; { Hold limit values }
RevCol : Boolean;
BackgroundChar : Char;
CONSTRUCTOR Init (Var Bounds: TRect);
CONSTRUCTOR Load (Var S: TStream);
DESTRUCTOR Done; Virtual;
FUNCTION Prev: PView;
FUNCTION Execute: Word; Virtual;
FUNCTION Focus: Boolean;
FUNCTION DataSize: Sw_Word; Virtual;
FUNCTION TopView: PView;
FUNCTION PrevView: PView;
FUNCTION NextView: PView;
FUNCTION GetHelpCtx: Word; Virtual;
FUNCTION EventAvail: Boolean;
FUNCTION GetPalette: PPalette; Virtual;
FUNCTION GetColor (Color: Word): Word;
FUNCTION Valid (Command: Word): Boolean; Virtual;
FUNCTION GetState (AState: Word): Boolean;
FUNCTION TextWidth (Txt: String): Sw_Integer;
FUNCTION MouseInView (Point: TPoint): Boolean;
FUNCTION CommandEnabled (Command: Word): Boolean;
FUNCTION OverLapsArea (X1, Y1, X2, Y2: Sw_Integer): Boolean;
FUNCTION MouseEvent (Var Event: TEvent; Mask: Word): Boolean;
PROCEDURE Hide;
PROCEDURE Show;
PROCEDURE Draw; Virtual;
PROCEDURE ResetCursor; Virtual;
PROCEDURE Select;
PROCEDURE Awaken; Virtual;
PROCEDURE DrawView;
PROCEDURE MakeFirst;
PROCEDURE DrawFocus; Virtual;
PROCEDURE DrawCursor; Virtual;
PROCEDURE DrawBorder; Virtual;
PROCEDURE DrawShadow; Virtual;
PROCEDURE HideCursor;
PROCEDURE ShowCursor;
PROCEDURE BlockCursor;
PROCEDURE NormalCursor;
PROCEDURE FocusFromTop; Virtual;
PROCEDURE SetViewLimits;
PROCEDURE DrawBackGround; Virtual;
PROCEDURE ReleaseViewLimits;
PROCEDURE MoveTo (X, Y: Sw_Integer);
PROCEDURE GrowTo (X, Y: Sw_Integer);
PROCEDURE SetDrawMask (Mask: Byte);
PROCEDURE EndModal (Command: Word); Virtual;
PROCEDURE SetCursor (X, Y: Sw_Integer);
PROCEDURE PutInFrontOf (Target: PView);
PROCEDURE DisplaceBy (Dx, Dy: Sw_Integer); Virtual;
PROCEDURE SetCommands (Commands: TCommandSet);
PROCEDURE ReDrawArea (X1, Y1, X2, Y2: Sw_Integer); Virtual;
PROCEDURE EnableCommands (Commands: TCommandSet);
PROCEDURE DisableCommands (Commands: TCommandSet);
PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
PROCEDURE SetCmdState (Commands: TCommandSet; Enable: Boolean);
PROCEDURE GetData (Var Rec); Virtual;
PROCEDURE SetData (Var Rec); Virtual;
PROCEDURE Store (Var S: TStream);
PROCEDURE Locate (Var Bounds: TRect);
PROCEDURE KeyEvent (Var Event: TEvent);
PROCEDURE GetEvent (Var Event: TEvent); Virtual;
PROCEDURE PutEvent (Var Event: TEvent); Virtual;
PROCEDURE GetExtent (Var Extent: TRect);
PROCEDURE GetBounds (Var Bounds: TRect);
PROCEDURE SetBounds (Var Bounds: TRect);
PROCEDURE GetClipRect (Var Clip: TRect);
PROCEDURE ClearEvent (Var Event: TEvent);
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
PROCEDURE SizeLimits (Var Min, Max: TPoint); Virtual;
PROCEDURE GetCommands (Var Commands: TCommandSet);
PROCEDURE GetPeerViewPtr (Var S: TStream; Var P);
PROCEDURE PutPeerViewPtr (Var S: TStream; P: PView);
PROCEDURE CalcBounds (Var Bounds: TRect; Delta: TPoint); Virtual;
FUNCTION Exposed: Boolean; { This needs help!!!!! }
PROCEDURE GraphLine (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
PROCEDURE GraphRectangle (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
PROCEDURE ClearArea (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
PROCEDURE GraphArc (Xc, Yc: Sw_Integer; Sa, Ea: Real; XRad, YRad: Sw_Integer;
Colour: Byte);
PROCEDURE FilletArc (Xc, Yc: Sw_Integer; Sa, Ea: Real; XRad, YRad, Ht: Sw_Integer;
Colour: Byte);
PROCEDURE BicolorRectangle (X1, Y1, X2, Y2: Sw_Integer; Light, Dark: Byte;
Down: Boolean);
PROCEDURE WriteBuf (X, Y, W, H: Sw_Integer; Var Buf);
PROCEDURE WriteLine (X, Y, W, H: Sw_Integer; Var Buf);
PROCEDURE MakeLocal (Source: TPoint; Var Dest: TPoint);
PROCEDURE MakeGlobal (Source: TPoint; Var Dest: TPoint);
PROCEDURE WriteStr (X, Y: Sw_Integer; Str: String; Color: Byte);
PROCEDURE WriteCStr (X, Y: Sw_Integer; Str: String; Color1, Color2 : Byte);
PROCEDURE WriteChar (X, Y: Sw_Integer; C: Char; Color: Byte;
Count: Sw_Integer);
PROCEDURE DragView (Event: TEvent; Mode: Byte; Var Limits: TRect;
MinSize, MaxSize: TPoint);
PROCEDURE WriteAbs(X, Y, L :Sw_Integer;var Buf);
PROCEDURE WriteShadow(X1, Y1, X2, Y2 : Sw_Integer);
FUNCTION FontWidth: Sw_Integer;
FUNCTION Fontheight: Sw_Integer;
END;
SelectMode = (NormalSelect, EnterSelect, LeaveSelect);
{---------------------------------------------------------------------------}
{ TGroup OBJECT - GROUP OBJECT ANCESTOR }
{---------------------------------------------------------------------------}
TGroup = OBJECT (TView)
Phase : (phFocused, phPreProcess, phPostProcess);
EndState: Word; { Modal result }
Current : PView; { Selected subview }
Last : PView; { 1st view inserted }
Buffer : PVideoBuf; { Speed up buffer }
CONSTRUCTOR Init (Var Bounds: TRect);
CONSTRUCTOR Load (Var S: TStream);
DESTRUCTOR Done; Virtual;
FUNCTION First: PView;
FUNCTION Execute: Word; Virtual;
FUNCTION GetHelpCtx: Word; Virtual;
FUNCTION DataSize: Sw_Word; Virtual;
FUNCTION ExecView (P: PView): Word; Virtual;
FUNCTION FirstThat (P: Pointer): PView;
FUNCTION Valid (Command: Word): Boolean; Virtual;
FUNCTION FocusNext (Forwards: Boolean): Boolean;
PROCEDURE Draw; Virtual;
PROCEDURE DrawBackGround; Virtual;
PROCEDURE Lock;
PROCEDURE UnLock;
PROCEDURE Awaken; Virtual;
PROCEDURE ReDraw;
PROCEDURE ReDrawArea (X1, Y1, X2, Y2: Sw_Integer); Virtual;
PROCEDURE ReDrawVisibleArea (X1, Y1, X2, Y2: Sw_Integer;Cur : PView);
PROCEDURE SelectDefaultView;
PROCEDURE Insert (P: PView);
PROCEDURE Delete (P: PView);
PROCEDURE ForEach (P: Pointer);
{ ForEach can't be virtual because it generates SIGSEGV }
PROCEDURE EndModal (Command: Word); Virtual;
PROCEDURE DisplaceBy (Dx, Dy: Sw_Integer); Virtual;
PROCEDURE SelectNext (Forwards: Boolean);
PROCEDURE InsertBefore (P, Target: PView);
PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
PROCEDURE GetData (Var Rec); Virtual;
PROCEDURE SetData (Var Rec); Virtual;
PROCEDURE Store (Var S: TStream);
PROCEDURE EventError (Var Event: TEvent); Virtual;
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
PROCEDURE GetSubViewPtr (Var S: TStream; Var P);
PROCEDURE PutSubViewPtr (Var S: TStream; P: PView);
PRIVATE
LockFlag: Byte;
Clip : TRect;
FUNCTION IndexOf (P: PView): Sw_Integer;
FUNCTION FindNext (Forwards: Boolean): PView;
FUNCTION FirstMatch (AState: Word; AOptions: Word): PView;
PROCEDURE ResetCurrent;
PROCEDURE RemoveView (P: PView);
PROCEDURE InsertView (P, Target: PView);
PROCEDURE SetCurrent (P: PView; Mode: SelectMode);
END;
{---------------------------------------------------------------------------}
{ TFrame OBJECT - FRAME VIEW OBJECT }
{---------------------------------------------------------------------------}
TYPE
TFrame = OBJECT (TView)
CONSTRUCTOR Init (Var Bounds: TRect);
FUNCTION GetPalette: PPalette; Virtual;
END;
PFrame = ^TFrame;
{---------------------------------------------------------------------------}
{ TScrollBar OBJECT - SCROLL BAR OBJECT }
{---------------------------------------------------------------------------}
TYPE
TScrollChars = Array [0..4] of Char;
TScrollBar = OBJECT (TView)
Value : Sw_Integer; { Scrollbar value }
Min : Sw_Integer; { Scrollbar minimum }
Max : Sw_Integer; { Scrollbar maximum }
PgStep: Sw_Integer; { One page step }
ArStep: Sw_Integer; { One range step }
Id : Sw_Integer; { Scrollbar ID }
CONSTRUCTOR Init (Var Bounds: TRect);
CONSTRUCTOR Load (Var S: TStream);
FUNCTION GetPalette: PPalette; Virtual;
FUNCTION ScrollStep (Part: Sw_Integer): Sw_Integer; Virtual;
PROCEDURE Draw; Virtual;
PROCEDURE ScrollDraw; Virtual;
PROCEDURE DrawBackGround; Virtual;
PROCEDURE SetValue (AValue: Sw_Integer);
PROCEDURE SetRange (AMin, AMax: Sw_Integer);
PROCEDURE SetStep (APgStep, AArStep: Sw_Integer);
PROCEDURE SetParams (AValue, AMin, AMax, APgStep, AArStep: Sw_Integer);
PROCEDURE Store (Var S: TStream);
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PRIVATE
Chars: TScrollChars; { Scrollbar chars }
FUNCTION GetPos: Sw_Integer;
FUNCTION GetSize: Sw_Integer;
PROCEDURE DrawPos (Pos: Sw_Integer);
PROCEDURE ClearPos (Pos: Sw_Integer);
END;
PScrollBar = ^TScrollBar;
{---------------------------------------------------------------------------}
{ TScroller OBJECT - SCROLLING VIEW ANCESTOR }
{---------------------------------------------------------------------------}
TYPE
TScroller = OBJECT (TView)
Delta : TPoint;
Limit : TPoint;
HScrollBar: PScrollBar; { Horz scroll bar }
VScrollBar: PScrollBar; { Vert scroll bar }
CONSTRUCTOR Init (Var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
CONSTRUCTOR Load (Var S: TStream);
FUNCTION GetPalette: PPalette; Virtual;
PROCEDURE ScrollDraw; Virtual;
PROCEDURE SetLimit (X, Y: Sw_Integer);
PROCEDURE ScrollTo (X, Y: Sw_Integer);
PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
PROCEDURE Store (Var S: TStream);
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
PRIVATE
DrawFlag: Boolean;
DrawLock: Byte;
PROCEDURE CheckDraw;
END;
PScroller = ^TScroller;
{---------------------------------------------------------------------------}
{ TListViewer OBJECT - LIST VIEWER OBJECT }
{---------------------------------------------------------------------------}
TYPE
TListViewer = OBJECT (TView)
NumCols : Sw_Integer; { Number of columns }
TopItem : Sw_Integer; { Top most item }
Focused : Sw_Integer; { Focused item }
Range : Sw_Integer; { Range of listview }
HScrollBar: PScrollBar; { Horz scrollbar }
VScrollBar: PScrollBar; { Vert scrollbar }
CONSTRUCTOR Init (Var Bounds: TRect; ANumCols: Sw_Word; AHScrollBar,
AVScrollBar: PScrollBar);
CONSTRUCTOR Load (Var S: TStream);
FUNCTION GetPalette: PPalette; Virtual;
FUNCTION IsSelected (Item: Sw_Integer): Boolean; Virtual;
FUNCTION GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
PROCEDURE DrawFocus; Virtual;
PROCEDURE DrawLoseFocus; Virtual;
PROCEDURE DrawBackGround; Virtual;
PROCEDURE FocusItem (Item: Sw_Integer); Virtual;
PROCEDURE SetTopItem (Item: Sw_Integer);
PROCEDURE SetRange (ARange: Sw_Integer);
PROCEDURE SelectItem (Item: Sw_Integer); Virtual;
PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
PROCEDURE Store (Var S: TStream);
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
PROCEDURE FocusItemNum (Item: Sw_Integer); Virtual;
END;
PListViewer = ^TListViewer;
{---------------------------------------------------------------------------}
{ TWindow OBJECT - WINDOW OBJECT ANCESTOR }
{---------------------------------------------------------------------------}
TYPE
TWindow = OBJECT (TGroup)
Flags : Byte; { Window flags }
Number : Sw_Integer; { Window number }
Palette : Sw_Integer; { Window palette }
ZoomRect: TRect; { Zoom rectangle }
Frame : PFrame; { Frame view object }
Title : PString; { Title string }
CONSTRUCTOR Init (Var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
CONSTRUCTOR Load (Var S: TStream);
DESTRUCTOR Done; Virtual;
FUNCTION GetPalette: PPalette; Virtual;
FUNCTION GetTitle (MaxSize: Sw_Integer): TTitleStr; Virtual;
FUNCTION StandardScrollBar (AOptions: Word): PScrollBar;
PROCEDURE Zoom; Virtual;
PROCEDURE Close; Virtual;
PROCEDURE InitFrame; Virtual;
PROCEDURE DrawBorder; Virtual;
PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
PROCEDURE Store (Var S: TStream);
PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
PROCEDURE SizeLimits (Var Min, Max: TPoint); Virtual;
END;
PWindow = ^TWindow;
{***************************************************************************}
{ INTERFACE ROUTINES }
{***************************************************************************}
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ WINDOW MESSAGE ROUTINES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{-Message------------------------------------------------------------
Message sets up an event record and calls Receiver^.HandleEvent to
handle the event. Message returns nil if Receiver is nil, or if
the event is not handled successfully.
12Sep97 LdB
---------------------------------------------------------------------}
FUNCTION Message (Receiver: PView; What, Command: Word;
InfoPtr: Pointer): Pointer;
{-NewMessage---------------------------------------------------------
NewMessage sets up an event record including the new fields and calls
Receiver^.HandleEvent to handle the event. Message returns nil if
Receiver is nil, or if the event is not handled successfully.
19Sep97 LdB
---------------------------------------------------------------------}
FUNCTION NewMessage (P: PView; What, Command: Word; Id: Sw_Integer; Data: Real;
InfoPtr: Pointer): Pointer;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ VIEW OBJECT REGISTRATION ROUTINES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{-RegisterViews------------------------------------------------------
This registers all the view type objects used in this unit.
11Aug99 LdB
---------------------------------------------------------------------}
PROCEDURE RegisterViews;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ NEW VIEW ROUTINES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{-CreateIdScrollBar--------------------------------------------------
Creates and scrollbar object of the given size and direction and sets
the scrollbar id number.
22Sep97 LdB
---------------------------------------------------------------------}
FUNCTION CreateIdScrollBar (X, Y, Size, Id: Sw_Integer; Horz: Boolean): PScrollBar;
{***************************************************************************}
{ INITIALIZED PUBLIC VARIABLES }
{***************************************************************************}
{---------------------------------------------------------------------------}
{ INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
{---------------------------------------------------------------------------}
CONST
UseNativeClasses: Boolean = True; { Native class modes }
CommandSetChanged: Boolean = False; { Command change flag }
ShowMarkers: Boolean = False; { Show marker state }
ErrorAttr: Byte = $CF; { Error colours }
PositionalEvents: Word = evMouse; { Positional defined }
FocusedEvents: Word = evKeyboard + evCommand; { Focus defined }
MinWinSize: TPoint = (X: 16; Y: 6); { Minimum window size }
ShadowSize: TPoint = (X: 2; Y: 1); { Shadow sizes }
ShadowAttr: Byte = $08; { Shadow attribute }
{ Characters used for drawing selected and default items in }
{ monochrome color sets }
SpecialChars: Array [0..5] Of Char = (#175, #174, #26, #27, ' ', ' ');
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ STREAM REGISTRATION RECORDS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{---------------------------------------------------------------------------}
{ TView STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RView: TStreamRec = (
ObjType: 1; { Register id = 1 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TView)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TView); { Alt style VMT link }
{$ENDIF}
Load: @TView.Load; { Object load method }
Store: @TView.Store { Object store method }
);
{---------------------------------------------------------------------------}
{ TFrame STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RFrame: TStreamRec = (
ObjType: 2; { Register id = 2 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TFrame)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TFrame); { Alt style VMT link }
{$ENDIF}
Load: @TFrame.Load; { Frame load method }
Store: @TFrame.Store { Frame store method }
);
{---------------------------------------------------------------------------}
{ TScrollBar STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RScrollBar: TStreamRec = (
ObjType: 3; { Register id = 3 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TScrollBar)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TScrollBar); { Alt style VMT link }
{$ENDIF}
Load: @TScrollBar.Load; { Object load method }
Store: @TScrollBar.Store { Object store method }
);
{---------------------------------------------------------------------------}
{ TScroller STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RScroller: TStreamRec = (
ObjType: 4; { Register id = 4 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TScroller)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TScroller); { Alt style VMT link }
{$ENDIF}
Load: @TScroller.Load; { Object load method }
Store: @TScroller.Store { Object store method }
);
{---------------------------------------------------------------------------}
{ TListViewer STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RListViewer: TStreamRec = (
ObjType: 5; { Register id = 5 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TListViewer)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TListViewer); { Alt style VMT link }
{$ENDIF}
Load: @TListViewer.Load; { Object load method }
Store: @TLIstViewer.Store { Object store method }
);
{---------------------------------------------------------------------------}
{ TGroup STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RGroup: TStreamRec = (
ObjType: 6; { Register id = 6 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TGroup)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TGroup); { Alt style VMT link }
{$ENDIF}
Load: @TGroup.Load; { Object load method }
Store: @TGroup.Store { Object store method }
);
{---------------------------------------------------------------------------}
{ TWindow STREAM REGISTRATION }
{---------------------------------------------------------------------------}
CONST
RWindow: TStreamRec = (
ObjType: 7; { Register id = 7 }
{$IFDEF BP_VMTLink}
VmtLink: Ofs(TypeOf(TWindow)^); { BP style VMT link }
{$ELSE}
VmtLink: TypeOf(TWindow); { Alt style VMT link }
{$ENDIF}
Load: @TWindow.Load; { Object load method }
Store: @TWindow.Store { Object store method }
);
{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
IMPLEMENTATION
{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
USES
{$IFDEF USE_VIDEO_API}
Video,
{$ENDIF USE_VIDEO_API}
CallSpec;
{***************************************************************************}
{ PRIVATE TYPE DEFINITIONS }
{***************************************************************************}
{---------------------------------------------------------------------------}
{ TFixupList DEFINITION }
{---------------------------------------------------------------------------}
TYPE
TFixupList = ARRAY [1..4096] Of Pointer; { Fix up ptr array }
PFixupList = ^TFixupList; { Ptr to fix up list }
{***************************************************************************}
{ PRIVATE INITIALIZED VARIABLES }
{***************************************************************************}
{---------------------------------------------------------------------------}
{ INITIALIZED DOS/DPMI/WIN/NT/OS2 PRIVATE VARIABLES }
{---------------------------------------------------------------------------}
CONST
TheTopView : PView = Nil; { Top focused view }
LimitsLocked: PView = Nil; { View locking limits }
OwnerGroup : PGroup = Nil; { Used for loading }
FixupList : PFixupList = Nil; { Used for loading }
CurCommandSet: TCommandSet = ([0..255] -
[cmZoom, cmClose, cmResize, cmNext, cmPrev]); { All active but these }
vdInSetCursor = $80; { AVOID RECURSION IN SetCursor }
{***************************************************************************}
{ PRIVATE INTERNAL ROUTINES }
{***************************************************************************}
function posidx(const substr,s : string;idx:sw_integer):sw_integer;
var
i,j : sw_integer;
e : boolean;
begin
i:=idx;
j:=0;
e:=(length(SubStr)>0);
while e and (i<=Length(s)-Length(SubStr)) do
begin
if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then
begin
j:=i;
e:=false;
end;
inc(i);
end;
PosIdx:=j;
end;
{$ifdef UNIX}
const
MouseUsesVideoBuf = true;
{$else not UNIX}
const
MouseUsesVideoBuf = false;
{$endif not UNIX}
procedure DrawScreenBuf;
begin
{$ifdef USE_VIDEO_API}
if (GetLockScreenCount=0) then
begin
If MouseUsesVideoBuf then
begin
LockScreenUpdate;
HideMouse;
ShowMouse;
UnlockScreenUpdate;
end
else
HideMouse;
if TextModeGFV then
UpdateScreen(false)
{$IFDEF GRAPH_API}
else
GraphUpdateScreen(false)
{$ENDIF GRAPH_API}
;
If not MouseUsesVideoBuf then
ShowMouse;
end;
{$endif USE_VIDEO_API}
end;
{***************************************************************************}
{ OBJECT METHODS }
{***************************************************************************}
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TView OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TView--------------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20Jun96 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TView.Init (Var Bounds: TRect);
BEGIN
Inherited Init; { Call ancestor }
DragMode := dmLimitLoY; { Default drag mode }
HelpCtx := hcNoContext; { Clear help context }
State := sfVisible; { Default state }
EventMask := evMouseDown + evKeyDown + evCommand; { Default event masks }
GOptions := goTabSelect; { Set new options }
BackgroundChar := ' ';
SetBounds(Bounds); { Set view bounds }
END;
{--TView--------------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
{---------------------------------------------------------------------------}
{ This load method will read old original TV data from a stream but the }
{ new options and tabmasks are not set so some NEW functionality is not }
{ supported but it should work as per original TV code. }
{---------------------------------------------------------------------------}
CONSTRUCTOR TView.Load (Var S: TStream);
VAR i: Integer;
BEGIN
Inherited Init; { Call ancestor }
S.Read(i, SizeOf(i)); Origin.X:=i; { Read origin x value }
S.Read(i, SizeOf(i)); Origin.Y:=i; { Read origin y value }
S.Read(i, SizeOf(i)); Size.X:=i; { Read view x size }
S.Read(i, SizeOf(i)); Size.Y:=i; { Read view y size }
S.Read(i, SizeOf(i)); Cursor.X:=i; { Read cursor x size }
S.Read(i, SizeOf(i)); Cursor.Y:=i; { Read cursor y size }
S.Read(GrowMode, SizeOf(GrowMode)); { Read growmode flags }
S.Read(DragMode, SizeOf(DragMode)); { Read dragmode flags }
S.Read(HelpCtx, SizeOf(HelpCtx)); { Read help context }
S.Read(State, SizeOf(State)); { Read state masks }
S.Read(Options, SizeOf(Options)); { Read options masks }
S.Read(Eventmask, SizeOf(Eventmask)); { Read event masks }
If (Options AND ofGFVModeView <> 0) Then Begin { STREAM HAS GFV TVIEW }
S.Read(GOptions, SizeOf(GOptions)); { Read new option masks }
S.Read(TabMask, SizeOf(TabMask)); { Read new tab masks }
S.Read(i, SizeOf(i)); RawOrigin.X:=i; { Read raw x origin point }
S.Read(i, SizeOf(i)); RawOrigin.Y:=i; { Read raw y origin point }
S.Read(i, SizeOf(i)); RawSize.X:=i; { Read raw x size }
S.Read(i, SizeOf(i)); RawSize.Y:=i; { Read raw y size }
S.Read(i, SizeOf(i)); ColourOfs:=i; { Read palette offset }
End Else Begin { STREAM HAS OLD TView }
RawOrigin.X := Origin.X * FontWidth; { Set x origin pt }
RawOrigin.Y := Origin.Y * FontHeight; { Set y origin pt }
RawSize.X := (Size.X * FontWidth) - 1; { Calc raw x size }
RawSize.Y := (Size.Y * FontHeight) - 1; { Calc raw y size }
End;
END;
{--TView--------------------------------------------------------------------}
{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Nov99 LdB }
{---------------------------------------------------------------------------}
DESTRUCTOR TView.Done;
VAR P: PComplexArea;
BEGIN
Hide; { Hide the view }
If (Owner <> Nil) Then Owner^.Delete(@Self); { Delete from owner }
While (HoldLimit <> Nil) Do Begin { Free limit memory }
P := HoldLimit^.NextArea; { Hold next pointer }
FreeMem(HoldLimit, SizeOf(TComplexArea)); { Release memory }
HoldLimit := P; { Shuffle to next }
End;
END;
{--TView--------------------------------------------------------------------}
{ Prev -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.Prev: PView;
VAR NP : PView;
BEGIN
Prev := @Self;
NP := Next;
While (NP <> Nil) AND (NP <> @Self) Do
Begin
Prev := NP; { Locate next view }
NP := NP^.Next;
End;
END;
{--TView--------------------------------------------------------------------}
{ Execute -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.Execute: Word;
BEGIN
Execute := cmCancel; { Return cancel }
END;
{--TView--------------------------------------------------------------------}
{ Focus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.Focus: Boolean;
VAR Res: Boolean;
BEGIN
Res := True; { Preset result }
If (State AND (sfSelected + sfModal)=0) Then Begin { Not modal/selected }
If (Owner <> Nil) Then Begin { View has an owner }
Res := Owner^.Focus; { Return focus state }
If Res Then { Owner has focus }
If ((Owner^.Current = Nil) OR { No current view }
(Owner^.Current^.Options AND ofValidate = 0) { Non validating view }
OR (Owner^.Current^.Valid(cmReleasedFocus))) { Okay to drop focus }
Then Select Else Res := False; { Then select us }
End;
End;
Focus := Res; { Return focus result }
END;
{--TView--------------------------------------------------------------------}
{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.DataSize: Sw_Word;
BEGIN
DataSize := 0; { Transfer size }
END;
{--TView--------------------------------------------------------------------}
{ TopView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.TopView: PView;
VAR P: PView;
BEGIN
If (TheTopView = Nil) Then Begin { Check topmost view }
P := @Self; { Start with us }
While (P <> Nil) AND (P^.State AND sfModal = 0) { Check if modal }
Do P := P^.Owner; { Search each owner }
TopView := P; { Return result }
End Else TopView := TheTopView; { Return topview }
END;
{--TView--------------------------------------------------------------------}
{ PrevView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.PrevView: PView;
BEGIN
If (@Self = Owner^.First) Then PrevView := Nil { We are first view }
Else PrevView := Prev; { Return our prior }
END;
{--TView--------------------------------------------------------------------}
{ NextView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.NextView: PView;
BEGIN
If (@Self = Owner^.Last) Then NextView := Nil { This is last view }
Else NextView := Next; { Return our next }
END;
{--TView--------------------------------------------------------------------}
{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.GetHelpCtx: Word;
BEGIN
If (State AND sfDragging <> 0) Then { Dragging state check }
GetHelpCtx := hcDragging Else { Return dragging }
GetHelpCtx := HelpCtx; { Return help context }
END;
{--TView--------------------------------------------------------------------}
{ EventAvail -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.EventAvail: Boolean;
VAR Event: TEvent;
BEGIN
GetEvent(Event); { Get next event }
If (Event.What <> evNothing) Then PutEvent(Event); { Put it back }
EventAvail := (Event.What <> evNothing); { Return result }
END;
{--TView--------------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.GetPalette: PPalette;
BEGIN
GetPalette := Nil; { Return nil ptr }
END;
{--TView--------------------------------------------------------------------}
{ GetColor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.GetColor (Color: Word): Word;
VAR Col: Byte; W: Word; P: PPalette; Q: PView;
BEGIN
W := 0; { Clear colour Sw_Word }
If (Hi(Color) > 0) Then Begin { High colour req }
Col := Hi(Color) + ColourOfs; { Initial offset }
Q := @Self; { Pointer to self }
Repeat
P := Q^.GetPalette; { Get our palette }
If (P <> Nil) Then Begin { Palette is valid }
If (Col <= Length(P^)) Then
Col := Ord(P^[Col]) Else { Return colour }
Col := ErrorAttr; { Error attribute }
End;
Q := Q^.Owner; { Move up to owner }
Until (Q = Nil); { Until no owner }
W := Col SHL 8; { Translate colour }
End;
If (Lo(Color) > 0) Then Begin
Col := Lo(Color) + ColourOfs; { Initial offset }
Q := @Self; { Pointer to self }
Repeat
P := Q^.GetPalette; { Get our palette }
If (P <> Nil) Then Begin { Palette is valid }
If (Col <= Length(P^)) Then
Col := Ord(P^[Col]) Else { Return colour }
Col := ErrorAttr; { Error attribute }
End;
Q := Q^.Owner; { Move up to owner }
Until (Q = Nil); { Until no owner }
End Else Col := ErrorAttr; { No colour found }
GetColor := W OR Col; { Return color }
END;
{--TView--------------------------------------------------------------------}
{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.Valid (Command: Word): Boolean;
BEGIN
Valid := True; { Simply return true }
END;
{--TView--------------------------------------------------------------------}
{ GetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.GetState (AState: Word): Boolean;
BEGIN
GetState := State AND AState = AState; { Check states equal }
END;
{--TView--------------------------------------------------------------------}
{ TextWidth -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Nov99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.TextWidth (Txt: String): Sw_Integer;
VAR I: Sw_Integer; S: String;
BEGIN
S := Txt; { Transfer text }
Repeat
I := Pos('~', S); { Check for tilde }
If (I <> 0) Then System.Delete(S, I, 1); { Remove the tilde }
Until (I = 0); { Remove all tildes }
TextWidth := Length(S) * SysFontWidth; { Calc text length }
END;
{--TView--------------------------------------------------------------------}
{ MouseInView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.MouseInView (Point: TPoint): Boolean;
BEGIN
MouseInView := False; { Preset false }
If (Point.X < RawOrigin.X) Then Exit; { Point to left }
If (Point.X > (RawOrigin.X+RawSize.X)) Then Exit; { Point to right }
If (Point.Y < RawOrigin.Y) Then Exit; { Point is above }
If (Point.Y > (RawOrigin.Y+RawSize.Y)) Then Exit; { Point is below }
MouseInView := True; { Return true }
END;
{--TView--------------------------------------------------------------------}
{ CommandEnabled -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.CommandEnabled(Command: Word): Boolean;
BEGIN
CommandEnabled := (Command > 255) OR
(Command IN CurCommandSet); { Check command }
END;
{--TView--------------------------------------------------------------------}
{ OverLapsArea -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.OverlapsArea (X1, Y1, X2, Y2: Sw_Integer): Boolean;
BEGIN
OverLapsArea := False; { Preset false }
If TextModeGFV then Begin
If (Origin.X > X2) Then Exit; { Area to the left }
If ((Origin.X + Size.X) < X1) Then Exit; { Area to the right }
If (Origin.Y > Y2) Then Exit; { Area is above }
If ((Origin.Y + Size.Y) < Y1) Then Exit; { Area is below }
End Else Begin
If (RawOrigin.X > X2) Then Exit; { Area to the left }
If ((RawOrigin.X + RawSize.X) < X1) Then Exit; { Area to the right }
If (RawOrigin.Y > Y2) Then Exit; { Area is above }
If ((RawOrigin.Y + RawSize.Y) < Y1) Then Exit; { Area is below }
End;
OverLapsArea := True; { Return true }
END;
{--TView--------------------------------------------------------------------}
{ MouseEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TView.MouseEvent (Var Event: TEvent; Mask: Word): Boolean;
BEGIN
Repeat
GetEvent(Event); { Get next event }
Until (Event.What AND (Mask OR evMouseUp) <> 0); { Wait till valid }
MouseEvent := Event.What <> evMouseUp; { Return result }
END;
{--TView--------------------------------------------------------------------}
{ Hide -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Hide;
BEGIN
If (State AND sfVisible <> 0) Then { View is visible }
SetState(sfVisible, False); { Hide the view }
END;
{--TView--------------------------------------------------------------------}
{ Show -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Show;
BEGIN
If (State AND sfVisible = 0) Then { View not visible }
SetState(sfVisible, True); { Show the view }
END;
{--TView--------------------------------------------------------------------}
{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Draw;
BEGIN { Abstract method }
END;
procedure TView.ResetCursor;
const
sfV_CV_F:word = sfVisible + sfCursorVis + sfFocused;
var
p,p2 : PView;
G : PGroup;
cur : TPoint;
function Check0:boolean;
var
res : byte;
begin
res:=0;
while res=0 do
begin
p:=p^.next;
if p=p2 then
begin
p:=P^.owner;
res:=1
end
else
if ((p^.state and sfVisible)<>0) and
(cur.x>=p^.origin.x) and
(cur.x<p^.size.x+p^.origin.x) and
(cur.y>=p^.origin.y) and
(cur.y<p^.size.y+p^.origin.y) then
res:=2;
end;
Check0:=res=2;
end;
begin
if (not TextModeGFV) and not UseFixedFont then
exit;
{$ifdef USE_VIDEO_API}
if ((state and sfV_CV_F) = sfV_CV_F) then
begin
p:=@Self;
cur:=cursor;
{ in FVISION origin is always relative to screen corner
for inserted views PM }
inc(cur.X,p^.origin.X);
inc(cur.Y,p^.origin.Y);
while true do
begin
if (cur.x<p^.origin.x) or (cur.x>=p^.origin.x+p^.size.x) or
(cur.y<p^.origin.y) or (cur.y>=p^.origin.y+p^.size.y) then
break;
p2:=p;
G:=p^.owner;
if G=Nil then { top view }
begin
if TextModeGFV then
Video.SetCursorPos(cur.x,cur.y)
{$IFDEF GRAPH_API}
else
GFVGraph.SetCursorPos(cur.x,cur.y)
{$ENDIF GRAPH_API}
;
if (state and sfCursorIns)<>0 then
begin
if TextModeGFV then
Video.SetCursorType(crBlock)
{$IFDEF GRAPH_API}
else
GFVGraph.SetCursorType(crBlock)
{$ENDIF GRAPH_API}
;
end
else
begin
if TextModeGFV then
Video.SetCursorType(crUnderline)
{$IFDEF GRAPH_API}
else
GFVGraph.SetCursorType(crUnderline)
{$ENDIF GRAPH_API}
;
end;
exit;
end;
if (G^.state and sfVisible)=0 then
break;
p:=G^.Last;
if Check0 then
break;
end; { while }
end; { if }
if TextModeGFV then
Video.SetCursorType(crHidden)
{$IFDEF GRAPH_API}
else
GFVGraph.SetCursorType(crHidden)
{$ENDIF GRAPH_API}
;
{$endif USE_VIDEO_API}
end;
{--TView--------------------------------------------------------------------}
{ Select -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Select;
BEGIN
If (Options AND ofSelectable <> 0) Then { View is selectable }
If (Options AND ofTopSelect <> 0) Then MakeFirst { Top selectable }
Else If (Owner <> Nil) Then { Valid owner }
Owner^.SetCurrent(@Self, NormalSelect); { Make owners current }
END;
{--TView--------------------------------------------------------------------}
{ Awaken -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Awaken;
BEGIN { Abstract method }
END;
{--TView--------------------------------------------------------------------}
{ DrawView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawView;
VAR ViewPort: ViewPortType; { Common variables }
Parent : PGroup;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) AND { View is exposed }
(State AND sfIconised = 0) Then Begin { View not iconised }
SetViewLimits; { Set view limits }
GetViewSettings(ViewPort, TextModeGFV); { Get set viewport }
If OverlapsArea(ViewPort.X1, ViewPort.Y1,
ViewPort.X2, ViewPort.Y2) Then
Begin { Must be in area }
Parent:=Owner;
While Assigned(Parent) do Begin
If (Parent^.LockFlag>0) then
Begin
If (DrawMask = 0) OR (DrawMask = vdNoChild) then
SetDrawMask(vdAll);
ReleaseViewLimits;
exit;
End;
Parent:=Parent^.Owner;
End;
{$ifdef USE_VIDEO_API}
LockScreenUpdate; { don't update the screen yet }
{$endif USE_VIDEO_API}
HideMouseCursor; { Hide mouse cursor }
If (DrawMask = 0) OR (DrawMask = vdNoChild) { No special masks set }
{ OR Assigned(LimitsLocked) }
Then Begin { Treat as a full redraw }
DrawBackGround; { Draw background }
Draw; { Draw interior }
If (GOptions AND goDrawFocus <> 0) Then
DrawFocus; { Draw focus }
If (State AND sfCursorVis <> 0) Then
DrawCursor; { Draw any cursor }
If (Options AND ofFramed <> 0) OR
(GOptions AND goThickFramed <> 0) { View has border }
Then DrawBorder; { Draw border }
{$ifndef NoShadow}
If ((State AND sfShadow) <> 0) AND
(GOptions And goNoShadow = 0) Then
DrawShadow;
{$endif ndef NoShadow}
End Else Begin { Masked draws only }
If (DrawMask AND vdBackGnd <> 0) Then { Chk background mask }
Begin
DrawMask := DrawMask and Not vdBackGnd;
DrawBackGround; { Draw background }
end;
If (DrawMask AND vdInner <> 0) Then { Check Inner mask }
Begin
DrawMask := DrawMask and Not vdInner;
Draw; { Draw interior }
End;
If (DrawMask AND vdFocus <> 0)
AND (GOptions AND goDrawFocus <> 0) then
Begin
DrawMask := DrawMask and Not vdFocus;
DrawFocus; { Check focus mask }
End;
if not TextModeGFV then
begin
If (DrawMask AND vdCursor <> 0) Then { Check cursor mask }
Begin
DrawMask := DrawMask and Not vdCursor;
DrawCursor; { Draw any cursor }
End;
end;
If (DrawMask AND vdBorder <> 0) Then { Check border mask }
Begin
DrawMask := DrawMask and Not vdBorder;
DrawBorder; { Draw border }
End;
{$ifndef NoShadow}
If ((State AND sfShadow) <> 0) AND
(DrawMask AND vdShadow <> 0) AND
(GOptions And goNoShadow = 0) AND
(not assigned(Owner) OR (Owner^.GOptions And goNoShadow = 0)) Then
Begin
DrawMask := DrawMask and Not vdShadow;
DrawShadow;
End;
{$endif ndef NoShadow}
End;
ShowMouseCursor; { Show mouse cursor }
{$ifdef USE_VIDEO_API}
UnlockScreenUpdate;
{$endif USE_VIDEO_API}
if TextModeGFV or UseFixedFont then
begin
DrawScreenBuf;
If (DrawMask AND vdCursor <> 0) Then { Check cursor mask }
Begin
DrawMask := DrawMask and Not vdCursor;
DrawCursor; { Draw any cursor }
End;
end;
End;
ReleaseViewLimits; { Release the limits }
End;
DrawMask := 0; { Clear the draw mask }
END;
{--TView--------------------------------------------------------------------}
{ MakeFirst -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.MakeFirst;
BEGIN
If (Owner <> Nil) Then Begin { Must have owner }
PutInFrontOf(Owner^.First); { Float to the top }
End;
END;
{--TView--------------------------------------------------------------------}
{ DrawFocus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawFocus;
BEGIN { Abstract method }
END;
{--TView--------------------------------------------------------------------}
{ DrawCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawCursor;
BEGIN { Abstract method }
if State and sfFocused <> 0 then
ResetCursor;
END;
{--TView--------------------------------------------------------------------}
{ DrawBorder -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawBorder;
BEGIN
If (TextModeGFV = FALSE) Then Begin { GRAPHICS GFV MODE }
BiColorRectangle(0, 0, RawSize.X, RawSize.Y,
White, DarkGray, False); { Draw 3d effect }
If (GOptions AND goThickFramed <> 0) Then Begin { Thick frame at work }
GraphRectangle(1, 1, RawSize.X-1, RawSize.Y-1,
LightGray); { Draw frame part 1 }
GraphRectangle(2, 2, RawSize.X-2, RawSize.Y-2,
LightGray); { Fraw frame part 2 }
BiColorRectangle(3, 3, RawSize.X-3, RawSize.Y-3,
White, DarkGray, True); { Draw highlights }
End;
End;
{ TView DrawBorder is empty for TextModeGFV }
END;
PROCEDURE TView.DrawShadow;
VAR X1, Y1, X2, Y2 : Sw_Integer;
BEGIN
{$ifdef DEBUG}
if WriteDebugInfo then
Begin
Writeln(stderr,'TView(',hexstr(longint(@self),8),')');
Writeln(stderr,'Object Type(',hexstr(plongint(@self)^,8),')');
Writeln(stderr,'DrawShadow');
End;
{$endif DEBUG}
If not TextModeGFV then
exit;
If Assigned(Owner) Then Begin
X1:=RawOrigin.X+RawSize.X+1;
X2:=X1+ShadowSize.X*SysFontWidth;
Y1:=RawOrigin.Y+SysFontHeight;
Y2:=RawOrigin.Y+RawSize.Y+1+ShadowSize.Y*SysFontHeight;
GOptions := GOptions OR goNoShadow;
Owner^.GOptions := Owner^.GOptions OR goNoShadow;
Owner^.RedrawArea(X1,Y1,X2,Y2);
WriteShadow(X1 div SysFontWidth, Y1 div SysFontHeight,
X2 div SysFontWidth, Y2 div SysFontHeight);
X1:=RawOrigin.X+SysFontWidth;
X2:=RawOrigin.X+RawSize.X+1;
Y1:=RawOrigin.Y+RawSize.Y+1;
Y2:=RawOrigin.Y+RawSize.Y+1+ShadowSize.Y*SysFontHeight;
Owner^.RedrawArea(X1,Y1,X2,Y2);
WriteShadow(X1 div SysFontWidth, Y1 div SysFontHeight,
X2 div SysFontWidth, Y2 div SysFontHeight);
GOptions := GOptions AND not goNoShadow;
Owner^.GOptions := Owner^.GOptions AND not goNoShadow;
End;
END;
{--TView--------------------------------------------------------------------}
{ HideCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.HideCursor;
BEGIN
SetState(sfCursorVis , False); { Hide the cursor }
END;
{--TView--------------------------------------------------------------------}
{ ShowCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ShowCursor;
BEGIN
SetState(sfCursorVis , True); { Show the cursor }
END;
{--TView--------------------------------------------------------------------}
{ BlockCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.BlockCursor;
BEGIN
SetState(sfCursorIns, True); { Set insert mode }
END;
{--TView--------------------------------------------------------------------}
{ NormalCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.NormalCursor;
BEGIN
SetState(sfCursorIns, False); { Clear insert mode }
END;
{--TView--------------------------------------------------------------------}
{ FocusFromTop -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11Aug99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.FocusFromTop;
BEGIN
If (Owner <> Nil) AND
(Owner^.State AND sfSelected = 0)
Then Owner^.Select;
If (State AND sfFocused = 0) Then Focus;
If (State AND sfSelected = 0) Then Select;
END;
{--TView--------------------------------------------------------------------}
{ SetViewLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetViewLimits;
VAR X1, Y1, X2, Y2: Sw_Integer; P: PGroup; ViewPort: ViewPortType; Ca: PComplexArea;
BEGIN
{$ifndef PPC_FPC}
If (MaxAvail >= SizeOf(TComplexArea)) Then
{$endif}
Begin { Check enough memory }
GetMem(Ca, SizeOf(TComplexArea)); { Allocate memory }
GetViewSettings(ViewPort, TextModeGFV or UseFixedFont); { Fetch view port }
Ca^.X1 := ViewPort.X1; { Hold current X1 }
Ca^.Y1 := ViewPort.Y1; { Hold current Y1 }
Ca^.X2 := ViewPort.X2; { Hold current X2 }
Ca^.Y2 := ViewPort.Y2; { Hold current Y2 }
Ca^.NextArea := HoldLimit; { Pointer to next }
HoldLimit := Ca; { Move down chain }
X1 := RawOrigin.X; { Xfer x raw origin }
Y1 := RawOrigin.Y; { Xfer y raw origin }
X2 := X1 + RawSize.X; { Calc right value }
Y2 := Y1 + RawSize.Y; { Calc lower value }
P := Owner; { Start on owner }
While (P <> Nil) Do Begin { While owner valid }
If (X1 < P^.RawOrigin.X) Then
X1 := P^.RawOrigin.X; { X minimum contain }
If (Y1 < P^.RawOrigin.Y) Then
Y1 := P^.RawOrigin.Y; { Y minimum contain }
If (X2 > P^.RawOrigin.X + P^.RawSize.X)
Then X2 := P^.RawOrigin.X + P^.RawSize.X; { X maximum contain }
If (Y2 > P^.RawOrigin.Y + P^.RawSize.Y)
Then Y2 := P^.RawOrigin.Y + P^.RawSize.Y; { Y maximum contain }
P := P^.Owner; { Move to owners owner }
End;
If TextModeGFV or UseFixedFont then Begin
X1 := X1 div SysFontWidth;
X2 := (X2 +SysFontWidth - 1) div SysFontWidth;
Y1 := Y1 div SysFontHeight;
Y2 := (Y2 +SysFontHeight -1) div SysFontHeight;
End;
If (LimitsLocked <> Nil) Then Begin { Locked = area redraw }
If (X2 < ViewPort.X1) Then Exit; { View left of locked }
If (X1 > ViewPort.X2) Then Exit; { View right of locked }
If (Y2 < ViewPort.Y1) Then Exit; { View above locked }
If (Y1 > ViewPort.Y2) Then Exit; { View below locked }
If (X1 < ViewPort.X1) Then X1 := ViewPort.X1; { Adjust x1 to locked }
If (Y1 < ViewPort.Y1) Then Y1 := ViewPort.Y1; { Adjust y1 to locked }
If (X2 > ViewPort.X2) Then X2 := ViewPort.X2; { Adjust x2 to locked }
If (Y2 > ViewPort.Y2) Then Y2 := ViewPort.Y2; { Adjust y2 to locked }
End;
SetViewPort(X1, Y1, X2, Y2, ClipOn, TextModeGFV or UseFixedFont);{ Set new clip limits }
End;
END;
{--TView--------------------------------------------------------------------}
{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 21Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawBackGround;
VAR Bc: Byte; X1, Y1, X2, Y2: Sw_Integer; ViewPort: ViewPortType;
X, Y: Sw_Integer;
Buf : TDrawBuffer;
BEGIN
If (GOptions AND goNoDrawView = 0) Then Begin { Non draw views exit }
If (State AND sfDisabled = 0) Then
Bc := GetColor(1) AND $F0 SHR 4 Else { Select back colour }
Bc := GetColor(4) AND $F0 SHR 4; { Disabled back colour }
GetViewSettings(ViewPort, TextModeGFV or UseFixedFont); { Get view settings }
If not TextModeGFV and not UseFixedFont Then Begin { GRAPHICS MODE GFV }
If (ViewPort.X1 <= RawOrigin.X) Then X1 := 0 { Right to left edge }
Else X1 := ViewPort.X1-RawOrigin.X; { Offset from left }
If (ViewPort.Y1 <= RawOrigin.Y) Then Y1 := 0 { Right to top edge }
Else Y1 := ViewPort.Y1-RawOrigin.Y; { Offset from top }
If (ViewPort.X2 >= RawOrigin.X+RawSize.X) Then
X2 := RawSize.X Else { Right to right edge }
X2 := ViewPort.X2-RawOrigin.X; { Offset from right }
If (ViewPort.Y2 >= RawOrigin.Y+RawSize.Y) Then
Y2 := RawSize.Y Else { Right to bottom edge }
Y2 := ViewPort.Y2-RawOrigin.Y; { Offset from bottom }
SetFillStyle(SolidFill, Bc); { Set fill colour }
Bar(0, 0, X2-X1, Y2-Y1); { Clear the area }
End Else Begin { TEXT MODE GFV }
If (ViewPort.X1 <= Origin.X) Then
X1 := Origin.X { Right to left edge }
Else X1 := ViewPort.X1; { Offset from left }
If (ViewPort.Y1 <= Origin.Y) Then
Y1 := Origin.Y { Right to top edge }
Else Y1 := ViewPort.Y1; { Offset from top }
If (ViewPort.X2 >= Origin.X+Size.X) Then
X2 := Origin.X + Size.X Else { Right to right edge }
X2 := ViewPort.X2; { Offset from right }
If (ViewPort.Y2 >= Origin.Y+Size.Y) Then
Y2 := Origin.Y + Size.Y Else { Right to bottom edge }
Y2 := ViewPort.Y2; { Offset from bottom }
If (State AND sfDisabled = 0) Then
Bc := GetColor(1) Else { Select back colour }
Bc := GetColor(4); { Disabled back colour }
For X := X1 To X2 Do Begin
Buf[X-X1]:=(Bc shl 8) or ord(BackgroundChar){not a directive,was $20};
End;
For Y := Y1 To Y2 Do Begin
WriteAbs(X1,Y, X2-X1, Buf);
End;
DrawScreenBuf;
End;
End;
END;
{--TView--------------------------------------------------------------------}
{ ReleaseViewLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ReleaseViewLimits;
VAR P: PComplexArea;
BEGIN
P := HoldLimit; { Transfer pointer }
If (P <> Nil) Then Begin { Valid complex area }
HoldLimit := P^.NextArea; { Move to prior area }
SetViewPort(P^.X1, P^.Y1, P^.X2, P^.Y2, ClipOn,
TextModeGFV or UseFixedFont); { Restore clip limits }
FreeMem(P, SizeOf(TComplexArea)); { Release memory }
End;
END;
{--TView--------------------------------------------------------------------}
{ MoveTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.MoveTo (X, Y: Sw_Integer);
VAR R: TRect;
BEGIN
R.Assign(X, Y, X + Size.X, Y + Size.Y); { Assign area }
Locate(R); { Locate the view }
END;
{--TView--------------------------------------------------------------------}
{ GrowTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GrowTo (X, Y: Sw_Integer);
VAR R: TRect;
BEGIN
R.Assign(Origin.X, Origin.Y, Origin.X + X,
Origin.Y + Y); { Assign area }
Locate(R); { Locate the view }
END;
{--TView--------------------------------------------------------------------}
{ SetDrawMask -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetDrawMask (Mask: Byte);
VAR
OldMask : byte;
BEGIN
If (Options AND ofFramed = 0) AND { Check for no frame }
(GOptions AND goThickFramed = 0) AND { Check no thick frame }
(GOptions AND goTitled = 0) Then { Check for title }
Mask := Mask AND NOT vdBorder; { Clear border draw }
If (State AND sfCursorVis = 0) Then { Check for no cursor }
Mask := Mask AND NOT vdCursor; { Clear cursor draw }
If (GOptions AND goDrawFocus = 0) Then { Check no focus draw }
Mask := Mask AND NOT vdFocus; { Clear focus draws }
OldMask:=DrawMask;
DrawMask := DrawMask OR Mask; { Set draw masks }
END;
{--TView--------------------------------------------------------------------}
{ EndModal -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.EndModal (Command: Word);
VAR P: PView;
BEGIN
P := TopView; { Get top view }
If (P <> Nil) Then P^.EndModal(Command); { End modal operation }
END;
{--TView--------------------------------------------------------------------}
{ SetCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetCursor (X, Y: Sw_Integer);
BEGIN
Cursor.X := X; { New x position }
Cursor.Y := Y; { New y position }
If ((DrawMask and vdInSetCursor)=0) and (State AND sfCursorVis <> 0) Then
Begin { Cursor visible }
if TextModeGFV or UseFixedFont then
ResetCursor
else
begin
SetDrawMask(vdCursor or vdInSetCursor); { Set draw mask }
DrawView; { Draw the cursor }
DrawMask:=DrawMask and not vdInSetCursor;
end;
End;
END;
{--TView--------------------------------------------------------------------}
{ PutInFrontOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.PutInFrontOf (Target: PView);
VAR P, LastView: PView;
BEGIN
If (Owner <> Nil) AND (Target <> @Self) AND
(Target <> NextView) AND ((Target = Nil) OR
(Target^.Owner = Owner)) Then { Check validity }
If (State AND sfVisible = 0) Then Begin { View not visible }
Owner^.RemoveView(@Self); { Remove from list }
Owner^.InsertView(@Self, Target); { Insert into list }
End Else Begin
LastView := NextView; { Hold next view }
If (LastView <> Nil) Then Begin { Lastview is valid }
P := Target; { P is target }
While (P <> Nil) AND (P <> LastView)
Do P := P^.NextView; { Find our next view }
If (P = Nil) Then LastView := Target; { Lastview is target }
End;
State := State AND NOT sfVisible; { Temp stop drawing }
If (LastView = Target) Then
If (Owner <> Nil) Then Owner^.ReDrawArea(
RawOrigin.X, RawOrigin.Y, RawOrigin.X + RawSize.X,
RawOrigin.Y + RawSize.Y); { Redraw old area }
Owner^.Lock;
Owner^.RemoveView(@Self); { Remove from list }
Owner^.InsertView(@Self, Target); { Insert into list }
State := State OR sfVisible; { Allow drawing again }
If (LastView <> Target) Then
Begin
SetDrawMask(vdAll);
DrawView; { Draw the view now }
End;
If (Options AND ofSelectable <> 0) Then { View is selectable }
If (Owner <> Nil) Then Owner^.ResetCurrent; { Reset current }
Owner^.Unlock;
End;
END;
{ ******************************* REMARK ****************************** }
{ The original TV origin data is only adjusted incase the user uses }
{ the values directly. New views should rely only on RawOrigin values. }
{ ****************************** END REMARK *** Leon de Boer, 15May98 * }
{--TView--------------------------------------------------------------------}
{ DisplaceBy -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DisplaceBy (Dx, Dy: Sw_Integer);
BEGIN
RawOrigin.X := RawOrigin.X + Dx; { Displace raw x }
RawOrigin.Y := RawOrigin.Y + Dy; { Displace raw y }
Origin.X := RawOrigin.X DIV FontWidth; { Calc new x origin }
Origin.Y := RawOrigin.Y DIV FontHeight; { Calc new y origin }
END;
{--TView--------------------------------------------------------------------}
{ SetCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetCommands (Commands: TCommandSet);
BEGIN
CommandSetChanged := CommandSetChanged OR
(CurCommandSet <> Commands); { Set change flag }
CurCommandSet := Commands; { Set command set }
END;
{--TView--------------------------------------------------------------------}
{ ReDrawArea -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ReDrawArea (X1, Y1, X2, Y2: Sw_Integer);
var
StoreDrawMask : Byte;
VAR HLimit: PView; ViewPort: ViewPortType;
BEGIN
{$ifdef DEBUG}
if WriteDebugInfo then
Begin
Writeln(stderr,'TView(',hexstr(longint(@self),8),')');
Writeln(stderr,'Object Type(',hexstr(plongint(@self)^,8),')');
Writeln(stderr,'ReDrawArea(',X1,',',Y1,',',X2,',',Y2,')');
End;
{$endif DEBUG}
GetViewSettings(ViewPort, TextModeGFV); { Hold view port }
If TextModeGFV then Begin
X1 := X1 div SysFontWidth;
X2 := (X2 +SysFontWidth - 1) div SysFontWidth;
Y1 := Y1 div SysFontHeight;
Y2 := (Y2 +SysFontHeight -1) div SysFontHeight;
End;
SetViewPort(X1, Y1, X2, Y2, ClipOn, TextModeGFV); { Set new clip limits }
HLimit := LimitsLocked; { Hold lock limits }
LimitsLocked := @Self; { We are the lock view }
StoreDrawMask:=DrawMask;
DrawMask:=vdAll;
DrawView; { Redraw the area }
DrawMask:=StoreDrawMask;
LimitsLocked := HLimit; { Release our lock }
SetViewPort(ViewPort.X1, ViewPort.Y1,
ViewPort.X2, ViewPort.Y2, ClipOn, TextModeGFV); { Reset old limits }
END;
{--TView--------------------------------------------------------------------}
{ EnableCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.EnableCommands (Commands: TCommandSet);
BEGIN
CommandSetChanged := CommandSetChanged OR
(CurCommandSet * Commands <> Commands); { Set changed flag }
CurCommandSet := CurCommandSet + Commands; { Update command set }
END;
{--TView--------------------------------------------------------------------}
{ DisableCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DisableCommands (Commands: TCommandSet);
BEGIN
CommandSetChanged := CommandSetChanged OR
(CurCommandSet * Commands <> []); { Set changed flag }
CurCommandSet := CurCommandSet - Commands; { Update command set }
END;
{--TView--------------------------------------------------------------------}
{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetState (AState: Word; Enable: Boolean);
VAR OldState, Command: Word;
ShouldDraw : Boolean;
BEGIN
OldState := State;
If Enable Then State := State OR AState { Set state mask }
Else State := State AND NOT AState; { Clear state mask }
ShouldDraw:=false;
If (AState AND sfVisible <> 0) Then Begin { Visibilty change }
If (Owner <> Nil) AND { valid owner }
(Owner^.State AND sfExposed <> 0) { If owner exposed }
Then SetState(sfExposed, Enable); { Expose this view }
If Enable Then DrawView Else { Draw the view }
If (Owner <> Nil) Then Owner^.ReDrawArea( { Owner valid }
RawOrigin.X, RawOrigin.Y,
RawOrigin.X + RawSize.X + ShadowSize.X*SysFontWidth,
RawOrigin.Y + RawSize.Y + ShadowSize.Y*SysFontHeight); { Owner redraws area }
If (Options AND ofSelectable <> 0) Then { View is selectable }
If (Owner <> Nil) Then Owner^.ResetCurrent; { Reset selected }
End;
If (AState AND sfFocused <> 0) Then Begin { Focus change }
If (Owner <> Nil) Then Begin { Owner valid }
If Enable Then Command := cmReceivedFocus { View gaining focus }
Else Command := cmReleasedFocus; { View losing focus }
Message(Owner, evBroadcast, Command, @Self); { Send out message }
SetDrawMask(vdBorder); { Set border draw mask }
ShouldDraw:=true;
End;
If (GOptions AND goDrawFocus <> 0) AND
(((AState XOR OldState) AND sfFocused) <> 0) Then Begin { Draw focus view }
SetDrawMask(vdFocus); { Set focus draw mask }
ShouldDraw:=true;
End;
End;
If (AState AND (sfCursorVis + sfCursorIns) <> 0) and { Change cursor state }
(OldState<>State)
Then Begin
if TextModeGFV or UseFixedFont then
ResetCursor
else
begin
SetDrawMask(vdCursor); { Set cursor draw mask }
ShouldDraw:=true;
end;
End;
If ShouldDraw then
begin
DrawView; { Redraw the border }
end;
END;
{--TView--------------------------------------------------------------------}
{ SetCmdState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetCmdState (Commands: TCommandSet; Enable: Boolean);
BEGIN
If Enable Then EnableCommands(Commands) { Enable commands }
Else DisableCommands(Commands); { Disable commands }
END;
{--TView--------------------------------------------------------------------}
{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetData (Var Rec);
BEGIN { Abstract method }
END;
{--TView--------------------------------------------------------------------}
{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetData (Var Rec);
BEGIN { Abstract method }
END;
{--TView--------------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
{---------------------------------------------------------------------------}
{ You can save data to the stream compatable with the old original TV by }
{ temporarily turning off the ofGFVModeView making the call to this store }
{ routine and resetting the ofGFVModeView flag after the call. }
{---------------------------------------------------------------------------}
PROCEDURE TView.Store (Var S: TStream);
VAR SaveState: Word;
i: integer;
BEGIN
SaveState := State; { Hold current state }
State := State AND NOT (sfActive OR sfSelected OR
sfFocused OR sfExposed); { Clear flags }
i:=Origin.X;S.Write(i, SizeOf(i)); { Write view x origin }
i:=Origin.Y;S.Write(i, SizeOf(i)); { Write view y origin }
i:=Size.X;S.Write(i, SizeOf(i)); { Write view x size }
i:=Size.Y;S.Write(i, SizeOf(i)); { Write view y size }
i:=Cursor.X;S.Write(i, SizeOf(i)); { Write cursor x size }
i:=Cursor.Y;S.Write(i, SizeOf(i)); { Write cursor y size }
S.Write(GrowMode, SizeOf(GrowMode)); { Write growmode flags }
S.Write(DragMode, SizeOf(DragMode)); { Write dragmode flags }
S.Write(HelpCtx, SizeOf(HelpCtx)); { Write help context }
S.Write(State, SizeOf(State)); { Write state masks }
S.Write(Options, SizeOf(Options)); { Write options masks }
S.Write(Eventmask, SizeOf(Eventmask)); { Write event masks }
If (Options AND ofGFVModeView <> 0) Then Begin { GFV GRAPHICAL TVIEW }
S.Write(GOptions, SizeOf(GOptions)); { Write new option masks }
S.Write(TabMask, SizeOf(TabMask)); { Write new tab masks }
i:=RawOrigin.X;S.Write(i, SizeOf(i)); { Write raw origin x point }
i:=RawOrigin.Y;S.Write(i, SizeOf(i)); { Write raw origin y point }
i:=RawSize.X;S.Write(i, SizeOf(i)); { Write raw x size }
i:=RawSize.Y;S.Write(i, SizeOf(i)); { Write raw y size }
i:=ColourOfs;S.Write(i, SizeOf(i)); { Write Palette offset }
End;
State := SaveState; { Reset state masks }
END;
{--TView--------------------------------------------------------------------}
{ Locate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Locate (Var Bounds: TRect);
VAR
X1, Y1, X2, Y2: Sw_Integer;
Min, Max: TPoint; R: TRect;
FUNCTION Range(Val, Min, Max: Sw_Integer): Sw_Integer;
BEGIN
If (Val < Min) Then Range := Min Else { Value to small }
If (Val > Max) Then Range := Max Else { Value to large }
Range := Val; { Value is okay }
END;
BEGIN
X1 := RawOrigin.X; { Current x origin }
Y1 := RawOrigin.Y; { Current y origin }
X2 := RawOrigin.X + RawSize.X; { Current x size }
Y2 := RawOrigin.Y + RawSize.Y; { Current y size }
SizeLimits(Min, Max); { Get size limits }
Bounds.B.X := Bounds.A.X + Range(Bounds.B.X -
Bounds.A.X, Min.X, Max.X); { X bound limit }
Bounds.B.Y := Bounds.A.Y + Range(Bounds.B.Y
- Bounds.A.Y, Min.Y, Max.Y); { Y bound limit }
GetBounds(R); { Current bounds }
If NOT Bounds.Equals(R) Then Begin { Size has changed }
ChangeBounds(Bounds); { Change bounds }
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) AND (Owner <> Nil) { Check view exposed }
Then Owner^.ReDrawArea(X1, Y1, X2, Y2); { Owner redraw }
DrawView; { Redraw the view }
End;
END;
{--TView--------------------------------------------------------------------}
{ KeyEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.KeyEvent (Var Event: TEvent);
BEGIN
Repeat
GetEvent(Event); { Get next event }
Until (Event.What = evKeyDown); { Wait till keydown }
END;
{--TView--------------------------------------------------------------------}
{ GetEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetEvent (Var Event: TEvent);
BEGIN
If (Owner <> Nil) Then Owner^.GetEvent(Event); { Event from owner }
END;
{--TView--------------------------------------------------------------------}
{ PutEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.PutEvent (Var Event: TEvent);
BEGIN
If (Owner <> Nil) Then Owner^.PutEvent(Event); { Put in owner }
END;
{--TView--------------------------------------------------------------------}
{ GetExtent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetExtent (Var Extent: TRect);
BEGIN
Extent.A.X := 0; { Zero x field }
Extent.A.Y := 0; { Zero y field }
Extent.B.X := Size.X; { Return x size }
Extent.B.Y := Size.Y; { Return y size }
END;
{--TView--------------------------------------------------------------------}
{ GetBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetBounds (Var Bounds: TRect);
BEGIN
Bounds.A := Origin; { Get first corner }
Bounds.B.X := Origin.X + Size.X; { Calc corner x value }
Bounds.B.Y := Origin.Y + Size.Y; { Calc corner y value }
If (Owner <> Nil) Then
Bounds.Move(-Owner^.Origin.X, -Owner^.Origin.Y); { Sub owner offset }
END;
{--TView--------------------------------------------------------------------}
{ SetBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SetBounds (Var Bounds: TRect);
VAR D, COrigin: TPoint;
BEGIN
{ Remove shadow first }
if (State and (sfShadow or sfVisible or sfExposed) =
(sfShadow or sfVisible or sfExposed)) and
assigned(Owner) then
begin
State:= State and not sfShadow;
Owner^.ReDrawArea(RawOrigin.X + RawSize.X, RawOrigin.Y,
RawOrigin.X + RawSize.X + ShadowSize.X*SysFontWidth,
RawOrigin.Y + RawSize.Y + ShadowSize.Y*SysFontHeight); { Owner redraws area }
Owner^.ReDrawArea(RawOrigin.X, RawOrigin.Y + RawSize.Y,
RawOrigin.X + RawSize.X + ShadowSize.X*SysFontWidth,
RawOrigin.Y + RawSize.Y + ShadowSize.Y*SysFontHeight); { Owner redraws area }
State:= State or sfShadow;
end;
If (Bounds.B.X > 0) AND (Bounds.B.Y > 0) { Normal text co-ords }
AND (GOptions AND goGraphView = 0) Then Begin { Normal text view }
If (Owner <> Nil) Then Begin { Owner is valid }
COrigin.X := Origin.X - Owner^.Origin.X; { Corrected x origin }
COrigin.Y := Origin.Y - Owner^.Origin.Y; { Corrected y origin }
D.X := Bounds.A.X - COrigin.X; { X origin disp }
D.Y := Bounds.A.Y - COrigin.Y; { Y origin disp }
If ((D.X <> 0) OR (D.Y <> 0)) Then
DisplaceBy(D.X*FontWidth, D.Y*FontHeight); { Offset the view }
End Else Origin := Bounds.A; { Hold as origin }
Size.X := Bounds.B.X-Bounds.A.X; { Hold view x size }
Size.Y := Bounds.B.Y-Bounds.A.Y; { Hold view y size }
RawOrigin.X := Origin.X * FontWidth; { Raw x origin }
RawOrigin.Y := Origin.Y * FontHeight; { Raw y origin }
RawSize.X := Size.X * FontWidth - 1; { Set raw x size }
RawSize.Y := Size.Y * FontHeight - 1; { Set raw y size }
End Else Begin { Graphical co-ords }
If (Owner <> Nil) Then Begin { Owner is valid }
COrigin.X := RawOrigin.X - Owner^.RawOrigin.X; { Corrected x origin }
COrigin.Y := RawOrigin.Y - Owner^.RawOrigin.Y; { Corrected y origin }
D.X := Bounds.A.X - COrigin.X; { X origin disp }
D.Y := Bounds.A.Y - COrigin.Y; { Y origin disp }
If ((D.X <> 0) OR (D.Y <> 0)) Then
DisplaceBy(D.X, D.Y); { Offset the view }
End Else RawOrigin := Bounds.A; { Hold as origin }
RawSize.X := Abs(Bounds.B.X) - Bounds.A.X; { Set raw x size }
RawSize.Y := Abs(Bounds.B.Y) - Bounds.A.Y; { Set raw y size }
Origin.X := RawOrigin.X DIV FontWidth; { Rough x position }
Origin.Y := RawOrigin.Y DIV FontHeight; { Rough y position }
Size.X := RawSize.X DIV FontWidth; { Rough x size }
Size.Y := RawSize.Y DIV FontHeight; { Rough y size }
End;
Options := Options OR ofGFVModeView; { Now in GFV mode }
END;
{--TView--------------------------------------------------------------------}
{ GetClipRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetClipRect (Var Clip: TRect);
BEGIN
GetBounds(Clip); { Get current bounds }
If (Owner <> Nil) Then Clip.Intersect(Owner^.Clip);{ Intersect with owner }
Clip.Move(-Origin.X, -Origin.Y); { Sub owner origin }
END;
{--TView--------------------------------------------------------------------}
{ ClearEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ClearEvent (Var Event: TEvent);
BEGIN
Event.What := evNothing; { Clear the event }
Event.InfoPtr := @Self; { Set us as handler }
END;
{--TView--------------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.HandleEvent (Var Event: TEvent);
BEGIN
If (Event.What = evMouseDown) Then { Mouse down event }
If (State AND (sfSelected OR sfDisabled) = 0) { Not selected/disabled }
AND (Options AND ofSelectable <> 0) Then { View is selectable }
If (Focus = False) OR { Not view with focus }
(Options AND ofFirstClick = 0) { Not 1st click select }
Then ClearEvent(Event); { Handle the event }
If (Event.What = evKeyDown) AND { Key down event }
(Options OR ofGFVModeView <> 0) Then Begin { GFV mode view check }
If (Owner <> Nil) AND (TabMask <> 0) AND { Owner and tab masks }
(State AND sfFocused <> 0) Then Begin { View has focus }
Case Event.KeyCode Of
kbTab: If (TabMask AND tmTab <> 0) Then { Tab key mask set }
Owner^.FocusNext(False) Else Exit; { Focus next view }
kbEnter: If (TabMask AND tmEnter <> 0) Then { Enter key mask set }
Owner^.FocusNext(False) Else Exit; { Focus next view }
kbShiftTab: If (TabMask AND tmShiftTab <> 0) { Shit tab mask set }
Then Owner^.FocusNext(True) Else Exit; { Focus prior view }
kbLeft: If (TabMask AND tmLeft <> 0) Then { Left arrow mask set }
Owner^.FocusNext(True) Else Exit; { Focus prior view }
kbRight: If (TabMask AND tmRight <> 0) Then { Right arrow mask set }
Owner^.FocusNext(False) Else Exit; { Focus next view }
kbUp: If (TabMask AND tmUp <> 0) Then { Up arrow mask set }
Owner^.FocusNext(True) Else Exit; { Focus prior view }
kbDown: If (TabMask AND tmDown <> 0) Then { Down arrow mask set }
Owner^.FocusNext(False) Else Exit; { Focus next view }
Else Exit; { Not a tab key }
End;
ClearEvent(Event); { Clear handled events }
End;
End;
END;
{--TView--------------------------------------------------------------------}
{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ChangeBounds (Var Bounds: TRect);
BEGIN
SetBounds(Bounds); { Set new bounds }
DrawView; { Draw the view }
END;
{--TView--------------------------------------------------------------------}
{ SizeLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.SizeLimits (Var Min, Max: TPoint);
BEGIN
Min.X := 0; { Zero x minimum }
Min.Y := 0; { Zero y minimum }
If (Owner = Nil) Then Begin
Max.X := $7FFF; { Max possible x size }
Max.Y := $7FFF; { Max possible y size }
End Else Max := Owner^.Size; { Max owner size }
END;
{--TView--------------------------------------------------------------------}
{ GetCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetCommands (Var Commands: TCommandSet);
BEGIN
Commands := CurCommandSet; { Return command set }
END;
{--TView--------------------------------------------------------------------}
{ GetPeerViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GetPeerViewPtr (Var S: TStream; Var P);
VAR Index: Integer;
BEGIN
Index := 0; { Zero index value }
S.Read(Index, SizeOf(Index)); { Read view index }
If (Index = 0) OR (OwnerGroup = Nil) Then { Check for peer views }
Pointer(P) := Nil Else Begin { Return nil }
Pointer(P) := FixupList^[Index]; { New view ptr }
FixupList^[Index] := @P; { Patch this pointer }
End;
END;
{--TView--------------------------------------------------------------------}
{ PutPeerViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.PutPeerViewPtr (Var S: TStream; P: PView);
VAR Index: Integer;
BEGIN
If (P = Nil) OR (OwnerGroup = Nil) Then Index := 0 { Return zero index }
Else Index := OwnerGroup^.IndexOf(P); { Return view index }
S.Write(Index, SizeOf(Index)); { Write the index }
END;
{--TView--------------------------------------------------------------------}
{ CalcBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.CalcBounds (Var Bounds: Objects.TRect; Delta: TPoint);
VAR S, D: Sw_Integer; Min, Max: TPoint;
FUNCTION Range (Val, Min, Max: Sw_Integer): Sw_Integer;
BEGIN
If (Val < Min) Then Range := Min Else { Value below min }
If (Val > Max) Then Range := Max Else { Value above max }
Range := Val; { Accept value }
END;
PROCEDURE GrowI (Var I: Sw_Integer);
BEGIN
If (GrowMode AND gfGrowRel = 0) Then Inc(I, D)
Else I := (I * S + (S - D) SHR 1) DIV (S - D); { Calc grow value }
END;
BEGIN
GetBounds(Bounds); { Get bounds }
If (GrowMode = 0) Then Exit; { No grow flags exits }
S := Owner^.Size.X; { Set initial size }
D := Delta.X; { Set initial delta }
If (GrowMode AND gfGrowLoX <> 0) Then
GrowI(Bounds.A.X); { Grow left side }
If (GrowMode AND gfGrowHiX <> 0) Then
GrowI(Bounds.B.X); { Grow right side }
If (Bounds.B.X - Bounds.A.X > MaxViewWidth) Then
Bounds.B.X := Bounds.A.X + MaxViewWidth; { Check values }
S := Owner^.Size.Y; D := Delta.Y; { set initial values }
If (GrowMode AND gfGrowLoY <> 0) Then
GrowI(Bounds.A.Y); { Grow top side }
If (GrowMode AND gfGrowHiY <> 0) Then
GrowI(Bounds.B.Y); { grow lower side }
SizeLimits(Min, Max); { Check sizes }
Bounds.B.X := Bounds.A.X + Range(Bounds.B.X -
Bounds.A.X, Min.X, Max.X); { Set right side }
Bounds.B.Y := Bounds.A.Y + Range(Bounds.B.Y -
Bounds.A.Y, Min.Y, Max.Y); { Set lower side }
END;
{***************************************************************************}
{ TView OBJECT PRIVATE METHODS }
{***************************************************************************}
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TGroup OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TGroup-------------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul99 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TGroup.Init (Var Bounds: TRect);
BEGIN
Inherited Init(Bounds); { Call ancestor }
Options := Options OR (ofSelectable + ofBuffered); { Set options }
GOptions := GOptions OR goNoDrawView; { Non drawing view }
GetExtent(Clip); { Get clip extents }
EventMask := $FFFF; { See all events }
GOptions := GOptions OR goTabSelect; { Set graphic options }
END;
{--TGroup-------------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TGroup.Load (Var S: TStream);
VAR I: Sw_Word;
Count: Word;
P, Q: ^Pointer; V: PView; OwnerSave: PGroup;
FixupSave: PFixupList;
BEGIN
Inherited Load(S); { Call ancestor }
GetExtent(Clip); { Get view extents }
OwnerSave := OwnerGroup; { Save current group }
OwnerGroup := @Self; { We are current group }
FixupSave := FixupList; { Save current list }
Count := 0; { Zero count value }
S.Read(Count, SizeOf(Count)); { Read entry count }
If (MaxAvail >= Count*SizeOf(Pointer)) Then Begin { Memory available }
GetMem(FixupList, Count*SizeOf(Pointer)); { List size needed }
FillChar(FixUpList^, Count*SizeOf(Pointer), #0); { Zero all entries }
For I := 1 To Count Do Begin
V := PView(S.Get); { Get view off stream }
If (V <> Nil) Then InsertView(V, Nil); { Insert valid views }
End;
V := Last; { Start on last view }
For I := 1 To Count Do Begin
V := V^.Next; { Fetch next view }
P := FixupList^[I]; { Transfer pointer }
While (P <> Nil) Do Begin { If valid view }
Q := P; { Copy pointer }
P := P^; { Fetch pointer }
Q^ := V; { Transfer view ptr }
End;
End;
FreeMem(FixupList, Count*SizeOf(Pointer)); { Release fixup list }
End;
OwnerGroup := OwnerSave; { Reload current group }
FixupList := FixupSave; { Reload current list }
GetSubViewPtr(S, V); { Load any subviews }
SetCurrent(V, NormalSelect); { Select current view }
If (OwnerGroup = Nil) Then Awaken; { If topview activate }
END;
{--TGroup-------------------------------------------------------------------}
{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
DESTRUCTOR TGroup.Done;
VAR P, T: PView;
BEGIN
Hide; { Hide the view }
P := Last; { Start on last }
If (P <> Nil) Then Begin { Subviews exist }
Repeat
P^.Hide; { Hide each view }
P := P^.Prev; { Prior view }
Until (P = Last); { Loop complete }
Repeat
T := P^.Prev; { Hold prior pointer }
Dispose(P, Done); { Dispose subview }
P := T; { Transfer pointer }
Until (Last = Nil); { Loop complete }
End;
Inherited Done; { Call ancestor }
END;
{--TGroup-------------------------------------------------------------------}
{ First -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.First: PView;
BEGIN
If (Last = Nil) Then First := Nil { No first view }
Else First := Last^.Next; { Return first view }
END;
{--TGroup-------------------------------------------------------------------}
{ Execute -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.Execute: Word;
VAR Event: TEvent;
BEGIN
Repeat
EndState := 0; { Clear end state }
Repeat
GetEvent(Event); { Get next event }
HandleEvent(Event); { Handle the event }
If (Event.What <> evNothing) Then
EventError(Event); { Event not handled }
Until (EndState <> 0); { Until command set }
Until Valid(EndState); { Repeat until valid }
Execute := EndState; { Return result }
EndState := 0; { Clear end state }
END;
{--TGroup-------------------------------------------------------------------}
{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.GetHelpCtx: Word;
VAR H: Word;
BEGIN
H := hcNoContext; { Preset no context }
If (Current <> Nil) Then H := Current^.GetHelpCtx; { Current context }
If (H=hcNoContext) Then H := Inherited GetHelpCtx; { Call ancestor }
GetHelpCtx := H; { Return result }
END;
{--TGroup-------------------------------------------------------------------}
{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.DataSize: Sw_Word;
VAR Total: Word; P: PView;
BEGIN
Total := 0; { Zero totals count }
P := Last; { Start on last view }
If (P <> Nil) Then Begin { Subviews exist }
Repeat
P := P^.Next; { Move to next view }
Total := Total + P^.DataSize; { Add view size }
Until (P = Last); { Until last view }
End;
DataSize := Total; { Return data size }
END;
{--TGroup-------------------------------------------------------------------}
{ ExecView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.ExecView (P: PView): Word;
VAR SaveOptions: Word; SaveTopView, SaveCurrent: PView; SaveOwner: PGroup;
SaveCommands: TCommandSet;
BEGIN
If (P<>Nil) Then Begin
SaveOptions := P^.Options; { Hold options }
SaveOwner := P^.Owner; { Hold owner }
SaveTopView := TheTopView; { Save topmost view }
SaveCurrent := Current; { Save current view }
GetCommands(SaveCommands); { Save commands }
TheTopView := P; { Set top view }
P^.Options := P^.Options AND NOT ofSelectable; { Not selectable }
P^.SetState(sfModal, True); { Make modal }
SetCurrent(P, EnterSelect); { Select next }
If (SaveOwner = Nil) Then Insert(P); { Insert view }
ExecView := P^.Execute; { Execute view }
If (SaveOwner = Nil) Then Delete(P); { Remove view }
SetCurrent(SaveCurrent, LeaveSelect); { Unselect current }
P^.SetState(sfModal, False); { Clear modal state }
P^.Options := SaveOptions; { Restore options }
TheTopView := SaveTopView; { Restore topview }
SetCommands(SaveCommands); { Restore commands }
End Else ExecView := cmCancel; { Return cancel }
END;
{ ********************************* REMARK ******************************** }
{ This call really is very COMPILER SPECIFIC and really can't be done }
{ effectively any other way but assembler code as SELF & FRAMES need }
{ to be put down in exact order and OPTIMIZERS make a mess of it. }
{ ******************************** END REMARK *** Leon de Boer, 17Jul99 *** }
{--TGroup-------------------------------------------------------------------}
{ FirstThat -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.FirstThat (P: Pointer): PView;
VAR
Tp : PView;
BEGIN
If (Last<>Nil) Then
Begin
Tp := Last; { Set temporary ptr }
Repeat
Tp := Tp^.Next; { Get next view }
IF Byte(Longint(CallPointerMethodLocal(P,PreviousFramePointer,@self,Tp)))<>0 THEN
Begin { Test each view }
FirstThat := Tp; { View returned true }
Exit; { Now exit }
End;
Until (Tp=Last); { Until last }
FirstThat := Nil; { None passed test }
End
Else
FirstThat := Nil; { Return nil }
END;
{--TGroup-------------------------------------------------------------------}
{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.Valid (Command: Word): Boolean;
FUNCTION IsInvalid (P: PView): Boolean; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
IsInvalid := NOT P^.Valid(Command); { Check if valid }
END;
BEGIN
Valid := True; { Preset valid }
If (Command = cmReleasedFocus) Then Begin { Release focus cmd }
If (Current <> Nil) AND { Current view exists }
(Current^.Options AND ofValidate <> 0) Then { Validating view }
Valid := Current^.Valid(Command); { Validate command }
End Else Valid := FirstThat(@IsInvalid) = Nil; { Check first valid }
END;
{--TGroup-------------------------------------------------------------------}
{ FocusNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.FocusNext (Forwards: Boolean): Boolean;
VAR P: PView;
BEGIN
P := FindNext(Forwards); { Find next view }
FocusNext := True; { Preset true }
If (P <> Nil) Then FocusNext := P^.Focus; { Check next focus }
END;
{--TGroup-------------------------------------------------------------------}
{ ReDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.ReDraw;
VAR P: PView;
BEGIN
If (DrawMask AND vdNoChild = 0) Then Begin { No draw child clear }
P := Last; { Start on Last }
While (P <> Nil) Do Begin
P^.DrawView; { Redraw each subview }
P := P^.PrevView; { Move to prior view }
End;
End;
END;
{--TGroup-------------------------------------------------------------------}
{ ReDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.ReDrawArea (X1, Y1, X2, Y2: Sw_Integer);
VAR P: PView;
BEGIN
{ redraw this }
// inherited RedrawArea(X1,Y1,X2,Y2);
{ This should do the whole job now }
If (DrawMask AND vdNoChild = 0) and
(State AND (sfExposed or sfVisible) = (sfExposed or sfVisible)) and
(X1<RawOrigin.X+RawSize.X) and
(Y1<RawOrigin.Y+RawSize.Y) and
(X2>=RawOrigin.X) and { No need to parse childs for Shadows }
(Y2>=RawOrigin.Y) Then { No draw child clear }
ReDrawVisibleArea(X1, Y1, X2, Y2,First); { Redraw each subview }
(* { redraw group members }
If (DrawMask AND vdNoChild = 0) and
(X1<RawOrigin.X+RawSize.X) and { No need to parse childs for Shadows }
(Y1<RawOrigin.Y+RawSize.Y) Then Begin { No draw child clear }
P := Last; { Start on Last }
While (P <> Nil) Do Begin
P^.ReDrawVisibleArea(X1, Y1, X2, Y2,First,P); { Redraw each subview }
P := P^.PrevView; { Move to prior view }
End;
End; *)
END;
PROCEDURE TGroup.ReDrawVisibleArea (X1, Y1, X2, Y2: Sw_Integer;Cur : PView);
var
StoreDrawMask : Byte;
VAR CurN: PView; ViewPort: ViewPortType;
x3,x4,y3,y4 : sw_integer;
BEGIN
while(assigned(Cur) and ((Cur^.State and sfvisible)=0)) and (Cur<>Last) do
Cur:=Cur^.Next;
if not assigned(Cur) then
Begin
TView.ReDrawArea(x1,y1,x2,y2);
exit;
End;
x3:=Cur^.RawOrigin.x;
x4:=x3+Cur^.RawSize.x;
y3:=Cur^.RawOrigin.Y;
y4:=y3+Cur^.RawSize.Y;
{ depending on relative positions of x1,x2,x3,x4
we should only draw subrectangles }
if cur=last then
CurN:=nil
else
curN:=Cur^.Next;
{ number of possible cases :
x3<x1, x1<=x3<x2, x3>=x2 : 3 possibilities
total : 3^4: 81... }
if ((x3>=x2) or (x4<=x1) or (y3>=y2) or (y4<=y1)) or
(assigned(Cur) and ((Cur^.State and sfvisible)=0)) then
ReDrawVisibleArea(x1,y1,x2,y2,curn)
else
begin
if x3>x1 then
begin
ReDrawVisibleArea(x1,y1,x3,y2,curn);
x1:=x3;
end;
if x4<x2 then
begin
ReDrawVisibleArea(x4,y1,x2,y2,curn);
x2:=x4;
end;
if y3>y1 then
Begin
ReDrawVisibleArea(x1,y1,x2,y3,curn);
y1:=y3;
End;
if y4<y2 then
Begin
ReDrawVisibleArea(x1,y4,x2,y2,curn);
y2:=y4;
End;
if (x1<=x2) and (y1<=y2) then
Cur^.ReDrawArea(x1,y1,x2,y2);
end;
END;
{--TGroup-------------------------------------------------------------------}
{ Awaken -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Awaken;
PROCEDURE DoAwaken (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
If (P <> Nil) Then P^.Awaken; { Awaken view }
END;
BEGIN
ForEach(@DoAwaken); { Awaken each view }
END;
{--TGroup-------------------------------------------------------------------}
{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Draw;
BEGIN
If Buffer=Nil then
ReDraw
else
WriteBuf(0,0,Size.X,Size.Y,Buffer);
END;
{--TGroup-------------------------------------------------------------------}
{ DrawBackground }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.DrawBackground;
var
P : PView;
BEGIN
Inherited DrawBackground;
P:=Last;
While (P <> Nil) Do Begin
If P^.Exposed then
P^.SetDrawMask(vdAll); { Redraw each exposed subview }
P := P^.PrevView; { Move to prior view }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ SelectDefaultView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.SelectDefaultView;
VAR P: PView;
BEGIN
P := Last; { Start at last }
While (P <> Nil) Do Begin
If P^.GetState(sfDefault) Then Begin { Search 1st default }
P^.Select; { Select default view }
P := Nil; { Force kick out }
End Else P := P^.PrevView; { Prior subview }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Insert (P: PView);
BEGIN
If (P <> Nil) and assigned(P^.Owner) Then { View is valid and already inserted }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
P^.DisplaceBy(-P^.Owner^.RawOrigin.X,
-P^.Owner^.RawOrigin.Y) Else { We are in GFV mode }
P^.DisplaceBy(-P^.Owner^.Origin.X*FontWidth,
-P^.Owner^.Origin.Y*FontHeight); { Displace old view }
If (P <> Nil) Then { View is valid }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
P^.DisplaceBy(RawOrigin.X, RawOrigin.Y) Else { We are in GFV mode }
P^.DisplaceBy(Origin.X*FontWidth,
Origin.Y*FontHeight); { Displace old view }
InsertBefore(P, First); { Insert the view }
END;
{--TGroup-------------------------------------------------------------------}
{ Delete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Delete (P: PView);
VAR SaveState: Word;
BEGIN
SaveState := P^.State; { Save state }
P^.Hide; { Hide the view }
RemoveView(P); { Remove the view }
P^.Owner := Nil; { Clear owner ptr }
P^.Next := Nil; { Clear next ptr }
{ We need to recalculate correct position }
If (P <> Nil) Then { View is valid }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
P^.DisplaceBy(-RawOrigin.X, -RawOrigin.Y) Else { We are in GFV mode }
P^.DisplaceBy(-Origin.X*FontWidth,
-Origin.Y*FontHeight); { Displace old view }
If (SaveState AND sfVisible <> 0) Then P^.Show; { Show view }
END;
{ ********************************* REMARK ******************************** }
{ This call really is very COMPILER SPECIFIC and really can't be done }
{ effectively any other way but assembler code as SELF & FRAMES need }
{ to be put down in exact order and OPTIMIZERS make a mess of it. }
{ ******************************** END REMARK *** Leon de Boer, 17Jul99 *** }
{--TGroup-------------------------------------------------------------------}
{ ForEach -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.ForEach (P: Pointer);
VAR
Tp,Hp,L0 : PView;
{ Vars Hp and L0 are necessary to hold original pointers in case }
{ when some view closes himself as a result of broadcast message ! }
BEGIN
If (Last<>Nil) Then
Begin
Tp:=Last;
Hp:=Tp^.Next;
L0:=Last; { Set temporary ptr }
Repeat
Tp:=Hp;
if tp=nil then
exit;
Hp:=Tp^.Next; { Get next view }
CallPointerMethodLocal(P,PreviousFramePointer,@self,Tp);
Until (Tp=L0); { Until last }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ EndModal -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.EndModal (Command: Word);
BEGIN
If (State AND sfModal <> 0) Then { This view is modal }
EndState := Command Else { Set endstate }
Inherited EndModal(Command); { Call ancestor }
END;
{--TGroup-------------------------------------------------------------------}
{ DisplaceBy -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.DisplaceBy (Dx, Dy: Sw_Integer);
VAR P: PView;
BEGIN
P := First; { Get first view }
While (P <> Nil) Do Begin
P^.DisplaceBy(Dx, Dy); { Displace subviews }
P := P^.NextView; { Next view }
End;
Inherited DisplaceBy(Dx, Dy); { Call ancestor }
END;
{--TGroup-------------------------------------------------------------------}
{ SelectNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.SelectNext (Forwards: Boolean);
VAR P: PView;
BEGIN
P := FindNext(Forwards); { Find next view }
If (P <> Nil) Then P^.Select; { Select view }
END;
{--TGroup-------------------------------------------------------------------}
{ InsertBefore -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.InsertBefore (P, Target: PView);
VAR SaveState : Word;
I: Sw_integer;
BEGIN
If (P <> Nil) AND (P^.Owner = Nil) AND { View valid }
((Target = Nil) OR (Target^.Owner = @Self)) { Target valid }
Then Begin
If (P^.Options AND ofCenterX <> 0) Then Begin { Centre on x axis }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
I := RawSize.X Else I := Size.X * FontWidth; { Calc owner x size }
If (P^.Options AND ofGFVModeView <> 0) { GFV mode view check }
Then Begin
I := (I - P^.RawSize.X) DIV 2; { Calc view offset }
I := I - P^.RawOrigin.X; { Subtract x origin }
End Else Begin
I := (I - (P^.Size.X * FontWidth)) DIV 2; { Calc view offset }
I := I - (P^.Origin.X * FontWidth); { Subtract x origin }
End;
{ make sure that I is a multiple of FontWidth }
if TextModeGFV or UseFixedFont then
I:= (I div FontWidth) * FontWidth;
P^.DisplaceBy(I, 0); { Displace the view }
End;
If (P^.Options AND ofCenterY <> 0) Then Begin { Centre on y axis }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
I := RawSize.Y Else I := Size.Y * FontHeight;{ Calc owner y size }
If (P^.Options AND ofGFVModeView <> 0) { GFV mode view check }
Then Begin
I := (I - P^.RawSize.Y) DIV 2; { Calc view offset }
I := I - P^.RawOrigin.Y; { Subtract y origin }
End Else Begin
I := (I - (P^.Size.Y * FontHeight)) DIV 2; { Calc view offset }
I := I - (P^.Origin.Y * FontHeight); { Subtract y origin }
End;
{ make sure that I is a multiple of FontHeight }
if TextModeGFV or UseFixedFont then
I:= (I div FontHeight) * FontHeight;
P^.DisplaceBy(0, I); { Displace the view }
End;
SaveState := P^.State; { Save view state }
P^.Hide; { Make sure hidden }
InsertView(P, Target); { Insert into list }
If (SaveState AND sfVisible <> 0) Then P^.Show; { Show the view }
If (State AND sfActive <> 0) Then { Was active before }
P^.SetState(sfActive , True); { Make active again }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.SetState (AState: Word; Enable: Boolean);
PROCEDURE DoSetState (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
If (P <> Nil) Then P^.SetState(AState, Enable); { Set subview state }
END;
PROCEDURE DoExpose (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
If (P <> Nil) Then Begin
If (P^.State AND sfVisible <> 0) Then { Check view visible }
P^.SetState(sfExposed, Enable); { Set exposed flag }
End;
END;
BEGIN
Inherited SetState(AState, Enable); { Call ancestor }
Case AState Of
sfActive, sfDragging: Begin
Lock; { Lock the view }
ForEach(@DoSetState); { Set each subview }
UnLock; { Unlock the view }
End;
sfFocused: Begin
If (Current <> Nil) Then
Current^.SetState(sfFocused, Enable); { Focus current view }
{If TextModeGFV then
SetDrawMask(vdBackGnd OR vdFocus OR vdInner OR vdBorder); Set redraw masks }
End;
sfExposed: Begin
ForEach(@DoExpose); { Expose each subview }
End;
End;
END;
{--TGroup-------------------------------------------------------------------}
{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Mar98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.GetData (Var Rec);
VAR Total: Sw_Word; P: PView;
BEGIN
Total := 0; { Clear total }
P := Last; { Start at last }
While (P <> Nil) Do Begin { Subviews exist }
P^.GetData(TByteArray(Rec)[Total]); { Get data }
Inc(Total, P^.DataSize); { Increase total }
P := P^.PrevView; { Previous view }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Mar98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.SetData (Var Rec);
VAR Total: Sw_Word; P: PView;
BEGIN
Total := 0; { Clear total }
P := Last; { Start at last }
While (P <> Nil) Do Begin { Subviews exist }
P^.SetData(TByteArray(Rec)[Total]); { Get data }
Inc(Total, P^.DataSize); { Increase total }
P := P^.PrevView; { Previous view }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Store (Var S: TStream);
VAR Count: Word; OwnerSave: PGroup;
PROCEDURE DoPut (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
S.Put(P); { Put view on stream }
END;
BEGIN
TView.Store(S); { Call view store }
OwnerSave := OwnerGroup; { Save ownergroup }
OwnerGroup := @Self; { Set as owner group }
Count := IndexOf(Last); { Subview count }
S.Write(Count, SizeOf(Count)); { Write the count }
ForEach(@DoPut); { Put each in stream }
PutSubViewPtr(S, Current); { Current on stream }
OwnerGroup := OwnerSave; { Restore ownergroup }
END;
{--TGroup-------------------------------------------------------------------}
{ EventError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.EventError (Var Event: TEvent);
BEGIN
If (Owner <> Nil) Then Owner^.EventError(Event); { Event error }
END;
{--TGroup-------------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.HandleEvent (Var Event: TEvent);
FUNCTION ContainsMouse (P: PView): Boolean; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
ContainsMouse := (P^.State AND sfVisible <> 0) { Is view visible }
AND P^.MouseInView(Event.Where); { Is point in view }
END;
PROCEDURE DoHandleEvent (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
If (P = Nil) OR ((P^.State AND sfDisabled <> 0) AND
(Event.What AND(PositionalEvents OR FocusedEvents) <>0 ))
Then Exit; { Invalid/disabled }
Case Phase Of
phPreProcess: If (P^.Options AND ofPreProcess = 0)
Then Exit; { Not pre processing }
phPostProcess: If (P^.Options AND ofPostProcess = 0)
Then Exit; { Not post processing }
End;
If (Event.What AND P^.EventMask <> 0) Then { View handles event }
P^.HandleEvent(Event); { Pass to view }
END;
BEGIN
Inherited HandleEvent(Event); { Call ancestor }
If (Event.What = evNothing) Then Exit; { No valid event exit }
If (Event.What AND FocusedEvents <> 0) Then Begin { Focused event }
Phase := phPreProcess; { Set pre process }
ForEach(@DoHandleEvent); { Pass to each view }
Phase := phFocused; { Set focused }
DoHandleEvent(Current); { Pass to current }
Phase := phPostProcess; { Set post process }
ForEach(@DoHandleEvent); { Pass to each }
End Else Begin
Phase := phFocused; { Set focused }
If (Event.What AND PositionalEvents <> 0) Then { Positional event }
DoHandleEvent(FirstThat(@ContainsMouse)) { Pass to first }
Else ForEach(@DoHandleEvent); { Pass to all }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.ChangeBounds (Var Bounds: TRect);
VAR D: TPoint;
PROCEDURE DoCalcChange (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
VAR R: TRect;
BEGIN
P^.CalcBounds(R, D); { Calc view bounds }
P^.ChangeBounds(R); { Change view bounds }
END;
BEGIN
D.X := Bounds.B.X - Bounds.A.X - Size.X; { Delta x value }
D.Y := Bounds.B.Y - Bounds.A.Y - Size.Y; { Delta y value }
If ((D.X=0) AND (D.Y=0)) Then Begin
SetBounds(Bounds); { Set new bounds }
DrawView; { Draw the view }
End Else Begin
SetBounds(Bounds); { Set new bounds }
GetExtent(Clip); { Get new clip extents }
Lock; { Lock drawing }
ForEach(@DoCalcChange); { Change each view }
UnLock; { Unlock drawing }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ GetSubViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.GetSubViewPtr (Var S: TStream; Var P);
VAR Index, I: Word; Q: PView;
BEGIN
Index := 0; { Zero index value }
S.Read(Index, SizeOf(Index)); { Read view index }
If (Index > 0) Then Begin { Valid index }
Q := Last; { Start on last }
For I := 1 To Index Do Q := Q^.Next; { Loop for count }
Pointer(P) := Q; { Return the view }
End Else Pointer(P) := Nil; { Return nil }
END;
{--TGroup-------------------------------------------------------------------}
{ PutSubViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.PutSubViewPtr (Var S: TStream; P: PView);
VAR Index: Sw_Word;
BEGIN
If (P = Nil) Then Index := 0 Else { Nil view, Index = 0 }
Index := IndexOf(P); { Calc view index }
S.Write(Index, SizeOf(Index)); { Write the index }
END;
{***************************************************************************}
{ TGroup OBJECT PRIVATE METHODS }
{***************************************************************************}
{--TGroup-------------------------------------------------------------------}
{ IndexOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.IndexOf (P: PView): Sw_Integer;
VAR I: Sw_Integer; Q: PView;
BEGIN
Q := Last; { Start on last view }
If (Q <> Nil) Then Begin { Subviews exist }
I := 1; { Preset value }
While (Q <> P) AND (Q^.Next <> Last) Do Begin
Q := Q^.Next; { Load next view }
Inc(I); { Increment count }
End;
If (Q <> P) Then IndexOf := 0 Else IndexOf := I; { Return index }
End Else IndexOf := 0; { Return zero }
END;
{--TGroup-------------------------------------------------------------------}
{ FindNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.FindNext (Forwards: Boolean): PView;
VAR P: PView;
BEGIN
FindNext := Nil; { Preset nil return }
If (Current <> Nil) Then Begin { Has current view }
P := Current; { Start on current }
Repeat
If Forwards Then P := P^.Next { Get next view }
Else P := P^.Prev; { Get prev view }
Until ((P^.State AND (sfVisible+sfDisabled) = sfVisible)
AND ((P^.Options AND ofSelectable <> 0) AND { Selectable }
(P^.GOptions AND goTabSelect <> 0))) OR { Tab selectable }
(P = Current); { Not singular select }
If (P <> Current) Then FindNext := P; { Return result }
End;
END;
{--TGroup-------------------------------------------------------------------}
{ FirstMatch -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TGroup.FirstMatch (AState: Word; AOptions: Word): PView;
FUNCTION Matches (P: PView): Boolean; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
BEGIN
Matches := (P^.State AND AState = AState) AND
(P^.Options AND AOptions = AOptions); { Return match state }
END;
BEGIN
FirstMatch := FirstThat(@Matches); { Return first match }
END;
{--TGroup-------------------------------------------------------------------}
{ ResetCurrent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.ResetCurrent;
BEGIN
SetCurrent(FirstMatch(sfVisible, ofSelectable),
NormalSelect); { Reset current view }
END;
{--TGroup-------------------------------------------------------------------}
{ RemoveView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.RemoveView (P: PView);
VAR Q: PView;
BEGIN
If (P <> Nil) AND (Last <> Nil) Then Begin { Check view is valid }
Q := Last; { Start on last view }
While (Q^.Next <> P) AND (Q^.Next <> Last) Do
Q := Q^.Next; { Find prior view }
If (Q^.Next = P) Then Begin { View found }
If (Q^.Next <> Q) Then Begin { Not only view }
Q^.Next := P^.Next; { Rechain views }
If (P = Last) Then Last := P^.Next; { Fix if last removed }
End Else Last := Nil; { Only view }
End;
End;
END;
{--TGroup-------------------------------------------------------------------}
{ InsertView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.InsertView (P, Target: PView);
BEGIN
If (P <> Nil) Then Begin { Check view is valid }
P^.Owner := @Self; { Views owner is us }
If (Target <> Nil) Then Begin { Valid target }
Target := Target^.Prev; { 1st part of chain }
P^.Next := Target^.Next; { 2nd part of chain }
Target^.Next := P; { Chain completed }
End Else Begin
If (Last <> Nil) Then Begin { Not first view }
P^.Next := Last^.Next; { 1st part of chain }
Last^.Next := P; { Completed chain }
End Else P^.Next := P; { 1st chain to self }
Last := P; { P is now last }
End;
End;
END;
{--TGroup-------------------------------------------------------------------}
{ SetCurrent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.SetCurrent (P: PView; Mode: SelectMode);
PROCEDURE SelectView (P: PView; Enable: Boolean);
BEGIN
If (P <> Nil) Then { View is valid }
P^.SetState(sfSelected, Enable); { Select the view }
END;
PROCEDURE FocusView (P: PView; Enable: Boolean);
BEGIN
If (State AND sfFocused <> 0) AND (P <> Nil) { Check not focused }
Then P^.SetState(sfFocused, Enable); { Focus the view }
END;
BEGIN
If (Current<>P) Then Begin { Not already current }
Lock; { Stop drawing }
FocusView(Current, False); { Defocus current }
If (Mode <> EnterSelect) Then
SelectView(Current, False); { Deselect current }
If (Mode<>LeaveSelect) Then SelectView(P, True); { Select view P }
FocusView(P, True); { Focus view P }
Current := P; { Set as current view }
UnLock; { Redraw now }
End;
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TFrame OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TFrame-------------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TFrame.Init (Var Bounds: TRect);
BEGIN
Inherited Init(Bounds); { Call ancestor }
GrowMode := gfGrowHiX + gfGrowHiY; { Set grow modes }
EventMask := EventMask OR evBroadcast; { See broadcasts }
END;
{--TFrame-------------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TFrame.GetPalette: PPalette;
CONST P: String[Length(CFrame)] = CFrame; { Always normal string }
BEGIN
GetPalette := @P; { Return palette }
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TScrollBar OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TScrollBar---------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TScrollBar.Init (Var Bounds: TRect);
const
VChars: array[boolean] of TScrollChars =
(('^','V', #177, #254, #178),(#30, #31, #177, #254, #178));
HChars: array[boolean] of TScrollChars =
(('<','>', #177, #254, #178),(#17, #16, #177, #254, #178));
BEGIN
Inherited Init(Bounds); { Call ancestor }
PgStep := 1; { Page step size = 1 }
ArStep := 1; { Arrow step sizes = 1 }
If (Size.X = 1) Then Begin { Vertical scrollbar }
GrowMode := gfGrowLoX + gfGrowHiX + gfGrowHiY; { Grow vertically }
Chars := VChars[LowAscii]; { Vertical chars }
End Else Begin { Horizontal scrollbar }
GrowMode := gfGrowLoY + gfGrowHiX + gfGrowHiY; { Grow horizontal }
Chars := HChars[LowAscii]; { Horizontal chars }
End;
END;
{--TScrollBar---------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
{ This load method will read old original TV data from a stream with the }
{ scrollbar id set to zero. }
{---------------------------------------------------------------------------}
CONSTRUCTOR TScrollBar.Load (Var S: TStream);
VAR i: Integer;
BEGIN
Inherited Load(S); { Call ancestor }
S.Read(i, SizeOf(i)); Value:=i; { Read current value }
S.Read(i, SizeOf(i)); Min:=i; { Read min value }
S.Read(i, SizeOf(i)); Max:=i; { Read max value }
S.Read(i, SizeOf(i)); PgStep:=i; { Read page step size }
S.Read(i, SizeOf(i)); ArStep:=i; { Read arrow step size }
S.Read(Chars, SizeOf(Chars)); { Read scroll chars }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
begin
S.Read(i, SizeOf(i)); Id:=i; { Read id }
end;
END;
{--TScrollBar---------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TScrollBar.GetPalette: PPalette;
CONST P: String[Length(CScrollBar)] = CScrollBar; { Always normal string }
BEGIN
GetPalette := @P; { Return palette }
END;
{--TScrollBar---------------------------------------------------------------}
{ ScrollStep -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TScrollBar.ScrollStep (Part: Sw_Integer): Sw_Integer;
VAR Step: Sw_Integer;
BEGIN
If (Part AND $0002 = 0) Then Step := ArStep { Range step size }
Else Step := PgStep; { Page step size }
If (Part AND $0001 = 0) Then ScrollStep := -Step { Upwards move }
Else ScrollStep := Step; { Downwards move }
END;
{--TScrollBar---------------------------------------------------------------}
{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.Draw;
BEGIN
If (GOptions AND goNativeClass = 0) Then
DrawPos(GetPos); { Draw position }
END;
{--TScrollBar---------------------------------------------------------------}
{ ScrollDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.ScrollDraw;
VAR P: PView;
BEGIN
If (Id <> 0) Then Begin
P := TopView; { Get topmost view }
NewMessage(P, evCommand, cmIdCommunicate, Id,
Value, @Self); { New Id style message }
End;
NewMessage(Owner, evBroadcast, cmScrollBarChanged,
Id, Value, @Self); { Old TV style message }
END;
{--TScrollBar---------------------------------------------------------------}
{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.DrawBackGround;
VAR Bc: Byte;
I : Longint;
B : TDrawBuffer;
BEGIN
If (GOptions AND goNativeClass = 0) Then Begin { Non natives draw }
Inherited DrawBackGround; { Call ancestor }
Bc := GetColor(1) AND $F0 SHR 4; { Background colour }
If TextModeGFV {or UseFixedFont} then
Begin
WriteChar(0,0,Chars[0],Bc,1);
If (Size.X = 1) Then Begin { Vertical scrollbar }
For i:=1 to Size.Y-2 do
WriteChar(0,i,Chars[2],Bc,1);
WriteChar(0,Size.Y-1,Chars[1],Bc,1);
End Else Begin
WriteChar(1,0,Chars[2],Bc,Size.X-2);
WriteChar(Size.X-1,0,Chars[1],Bc,1);
End;
End
else
Begin
ClearArea(0, 0, FontWidth-1, FontHeight-1, Bc); { Clear top/left area }
BiColorRectangle(0, 0, FontWidth-1, FontHeight-1,
15, 0, False); { Draw 3d effect }
ClearArea(RawSize.X-FontWidth+1, RawSize.Y-
FontHeight+1, RawSize.X, RawSize.Y, Bc); { Clr right/lower area }
BiColorRectangle(RawSize.X-FontWidth+1,
RawSize.Y-FontHeight+1,RawSize.X, RawSize.Y,
15, 0, False); { Draw 3d effect }
End;
End;
END;
{--TScrollBar---------------------------------------------------------------}
{ SetValue -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.SetValue (AValue: Sw_Integer);
BEGIN
SetParams(AValue, Min, Max, PgStep, ArStep); { Set value }
END;
{--TScrollBar---------------------------------------------------------------}
{ SetRange -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.SetRange (AMin, AMax: Sw_Integer);
BEGIN
SetParams(Value, AMin, AMax, PgStep, ArStep); { Set range }
END;
{--TScrollBar---------------------------------------------------------------}
{ SetStep -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.SetStep (APgStep, AArStep: Sw_Integer);
BEGIN
SetParams(Value, Min, Max, APgStep, AArStep); { Set step sizes }
END;
{--TScrollBar---------------------------------------------------------------}
{ SetParams -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 21Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.SetParams (AValue, AMin, AMax, APgStep, AArStep: Sw_Integer);
BEGIN
If (AMax < AMin) Then AMax := AMin; { Max below min fix up }
If (AValue < AMin) Then AValue := AMin; { Value below min fix }
If (AValue > AMax) Then AValue := AMax; { Value above max fix }
If (Value <> AValue) OR (Min <> AMin) OR
(Max <> AMax) Then Begin { Something changed }
If (Min <> AMin) OR (Max <> AMax) Then Begin { Range has changed }
If (GOptions AND goNativeClass = 0) Then
ClearPos(GetPos); { Clear old position }
Min := AMin; { Set new minimum }
Max := AMax; { Set new maximum }
{ This was removed as found not needed but if you
change limits but value unchanged scrollbar is not redrawm..LdB }
{If (Value = AValue) AND (State and sfVisible <> 0)
Then ScrollDraw;} { Send message out }
End Else Begin
If (GOptions AND goNativeClass = 0) Then { Not in native mode }
ClearPos(GetPos); { Clear old position }
End;
If (Value <> AValue) Then Begin { Position moved }
Value := AValue; { Set new value }
If (GOptions AND goNativeClass = 0) Then Begin { Not in native mode }
SetDrawMask(vdInner); { Set draw masks }
DrawView; { Redraw changed }
End;
{If (State AND sfVisible <> 0) Then }
{ We need to inform the owner if the value changes
even if not visible !! }
ScrollDraw; { Send update message }
End;
End;
PgStep := APgStep; { Hold page step }
ArStep := AArStep; { Hold arrow step }
END;
{--TScrollBar---------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
{ You can save data to the stream compatable with the old original TV by }
{ temporarily turning off the ofGrafVersion making the call to this store }
{ routine and resetting the ofGrafVersion flag after the call. }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.Store (Var S: TStream);
VAR i: Integer;
BEGIN
TView.Store(S); { TView.Store called }
i:=Value;S.Write(i, SizeOf(i)); { Write current value }
i:=Min;S.Write(i, SizeOf(i)); { Write min value }
i:=Max;S.Write(i, SizeOf(i)); { Write max value }
i:=PgStep;S.Write(i, SizeOf(i)); { Write page step size }
i:=ArStep;S.Write(i, SizeOf(i)); { Write arrow step size }
S.Write(Chars, SizeOf(Chars)); { Write scroll chars }
If (Options AND ofGFVModeView <> 0) Then { GFV mode view check }
begin
i:=Id;S.Write(i, SizeOf(i)); { Write scrollbar id }
end;
END;
{--TScrollBar---------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.HandleEvent (Var Event: TEvent);
VAR Tracking: Boolean; I, P, S, ClickPart, Iv: Sw_Integer;
Mouse: TPoint; Extent: TRect;
FUNCTION GetPartCode: Sw_Integer;
VAR Mark, Part, J: Sw_Integer;
BEGIN
Part := -1; { Preset failure }
If Extent.Contains(Mouse) Then Begin { Contains mouse }
If (Size.X = 1) Then Begin { Vertical scrollbar }
Mark := Mouse.Y - FontHeight; { Calc position }
J := FontHeight; { Font height }
End Else Begin { Horizontal bar }
Mark := Mouse.X - FontWidth; { Calc position }
J := FontWidth; { Font width }
End;
If (Mark >= P) AND (Mark < P+J) Then { Within thumbnail }
Part := sbIndicator; { Indicator part }
If (Part <> sbIndicator) Then Begin { Not indicator part }
If (Mark < 1) Then Part := sbLeftArrow Else { Left arrow part }
If (Mark < P) Then Part := sbPageLeft Else { Page left part }
If (Mark < S) Then Part := sbPageRight Else { Page right part }
Part := sbRightArrow; { Right arrow part }
If (Size.X = 1) Then Inc(Part, 4); { Correct for vertical }
End;
End;
GetPartCode := Part; { Return part code }
END;
PROCEDURE Clicked;
BEGIN
NewMessage(Owner, evBroadcast, cmScrollBarClicked,
Id, Value, @Self); { Old TV style message }
END;
BEGIN
Inherited HandleEvent(Event); { Call ancestor }
Case Event.What Of
evNothing: Exit; { Speed up exit }
evCommand: Begin { Command event }
If (Event.Command = cmIdCommunicate) AND { Id communication }
(Event.Id = Id) AND (Event.InfoPtr <> @Self) { Targeted to us }
Then Begin
SetValue(Round(Event.Data)); { Set scrollbar value }
ClearEvent(Event); { Event was handled }
End;
End;
evKeyDown:
If (State AND sfVisible <> 0) Then Begin { Scrollbar visible }
ClickPart := sbIndicator; { Preset result }
If (Size.Y = 1) Then { Horizontal bar }
Case CtrlToArrow(Event.KeyCode) Of
kbLeft: ClickPart := sbLeftArrow; { Left one item }
kbRight: ClickPart := sbRightArrow; { Right one item }
kbCtrlLeft: ClickPart := sbPageLeft; { One page left }
kbCtrlRight: ClickPart := sbPageRight; { One page right }
kbHome: I := Min; { Move to start }
kbEnd: I := Max; { Move to end }
Else Exit; { Not a valid key }
End
Else { Vertical bar }
Case CtrlToArrow(Event.KeyCode) Of
kbUp: ClickPart := sbUpArrow; { One item up }
kbDown: ClickPart := sbDownArrow; { On item down }
kbPgUp: ClickPart := sbPageUp; { One page up }
kbPgDn: ClickPart := sbPageDown; { One page down }
kbCtrlPgUp: I := Min; { Move to top }
kbCtrlPgDn: I := Max; { Move to bottom }
Else Exit; { Not a valid key }
End;
Clicked; { Send out message }
If (ClickPart <> sbIndicator) Then
I := Value + ScrollStep(ClickPart); { Calculate position }
SetValue(I); { Set new item }
ClearEvent(Event); { Event now handled }
End;
evMouseDown: Begin { Mouse press event }
Clicked; { Scrollbar clicked }
Mouse.X := Event.Where.X - RawOrigin.X; { Localize x value }
Mouse.Y := Event.Where.Y - RawOrigin.Y; { Localize y value }
Extent.A.X := 0; { Zero x extent value }
Extent.A.Y := 0; { Zero y extent value }
Extent.B.X := RawSize.X; { Set extent x value }
Extent.B.Y := RawSize.Y; { set extent y value }
P := GetPos; { Current position }
S := GetSize; { Initial size }
ClickPart := GetPartCode; { Get part code }
If (ClickPart <> sbIndicator) Then Begin { Not thumb nail }
Repeat
Mouse.X := Event.Where.X-RawOrigin.X; { Localize x value }
Mouse.Y := Event.Where.Y-RawOrigin.Y; { Localize y value }
If GetPartCode = ClickPart Then
SetValue(Value+ScrollStep(ClickPart)); { Same part repeat }
Until NOT MouseEvent(Event, evMouseAuto); { Until auto done }
Clicked; { Scrollbar clicked }
End Else Begin { Thumb nail move }
Iv := Value; { Initial value }
Repeat
Mouse.X := Event.Where.X - RawOrigin.X; { Localize x value }
Mouse.Y := Event.Where.Y - RawOrigin.Y; { Localize y value }
Tracking := Extent.Contains(Mouse); { Check contains }
If Tracking Then Begin { Tracking mouse }
If (Size.X=1) Then
I := Mouse.Y-FontHeight Else { Calc vert position }
I := Mouse.X-FontWidth; { Calc horz position }
If (I < 0) Then I := 0; { Check underflow }
If (I > S) Then I := S; { Check overflow }
End Else I := GetPos; { Get position }
If (I <> P) Then Begin
SetValue(LongInt((LongInt(I)*(Max-Min))
+(S SHR 1)) DIV S + Min); { Set new value }
P := I; { Hold new position }
End;
Until NOT MouseEvent(Event, evMouseMove); { Until not moving }
If Tracking AND (S > 0) Then { Tracking mouse }
SetValue(LongInt((LongInt(P)*(Max-Min))+
(S SHR 1)) DIV S + Min); { Set new value }
If (Iv <> Value) Then Clicked; { Scroll has moved }
End;
ClearEvent(Event); { Clear the event }
End;
End;
END;
{***************************************************************************}
{ TScrollBar OBJECT PRIVATE METHODS }
{***************************************************************************}
{--TScrollBar---------------------------------------------------------------}
{ GetPos -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TScrollBar.GetPos: Sw_Integer;
VAR R: Sw_Integer;
BEGIN
R := Max - Min; { Get full range }
If (R = 0) Then GetPos := 0 Else { Return zero }
GetPos := LongInt((LongInt(Value-Min) * GetSize)
+ (R SHR 1)) DIV R; { Calc position }
END;
{--TScrollBar---------------------------------------------------------------}
{ GetSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TScrollBar.GetSize: Sw_Integer;
VAR S: Sw_Integer;
BEGIN
If TextModeGFV then Begin
If Size.X = 1 Then
S:= (Size.Y-3)*FontHeight
else
S:= (Size.X-3)*FontWidth;
end else If (Size.X = 1) Then S := RawSize.Y-3*FontHeight+1 { Vertical bar }
Else S := RawSize.X-3*FontWidth+1; { Horizontal bar }
If (S < 1) Then S := 1; { Fix minimum size }
GetSize := S; { Return size }
END;
{--TScrollBar---------------------------------------------------------------}
{ DrawPos -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27OctMay99 LdB }
{---------------------------------------------------------------------------}
{ This could be called from a message handling event so it must check the }
{ view is visible, exposed and not obstructed before drawing the thumbnail }
{ square area. }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.DrawPos (Pos: Sw_Integer);
VAR i, X1, Y1, X2, Y2: Sw_Integer; ViewPort: ViewPortType;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) AND { View is exposed }
(Max <> Min) Then Begin { View has some size }
SetViewLimits; { Set view limits }
GetViewSettings(ViewPort, TextModeGFV); { Get set viewport }
If OverlapsArea(ViewPort.X1, ViewPort.Y1,
ViewPort.X2, ViewPort.Y2) Then Begin { Must be in area }
HideMouseCursor; { Hide the mouse }
X1 := 0; { Initial x position }
Y1 := 0; { Initial y position }
If TextModeGFV then Begin
If (Size.X = 1) Then Begin { Vertical scrollbar }
Pos:=Pos div FontHeight;
WriteChar(0,0,Chars[0],2,1);
For i:=1 to Size.Y-2 do
WriteChar(0,i,Chars[2],2,1);
WriteChar(0,Size.Y-1,Chars[1],2,1);
End Else Begin
Pos:=Pos div FontWidth;
WriteChar(0,0,Chars[0],2,1);
WriteChar(1,0,Chars[2],2,Size.X-2);
WriteChar(Size.X-1,0,Chars[1],2,1);
End;
If (Size.X=1) Then Y1 := Pos+1 { Vertical bar }
Else X1 := Pos+1; { Horizontal bar }
WriteChar(X1,Y1,Chars[3],2,1);
End Else Begin
If (Size.X=1) Then Y1 := Pos + FontHeight { Vertical bar }
Else X1 := Pos + FontWidth; { Horizontal bar }
X2 := X1 + FontWidth - 1; { Right side point }
Y2 := Y1 + FontHeight - 1; { Lower side point }
ClearArea(X1, Y1, X2, Y2, GetColor(2) AND $0F);{ Thumbnail back }
BiColorRectangle(X1, Y1, X2, Y2, 15, 8, False);{ Draw highlight }
Y1 := (Y2 + Y1) DIV 2; { Middle of thumb }
Y2 := Y1+1; { One line down }
Inc(X1, 1); { One in off left }
Dec(X2, 1); { One in off right }
BiColorRectangle(X1, Y1, X2, Y2, 15, 8, True); { Draw line marker }
End;
ShowMouseCursor; { Show the mouse }
End;
ReleaseViewLimits; { Release the limits }
End;
END;
{--TScrollBar---------------------------------------------------------------}
{ ClearPos -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
{ This could be called from a message handling event so it must check the }
{ view is visible, exposed and not obstructed before clearing the old }
{ thumbnail area. }
{---------------------------------------------------------------------------}
PROCEDURE TScrollBar.ClearPos (Pos: Sw_Integer);
VAR X, Y: Sw_Integer; ViewPort: ViewPortType;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) Then Begin { View is exposed }
SetViewLimits; { Set view limits }
GetViewSettings(ViewPort, TextModeGFV); { Get set viewport }
If OverlapsArea(ViewPort.X1, ViewPort.Y1,
ViewPort.X2, ViewPort.Y2) Then Begin { Must be in area }
HideMouseCursor; { Hide the mouse }
X := 0; { Initial x position }
Y := 0; { Initial y position }
If (Size.X=1) Then Y := Pos + FontHeight { Vertical bar }
Else X := Pos + FontWidth; { Horizontal bar }
ClearArea(X, Y, X+FontWidth-1, Y+FontHeight-1,
GetColor(1) AND $F0 SHR 4); { Clear the area }
ShowMouseCursor; { Show the mouse }
End;
ReleaseViewLimits; { Release the limits }
End;
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TScroller OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TScroller----------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TScroller.Init (Var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
BEGIN
Inherited Init(Bounds); { Call ancestor }
Options := Options OR ofSelectable; { View is selectable }
EventMask := EventMask OR evBroadcast; { See broadcasts }
HScrollBar := AHScrollBar; { Hold horz scrollbar }
VScrollBar := AVScrollBar; { Hold vert scrollbar }
END;
{--TScroller----------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
{ This load method will read old original TV data from a stream as well }
{ as the new graphical scroller views. }
{---------------------------------------------------------------------------}
CONSTRUCTOR TScroller.Load (Var S: TStream);
VAR i: Integer;
BEGIN
Inherited Load(S); { Call ancestor }
GetPeerViewPtr(S, HScrollBar); { Load horz scrollbar }
GetPeerViewPtr(S, VScrollBar); { Load vert scrollbar }
S.Read(i, SizeOf(i)); Delta.X:=i; { Read delta x value }
S.Read(i, SizeOf(i)); Delta.Y:=i; { Read delta y value }
S.Read(i, SizeOf(i)); Limit.X:=i; { Read limit x value }
S.Read(i, SizeOf(i)); Limit.Y:=i; { Read limit y value }
END;
{--TScroller----------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
FUNCTION TScroller.GetPalette: PPalette;
CONST P: String[Length(CScroller)] = CScroller; { Always normal string }
BEGIN
GetPalette := @P; { Scroller palette }
END;
{--TScroller----------------------------------------------------------------}
{ ScrollTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScroller.ScrollTo (X, Y: Sw_Integer);
BEGIN
Inc(DrawLock); { Set draw lock }
If (HScrollBar<>Nil) Then HScrollBar^.SetValue(X); { Set horz scrollbar }
If (VScrollBar<>Nil) Then VScrollBar^.SetValue(Y); { Set vert scrollbar }
Dec(DrawLock); { Release draw lock }
CheckDraw; { Check need to draw }
END;
{--TScroller----------------------------------------------------------------}
{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScroller.SetState (AState: Word; Enable: Boolean);
PROCEDURE ShowSBar (SBar: PScrollBar);
BEGIN
If (SBar <> Nil) Then { Scroll bar valid }
If GetState(sfActive + sfSelected) Then { Check state masks }
SBar^.Show Else SBar^.Hide; { Draw appropriately }
END;
BEGIN
Inherited SetState(AState, Enable); { Call ancestor }
If (AState AND (sfActive + sfSelected) <> 0) { Active/select change }
Then Begin
ShowSBar(HScrollBar); { Redraw horz scrollbar }
ShowSBar(VScrollBar); { Redraw vert scrollbar }
End;
END;
{--TScroller----------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
{ The scroller is saved to the stream compatable with the old TV object. }
{---------------------------------------------------------------------------}
PROCEDURE TScroller.Store (Var S: TStream);
VAR i: Integer;
BEGIN
TView.Store(S); { Call TView explicitly }
PutPeerViewPtr(S, HScrollBar); { Store horz bar }
PutPeerViewPtr(S, VScrollBar); { Store vert bar }
i:=Delta.X;S.Write(i, SizeOf(i)); { Write delta x value }
i:=Delta.Y;S.Write(i, SizeOf(i)); { Write delta y value }
i:=Limit.X;S.Write(i, SizeOf(i)); { Write limit x value }
i:=Limit.Y;S.Write(i, SizeOf(i)); { Write limit y value }
END;
{--TScroller----------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScroller.HandleEvent (Var Event: TEvent);
BEGIN
Inherited HandleEvent(Event); { Call ancestor }
If (Event.What = evBroadcast) AND
(Event.Command = cmScrollBarChanged) AND { Scroll bar change }
((Event.InfoPtr = HScrollBar) OR { Our scrollbar? }
(Event.InfoPtr = VScrollBar)) Then ScrollDraw; { Redraw scroller }
END;
{--TScroller----------------------------------------------------------------}
{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TScroller.ChangeBounds (Var Bounds: TRect);
BEGIN
SetBounds(Bounds); { Set new bounds }
Inc(DrawLock); { Set draw lock }
SetLimit(Limit.X, Limit.Y); { Adjust limits }
Dec(DrawLock); { Release draw lock }
DrawFlag := False; { Clear draw flag }
DrawView; { Redraw now }
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TListViewer OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
CONST TvListViewerName = 'LISTBOX'; { Native name }
{--TListViewer--------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TListViewer.Init (Var Bounds: TRect; ANumCols: Sw_Word; AHScrollBar,
AVScrollBar: PScrollBar);
VAR ArStep, PgStep: Sw_Integer;
BEGIN
Inherited Init(Bounds); { Call ancestor }
Options := Options OR (ofFirstClick+ofSelectable); { Set options }
EventMask := EventMask OR evBroadcast; { Set event mask }
NumCols := ANumCols; { Hold column number }
If (AVScrollBar <> Nil) Then Begin { Chk vert scrollbar }
If (NumCols = 1) Then Begin { Only one column }
PgStep := Size.Y -1; { Set page size }
ArStep := 1; { Set step size }
End Else Begin { Multiple columns }
PgStep := Size.Y * NumCols; { Set page size }
ArStep := Size.Y; { Set step size }
End;
AVScrollBar^.SetStep(PgStep, ArStep); { Set scroll values }
End;
If (AHScrollBar <> Nil) Then
AHScrollBar^.SetStep(Size.X DIV NumCols, 1); { Set step size }
HScrollBar := AHScrollBar; { Horz scrollbar held }
VScrollBar := AVScrollBar; { Vert scrollbar held }
GOptions := GOptions OR goDrawFocus; { Draw focus changes }
END;
{--TListViewer--------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TListViewer.Load (Var S: TStream);
VAR w: Word;
BEGIN
Inherited Load(S); { Call ancestor }
GetPeerViewPtr(S, HScrollBar); { Get horz scrollbar }
GetPeerViewPtr(S, VScrollBar); { Get vert scrollbar }
S.Read(w, SizeOf(w)); NumCols:=w; { Read column number }
S.Read(w, SizeOf(w)); TopItem:=w; { Read top most item }
S.Read(w, SizeOf(w)); Focused:=w; { Read focused item }
S.Read(w, SizeOf(w)); Range:=w; { Read listview range }
END;
{--TListViewer--------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TListViewer.GetPalette: PPalette;
CONST P: String[Length(CListViewer)] = CListViewer; { Always normal string }
BEGIN
GetPalette := @P; { Return palette }
END;
{--TListViewer--------------------------------------------------------------}
{ IsSelected -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TListViewer.IsSelected (Item: Sw_Integer): Boolean;
BEGIN
If (Item = Focused) Then IsSelected := True Else
IsSelected := False; { Selected item }
END;
{--TListViewer--------------------------------------------------------------}
{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
{---------------------------------------------------------------------------}
FUNCTION TListViewer.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
BEGIN { Abstract method }
GetText := ''; { Return empty }
END;
{--TListViewer--------------------------------------------------------------}
{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.DrawBackGround;
VAR I, J, ColWidth, Item, Indent, CurCol: Sw_Integer; Color: Word;
Text: String; B: TDrawBuffer;
BEGIN
ColWidth := Size.X DIV NumCols + 1; { Calc column width }
If (HScrollBar = Nil) Then Indent := 0 Else { Set indent to zero }
Indent := HScrollBar^.Value; { Fetch any indent }
Inherited DrawBackGround; { Call ancestor }
Color := GetColor(2); { Normal colour }
For I := 0 To Size.Y - 1 Do Begin { For each line }
For J := 0 To NumCols-1 Do Begin { For each column }
Item := J*Size.Y + I + TopItem; { Process this item }
CurCol := J*ColWidth; { Current column }
MoveChar(B[CurCol], ' ', Color, ColWidth); { Clear buffer }
If (Item < Range) Then Begin { Within text range }
Text := GetText(Item, ColWidth + Indent); { Fetch text }
Text := Copy(Text, Indent, ColWidth); { Select right bit }
MoveStr(B[CurCol+1], Text, Color); { Transfer to buffer }
If ShowMarkers Then Begin
WordRec(B[CurCol]).Lo := Byte(
SpecialChars[4]); { Set marker character }
WordRec(B[CurCol+ColWidth-2]).Lo := Byte(
SpecialChars[5]); { Set marker character }
End;
End;
MoveChar(B[CurCol+ColWidth-1], #179,
GetColor(5), 1); { Put centre line marker }
End;
WriteLine(0, I, Size.X-1, 1, B); { Write line to screen }
End;
END;
{--TListViewer--------------------------------------------------------------}
{ DrawFocus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.DrawFocus;
VAR DrawIt: Boolean; SCOff: Byte; I, J, Item, CurCol, ColWidth: Sw_Integer;
Color: Word;
Indent: Sw_Integer;
B: TDrawBuffer;
Text: String;
BEGIN
ColWidth := Size.X DIV NumCols + 1; { Calc column width }
If (HScrollBar = Nil) Then Indent := 0 Else { Set indent to zero }
Indent := HScrollBar^.Value; { Fetch any indent }
For I := 0 To Size.Y - 1 Do Begin { For each line }
For J := 0 To NumCols-1 Do Begin { For each column }
Item := J*Size.Y + I + TopItem; { Process this item }
CurCol := J*ColWidth; { Current column }
DrawIt := False; { Preset false }
If (State AND (sfSelected + sfActive) =
(sfSelected + sfActive)) AND (Focused = Item) { Focused item }
AND (Range > 0) Then Begin
DrawIt := True; { Draw this item }
Color := GetColor(3); { Focused colour }
SetCursor(CurCol+1,I); { Set the cursor }
SCOff := 0; { Zero colour offset }
End Else If (Item < Range) AND IsSelected(Item){ Selected item }
Then Begin
DrawIt := True; { Draw this item }
If (State AND sfActive <> 0) Then
Color := GetColor(4) Else { Selected colour }
Color := GetColor(2); { Remove focus }
SCOff := 2; { Colour offset=2 }
End;
If DrawIt Then Begin { We are drawing item }
ClearArea(CurCol*FontWidth, I*FontHeight, (CurCol+ColWidth-1)*FontWidth,
(I+1)*FontHeight-1, Color AND $F0 SHR 4); { Draw the bar }
MoveChar(B[CurCol], ' ', Color, ColWidth);
if Item < Range then begin
Text := GetText(Item, ColWidth + Indent);
Text := Copy(Text,Indent,ColWidth);
MoveStr(B[CurCol+1], Text, Color);
if ShowMarkers then begin
WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
end;
end;
{ MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);}
WriteLine(CurCol, I, Min(Size.X-1-CurCol,ColWidth-2), 1, B[CurCol]);
End;
End;
End;
END;
{--TListViewer--------------------------------------------------------------}
{ DrawLoseFocus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.DrawLoseFocus;
VAR DrawIt: Boolean; SCOff: Byte; I, J, Item, CurCol, ColWidth: Sw_Integer;
Color: Word;
Indent: Sw_Integer;
B: TDrawBuffer;
Text: String;
BEGIN
ColWidth := Size.X DIV NumCols + 1; { Calc column width }
If (HScrollBar = Nil) Then Indent := 0 Else { Set indent to zero }
Indent := HScrollBar^.Value; { Fetch any indent }
For I := 0 To Size.Y - 1 Do Begin { For each line }
For J := 0 To NumCols-1 Do Begin { For each column }
Item := J*Size.Y + I + TopItem; { Process this item }
CurCol := J*ColWidth; { Current column }
DrawIt := False; { Preset false }
If (State AND (sfSelected + sfActive) =
(sfSelected + sfActive)) AND (Focused = Item) { Focused item }
AND (Range > 0) Then Begin
DrawIt := True; { Draw this item }
Color := GetColor(2); { Focused colour }
SetCursor(CurCol+1,I); { Set the cursor }
SCOff := 2; { Zero colour offset }
End Else If (Item < Range) AND IsSelected(Item){ Selected item }
Then Begin
DrawIt := True; { Draw this item }
Color := GetColor(2); { Remove focus }
SCOff := 2; { Colour offset=2 }
End;
If DrawIt Then Begin { We are drawing item }
ClearArea(CurCol*FontWidth, I*FontHeight, (CurCol+ColWidth-1)*FontWidth,
(I+1)*FontHeight-1, Color AND $F0 SHR 4); { Draw the bar }
MoveChar(B[CurCol], ' ', Color, ColWidth);
if Item < Range then begin
Text := GetText(Item, ColWidth + Indent);
Text := Copy(Text,Indent,ColWidth);
MoveStr(B[CurCol+1], Text, Color);
if ShowMarkers then begin
WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
end;
end;
{ MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);}
WriteLine(CurCol, I, Min(Size.X-1-CurCol,ColWidth-2), 1, B[CurCol]);
End;
End;
End;
END;
{--TListViewer--------------------------------------------------------------}
{ FocusItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.FocusItem (Item: Sw_Integer);
BEGIN
If Focused<>Item then
DrawLoseFocus;
Focused := Item; { Set focus to item }
If (VScrollBar <> Nil) Then
VScrollBar^.SetValue(Item); { Scrollbar to value }
If (Item < TopItem) Then { Item above top item }
If (NumCols = 1) Then TopItem := Item { Set top item }
Else TopItem := Item - Item MOD Size.Y { Set top item }
Else If (Item >= TopItem + (Size.Y*NumCols)) Then { Item below bottom }
If (NumCols = 1) Then TopItem := Item-Size.Y+1 { Set new top item }
Else TopItem := Item - Item MOD Size.Y -
(Size.Y*(NumCols-1)); { Set new top item }
END;
{--TListViewer--------------------------------------------------------------}
{ SetTopItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Aug99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.SetTopItem (Item: Sw_Integer);
BEGIN
TopItem := Item; { Set the top item }
END;
{--TListViewer--------------------------------------------------------------}
{ SetRange -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.SetRange (ARange: Sw_Integer);
BEGIN
Range := ARange; { Set new range }
If (VScrollBar <> Nil) Then Begin { Vertical scrollbar }
If (Focused > ARange) Then Focused := 0; { Clear focused }
VScrollBar^.SetParams(Focused, 0, ARange - 1,
VScrollBar^.PgStep, VScrollBar^.ArStep); { Set parameters }
End;
END;
{--TListViewer--------------------------------------------------------------}
{ SelectItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.SelectItem (Item: Sw_Integer);
BEGIN
Message(Owner, evBroadcast, cmListItemSelected,
@Self); { Send message }
END;
{--TListViewer--------------------------------------------------------------}
{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.SetState (AState: Word; Enable: Boolean);
PROCEDURE ShowSBar(SBar: PScrollBar);
BEGIN
If (SBar <> Nil) Then { Valid scrollbar }
If GetState(sfActive) AND GetState(sfVisible) { Check states }
Then SBar^.Show Else SBar^.Hide; { Show or hide }
END;
PROCEDURE LoseFocus;
VAR Cs: Sw_Integer;
BEGIN
If (GOptions AND goNativeClass = 0) Then Begin { Not in native mode }
Cs := State; { Hold current state }
State := State AND NOT sfActive; { Must remove focus }
SetDrawmask(vdFocus); { Set focus mask }
DrawView; { Remove focus box }
State := Cs; { Reset state masks }
End;
END;
BEGIN
Inherited SetState(AState, Enable); { Call ancestor }
If (AState AND sfFocused <> 0) Then { Focus change }
If NOT Enable Then LoseFocus; { Redraw drop focus }
If (AState AND (sfSelected + sfActive + sfVisible) <> 0)
Then Begin { Check states }
SetDrawMask(vdFocus);
DrawView; { Draw the view }
ShowSBar(HScrollBar); { Show horz scrollbar }
ShowSBar(VScrollBar); { Show vert scrollbar }
End;
END;
{--TListViewer--------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.Store (Var S: TStream);
VAR w: Word;
BEGIN
TView.Store(S); { Call TView explicitly }
PutPeerViewPtr(S, HScrollBar); { Put horz scrollbar }
PutPeerViewPtr(S, VScrollBar); { Put vert scrollbar }
w:=NumCols;S.Write(w, SizeOf(w)); { Write column number }
w:=TopItem;S.Write(w, SizeOf(w)); { Write top most item }
w:=Focused;S.Write(w, SizeOf(w)); { Write focused item }
w:=Range;S.Write(w, SizeOf(w)); { Write listview range }
END;
{--TListViewer--------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.HandleEvent (Var Event: TEvent);
CONST MouseAutosToSkip = 4;
VAR Oi, Ni: Sw_Integer; Ct, Cw: Word; Mouse: TPoint;
PROCEDURE MoveFocus (Req: Sw_Integer);
VAR Ti, Cs: Sw_Integer;
BEGIN
If (GOptions AND goNativeClass = 0) Then Begin { Not in native mode }
Ti := TopItem; { Hold top item }
Cs := State; { Hold current state }
State := State AND NOT sfActive; { Must remove focus }
SetDrawmask(vdFocus); { Set focus mask }
DrawView; { Remove focus box }
State := Cs; { Reset state masks }
End;
FocusItemNum(Req); { Focus req item }
If (GOptions AND goNativeClass = 0) Then Begin { Not in native mode }
If (Ti <> TopItem) Then DrawView Else Begin { Redraw all view }
SetDrawmask(vdFocus); { Set focus mask }
DrawView; { Redraw focus box }
End;
End;
END;
BEGIN
Inherited HandleEvent(Event); { Call ancestor }
Case Event.What Of
evNothing: Exit; { Speed up exit }
evKeyDown: Begin { Key down event }
If (Event.CharCode = ' ') AND (Focused < Range){ Spacebar select }
Then Begin
SelectItem(Focused); { Select focused item }
Ni := Focused; { Hold new item }
End Else Case CtrlToArrow(Event.KeyCode) Of
kbUp: Ni := Focused - 1; { One item up }
kbDown: Ni := Focused + 1; { One item down }
kbRight: If (NumCols > 1) Then
Ni := Focused + Size.Y Else Exit; { One column right }
kbLeft: If (NumCols > 1) Then
Ni := Focused - Size.Y Else Exit; { One column left }
kbPgDn: Ni := Focused + Size.Y * NumCols; { One page down }
kbPgUp: Ni := Focused - Size.Y * NumCols; { One page up }
kbHome: Ni := TopItem; { Move to top }
kbEnd: Ni := TopItem + (Size.Y*NumCols)-1; { Move to bottom }
kbCtrlPgDn: Ni := Range - 1; { Move to last item }
kbCtrlPgUp: Ni := 0; { Move to first item }
Else Exit;
End;
MoveFocus(Ni); { Move the focus }
ClearEvent(Event); { Event was handled }
End;
evBroadcast: Begin { Broadcast event }
If (Options AND ofSelectable <> 0) Then { View is selectable }
If (Event.Command = cmScrollBarClicked) AND { Scrollbar click }
((Event.InfoPtr = HScrollBar) OR
(Event.InfoPtr = VScrollBar)) Then Select { Scrollbar selects us }
Else If (Event.Command = cmScrollBarChanged) { Scrollbar changed }
Then Begin
If (VScrollBar = Event.InfoPtr) Then Begin
MoveFocus(VScrollBar^.Value); { Focus us to item }
End Else If (HScrollBar = Event.InfoPtr)
Then DrawView; { Redraw the view }
End;
End;
evMouseDown: Begin { Mouse down event }
Cw := Size.X DIV NumCols + 1; { Column width }
Oi := Focused; { Hold focused item }
MakeLocal(Event.Where, Mouse); { Localize mouse }
If MouseInView(Event.Where) Then Ni := Mouse.Y
+ (Size.Y*(Mouse.X DIV Cw))+TopItem { Calc item to focus }
Else Ni := Oi; { Focus old item }
Ct := 0; { Clear count value }
Repeat
If (Ni <> Oi) Then Begin { Item is different }
MoveFocus(Ni); { Move the focus }
Oi := Focused; { Hold as focused item }
End;
MakeLocal(Event.Where, Mouse); { Localize mouse }
If NOT MouseInView(Event.Where) Then Begin
If (Event.What = evMouseAuto) Then Inc(Ct);{ Inc auto count }
If (Ct = MouseAutosToSkip) Then Begin
Ct := 0; { Reset count }
If (NumCols = 1) Then Begin { Only one column }
If (Mouse.Y < 0) Then Ni := Focused-1; { Move up one item }
If (Mouse.Y >= Size.Y) Then
Ni := Focused+1; { Move down one item }
End Else Begin { Multiple columns }
If (Mouse.X < 0) Then { Mouse x below zero }
Ni := Focused-Size.Y; { Move down 1 column }
If (Mouse.X >= Size.X) Then { Mouse x above width }
Ni := Focused+Size.Y; { Move up 1 column }
If (Mouse.Y < 0) Then { Mouse y below zero }
Ni := Focused-Focused MOD Size.Y; { Move up one item }
If (Mouse.Y > Size.Y) Then { Mouse y above height }
Ni := Focused-Focused MOD
Size.Y+Size.Y-1; { Move down one item }
End;
End;
End Else Ni := Mouse.Y + (Size.Y*(Mouse.X
DIV Cw))+TopItem; { New item to focus }
Until NOT MouseEvent(Event, evMouseMove +
evMouseAuto); { Mouse stopped }
If (Oi <> Ni) Then MoveFocus(Ni); { Focus moved again }
If (Event.Double AND (Range > Focused)) Then
SelectItem(Focused); { Select the item }
ClearEvent(Event); { Event was handled }
End;
End;
END;
{--TListViewer--------------------------------------------------------------}
{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.ChangeBounds (Var Bounds: TRect);
BEGIN
Inherited ChangeBounds(Bounds); { Call ancestor }
If (HScrollBar <> Nil) Then { Valid horz scrollbar }
HScrollBar^.SetStep(Size.X DIV NumCols,
HScrollBar^.ArStep); { Update horz bar }
If (VScrollBar <> Nil) Then { Valid vert scrollbar }
VScrollBar^.SetStep(Size.Y * NumCols,
VScrollBar^.ArStep); { Update vert bar }
END;
{***************************************************************************}
{ TListViewer OBJECT PRIVATE METHODS }
{***************************************************************************}
{--TListViewer--------------------------------------------------------------}
{ FocusItemNum -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TListViewer.FocusItemNum (Item: Sw_Integer);
BEGIN
If (Item < 0) Then Item := 0 Else { Restrain underflow }
If (Item >= Range) AND (Range > 0) Then
Item := Range-1; { Restrain overflow }
If (Range <> 0) Then FocusItem(Item); { Set focus value }
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TWindow OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TWindow------------------------------------------------------------------}
{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
CONSTRUCTOR TWindow.Init (Var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
BEGIN
Inherited Init(Bounds); { Call ancestor }
State := State OR sfShadow; { View is shadowed }
Options := Options OR (ofSelectable+ofTopSelect); { Select options set }
GrowMode := gfGrowAll + gfGrowRel; { Set growmodes }
Flags := wfMove + wfGrow + wfClose + wfZoom; { Set flags }
Title := NewStr(ATitle); { Hold title }
Number := ANumber; { Hold number }
Palette := wpBlueWindow; { Default palette }
GOptions := GOptions OR goThickFramed; { Thick frame }
GOptions := GOptions OR goTitled; { Title window }
GOptions := GOptions AND NOT goNoDrawView; { View does draw self }
InitFrame; { Initialize frame }
If (Frame <> Nil) Then Insert(Frame); { Insert any frame }
GetBounds(ZoomRect); { Default zoom rect }
END;
{--TWindow------------------------------------------------------------------}
{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
{ This load method will read old original TV data from a stream however }
{ although a frame view is read for compatability it is disposed of. }
{---------------------------------------------------------------------------}
CONSTRUCTOR TWindow.Load (Var S: TStream);
VAR I: Integer;
BEGIN
Inherited Load(S); { Call ancestor }
S.Read(Flags, SizeOf(Flags)); { Read window flags }
S.Read(i, SizeOf(i)); Number:=i; { Read window number }
S.Read(i, SizeOf(i)); Palette:=i; { Read window palette }
S.Read(i, SizeOf(i)); ZoomRect.A.X:=i; { Read zoom area x1 }
S.Read(i, SizeOf(i)); ZoomRect.A.Y:=i; { Read zoom area y1 }
S.Read(i, SizeOf(i)); ZoomRect.B.X:=i; { Read zoom area x2 }
S.Read(i, SizeOf(i)); ZoomRect.B.Y:=i; { Read zoom area y2 }
GetSubViewPtr(S, Frame); { Now read frame object }
If (Frame <> Nil) Then Begin
Dispose(Frame, Done); { Kill we don't use it }
Frame := Nil; { Clear the pointer }
End;
Title := S.ReadStr; { Read title }
END;
{--TWindow------------------------------------------------------------------}
{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
DESTRUCTOR TWindow.Done;
BEGIN
Inherited Done; { Call ancestor }
If (Title <> Nil) Then DisposeStr(Title); { Dispose title }
END;
{--TWindow------------------------------------------------------------------}
{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TWindow.GetPalette: PPalette;
CONST P: ARRAY [wpBlueWindow..wpGrayWindow] Of String[Length(CBlueWindow)] =
(CBlueWindow, CCyanWindow, CGrayWindow); { Always normal string }
BEGIN
GetPalette := @P[Palette]; { Return palette }
END;
{--TWindow------------------------------------------------------------------}
{ GetTitle -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{ Modified 31may2002 PM (No number included anymore) }
{---------------------------------------------------------------------------}
FUNCTION TWindow.GetTitle (MaxSize: Sw_Integer): TTitleStr;
VAR S: String;
BEGIN
If (Title <> Nil) Then S:=Title^
Else S := '';
if Length(S)>MaxSize then
GetTitle:=Copy(S,1,MaxSize)
else
GetTitle:=S;
END;
{--TWindow------------------------------------------------------------------}
{ StandardScrollBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION TWindow.StandardScrollBar (AOptions: Word): PScrollBar;
VAR R: TRect; S: PScrollBar;
BEGIN
GetExtent(R); { View extents }
If (AOptions AND sbVertical = 0) Then
R.Assign(R.A.X+2, R.B.Y-1, R.B.X-2, R.B.Y) { Horizontal scrollbar }
Else R.Assign(R.B.X-1, R.A.Y+1, R.B.X, R.B.Y-1); { Vertical scrollbar }
S := New(PScrollBar, Init(R)); { Create scrollbar }
Insert(S); { Insert scrollbar }
If (AOptions AND sbHandleKeyboard <> 0) Then
S^.Options := S^.Options or ofPostProcess; { Post process }
StandardScrollBar := S; { Return scrollbar }
END;
{--TWindow------------------------------------------------------------------}
{ Zoom -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.Zoom;
VAR R: TRect; Max, Min: TPoint;
BEGIN
SizeLimits(Min, Max); { Return size limits }
If ((Size.X <> Max.X) OR (Size.Y <> Max.Y)) { Larger size possible }
Then Begin
GetBounds(ZoomRect); { Get zoom bounds }
R.A.X := 0; { Zero x origin }
R.A.Y := 0; { Zero y origin }
R.B := Max; { Bounds to max size }
Locate(R); { Locate the view }
End Else Locate(ZoomRect); { Move to zoom rect }
END;
{--TWindow------------------------------------------------------------------}
{ Close -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.Close;
BEGIN
If Valid(cmClose) Then Free; { Dispose of self }
END;
{--TWindow------------------------------------------------------------------}
{ InitFrame -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.InitFrame;
BEGIN { Compatability only }
END;
{--TWindow------------------------------------------------------------------}
{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.SetState (AState: Word; Enable: Boolean);
VAR WindowCommands: TCommandSet;
BEGIN
Inherited SetState(AState, Enable); { Call ancestor }
If (AState = sfSelected) Then
SetState(sfActive, Enable); { Set active state }
If (AState = sfSelected) OR ((AState = sfExposed)
AND (State AND sfSelected <> 0)) Then Begin { View is selected }
WindowCommands := [cmNext, cmPrev]; { Set window commands }
If (Flags AND (wfGrow + wfMove) <> 0) Then
WindowCommands := WindowCommands + [cmResize]; { Add resize command }
If (Flags AND wfClose <> 0) Then
WindowCommands := WindowCommands + [cmClose]; { Add close command }
If (Flags AND wfZoom <> 0) Then
WindowCommands := WindowCommands + [cmZoom]; { Add zoom command }
If Enable Then EnableCommands(WindowCommands) { Enable commands }
Else DisableCommands(WindowCommands); { Disable commands }
End;
END;
{--TWindow------------------------------------------------------------------}
{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
{---------------------------------------------------------------------------}
{ You can save data to the stream compatable with the old original TV by }
{ temporarily turning off the ofGrafVersion making the call to this store }
{ routine and resetting the ofGrafVersion flag after the call. }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.Store (Var S: TStream);
VAR i: Integer;
BEGIN
TGroup.Store(S); { Call group store }
S.Write(Flags, SizeOf(Flags)); { Write window flags }
i:=Number;S.Write(i, SizeOf(i)); { Write window number }
i:=Palette;S.Write(i, SizeOf(i)); { Write window palette }
i:=ZoomRect.A.X;S.Write(i, SizeOf(i)); { Write zoom area x1 }
i:=ZoomRect.A.Y;S.Write(i, SizeOf(i)); { Write zoom area y1 }
i:=ZoomRect.B.X;S.Write(i, SizeOf(i)); { Write zoom area x2 }
i:=ZoomRect.B.Y;S.Write(i, SizeOf(i)); { Write zoom area y2 }
PutSubViewPtr(S, Frame); { Write any frame }
S.WriteStr(Title); { Write title string }
END;
{--TWindow------------------------------------------------------------------}
{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11Aug99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.HandleEvent (Var Event: TEvent);
VAR I, J: Sw_Integer;
Min, Max: TPoint; Limits: TRect;
PROCEDURE DragWindow (Mode: Byte);
VAR Limits: TRect; Min, Max: TPoint;
BEGIN
Owner^.GetExtent(Limits); { Get owner extents }
SizeLimits(Min, Max); { Restrict size }
DragView(Event, DragMode OR Mode, Limits, Min,
Max); { Drag the view }
ClearEvent(Event); { Clear the event }
END;
BEGIN
Inherited HandleEvent(Event); { Call ancestor }
Case Event.What Of
evNothing: Exit; { Speeds up exit }
evCommand: { COMMAND EVENT }
Case Event.Command Of { Command type case }
cmResize: { RESIZE COMMAND }
If (Flags AND (wfMove + wfGrow) <> 0) { Window can resize }
AND (Owner <> Nil) Then Begin { Valid owner }
Owner^.GetExtent(Limits); { Owners extents }
SizeLimits(Min, Max); { Check size limits }
DragView(Event, DragMode OR (Flags AND
(wfMove + wfGrow)), Limits, Min, Max); { Drag the view }
ClearEvent(Event); { Clear the event }
End;
cmClose: { CLOSE COMMAND }
If (Flags AND wfClose <> 0) AND { Close flag set }
((Event.InfoPtr = Nil) OR { None specific close }
(Event.InfoPtr = @Self)) Then Begin { Close to us }
ClearEvent(Event); { Clear the event }
If (State AND sfModal = 0) Then Close { Non modal so close }
Else Begin { Modal window }
Event.What := evCommand; { Command event }
Event.Command := cmCancel; { Cancel command }
PutEvent(Event); { Place on queue }
ClearEvent(Event); { Clear the event }
End;
End;
cmZoom: { ZOOM COMMAND }
If (Flags AND wfZoom <> 0) AND { Zoom flag set }
((Event.InfoPtr = Nil) OR { No specific zoom }
(Event.InfoPtr = @Self)) Then Begin
Zoom; { Zoom our window }
ClearEvent(Event); { Clear the event }
End;
End;
evBroadcast: { BROADCAST EVENT }
If (Event.Command = cmSelectWindowNum) AND
(Event.InfoInt = Number) AND { Select our number }
(Options AND ofSelectable <> 0) Then Begin { Is view selectable }
Select; { Select our view }
ClearEvent(Event); { Clear the event }
End;
evKeyDown: Begin { KEYDOWN EVENT }
Case Event.KeyCode Of
kbTab: Begin { TAB KEY }
FocusNext(False); { Select next view }
ClearEvent(Event); { Clear the event }
End;
kbShiftTab: Begin { SHIFT TAB KEY }
FocusNext(True); { Select prior view }
ClearEvent(Event); { Clear the event }
End;
End;
End;
evMouseDown: { MOUSE DOWN EVENT }
If (GOptions AND goTitled <> 0) Then Begin { Must have title area }
If TextModeGFV then
I:=0 Else
If (GOptions AND goThickFramed <> 0) Then
I := 5 Else { Thick frame adjust }
If (Options AND ofFramed <> 0) Then I := 1 { Frame adjust }
Else I := 0; { No frame size }
If (Event.Where.Y >= (RawOrigin.Y + I)) AND
(Event.Where.Y < RawOrigin.Y+FontHeight+I)
Then Begin { Within top line }
If (Current <> Nil) AND
(Current^.Options AND ofSelectable <> 0)
Then Current^.FocusFromTop Else
FocusFromTop;
If (Flags AND wfClose <> 0) Then Begin { Has close icon }
J := I + 2*FontWidth; { Set X value }
If (Event.Where.X >= RawOrigin.X+J) AND
(Event.Where.X < RawOrigin.X+J+3*FontWidth)
Then Begin { In close area }
Event.What := evCommand; { Command event }
Event.Command := cmClose; { Close command }
Event.InfoPtr := Nil; { Clear pointer }
PutEvent(Event); { Put event on queue }
ClearEvent(Event); { Clear the event }
Exit; { Now exit }
End;
End;
If (Flags AND wfZoom <> 0) Then Begin { Has Zoom icon }
J := (SIZE.X-5)*FontWidth; { Set X value }
If (Event.Where.X >= RawOrigin.X+J) AND
(Event.Where.X < RawOrigin.X+J+3*FontWidth)
Then Begin { In close area }
Event.What := evCommand; { Command event }
Event.Command := cmZoom; { Close command }
Event.InfoPtr := Nil; { Clear pointer }
PutEvent(Event); { Put event on queue }
ClearEvent(Event); { Clear the event }
Exit; { Now exit }
End;
End;
If (Owner <> Nil) AND (Flags AND wfMove <> 0)
Then DragWindow(dmDragMove); { Drag the window }
End Else If (Event.Where.X >= RawOrigin.X + RawSize.X-2*FontWidth) AND
(Event.Where.Y >= RawOrigin.Y + RawSize.Y - FontHeight)
Then If (Flags AND wfGrow <> 0) Then { Check grow flags }
DragWindow(dmDragGrow); { Change window size }
End;
End; { Event.What case end }
END;
{--TWindow------------------------------------------------------------------}
{ SizeLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TWindow.SizeLimits (Var Min, Max: TPoint);
BEGIN
Inherited SizeLimits(Min, Max); { View size limits }
Min.X := MinWinSize.X; { Set min x size }
Min.Y := MinWinSize.Y; { Set min y size }
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ UNCOMPLETED OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TView--------------------------------------------------------------------}
{ Exposed -> Platforms DOS/DPMI/WIN/OS2 - Checked 17Sep97 LdB }
{---------------------------------------------------------------------------}
{ This needs big help!!!!! }
FUNCTION TView.Exposed: Boolean;
VAR ViewPort: ViewPortType;
BEGIN
GetViewSettings(ViewPort, TextModeGFV); { Fetch viewport }
If (State AND sfVisible<>0) AND { View visible }
(State AND sfExposed<>0) AND { View exposed }
OverlapsArea(ViewPort.X1, ViewPort.Y1,
ViewPort.X2, ViewPort.Y2) Then Exposed := True { Must be exposed }
Else Exposed := False; { Is hidden }
END;
{--TView--------------------------------------------------------------------}
{ GraphLine -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.GraphLine (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
VAR ViewPort: ViewPortType;
x,y,i,j : sw_integer;
BEGIN
GetViewSettings(ViewPort, TextModeGFV); { Get viewport settings }
If (TextModeGFV <> TRUE) Then Begin
SetColor(Colour); { Set line colour }
Line(RawOrigin.X + X1 - ViewPort.X1,
RawOrigin.Y + Y1 - ViewPort.Y1, RawOrigin.X + X2
- ViewPort.X1, RawOrigin.Y + Y2-ViewPort.Y1); { Draw the line }
{ mark the corresponding lines as without chars }
{$IFDEF GRAPH_API}
If UseFixedFont then
begin
if abs(x1-x2)<abs(y1-y2) then
begin
for j:=y1 to y2 do
begin
y:=(RawOrigin.y + j);
x:=(RawOrigin.X + X1 + ((x2-x1)*(j-y1)) div (y2-y1));
if (x>=0) and (x<=Graph.GetMaxX) and (y>=0) and (y<=Graph.GetMaxY) then
SetExtraInfo(x div SysFontWidth,y div SysFontHeight,
x mod SysFontWidth,y mod SysFontHeight, Colour);
end;
end
else
begin
for j:=x1 to x2 do
begin
x:=(RawOrigin.x + j);
y:=(RawOrigin.y + y1 + ((j-x1)*(y2-y1)) div (x2-x1));
if (x>=0) and (x<=Graph.GetMaxX) and (y>=0) and (y<=Graph.GetMaxY) then
SetExtraInfo(x div SysFontWidth,y div SysFontHeight,
x mod SysFontWidth,y mod SysFontHeight, Colour);
end;
end;
end;
{$ENDIF GRAPH_API}
End Else Begin { LEON???? }
End;
END;
PROCEDURE TView.GraphRectangle (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
VAR ViewPort: ViewPortType;
BEGIN
If (TextModeGFV <> TRUE) Then Begin { GRAPHICS MODE GFV }
If UseFixedFont then
begin
Graphline(x1,y1,x1,y2,colour);
Graphline(x1,y2,x2,y2,colour);
Graphline(x2,y2,x2,y1,colour);
Graphline(x2,y1,x1,y1,colour);
end
else
begin
SetColor(Colour); { Set line colour }
GetViewSettings(ViewPort, TextModeGFV);
Rectangle(RawOrigin.X + X1 - ViewPort.X1, RawOrigin.Y + Y1
- ViewPort.Y1, RawOrigin.X + X2 - ViewPort.X1,
RawOrigin.Y+Y2-ViewPort.Y1); { Draw a rectangle }
end;
End Else Begin { LEON???? }
End;
END;
{--TView--------------------------------------------------------------------}
{ ClearArea -> Platforms DOS/DPMI/WIN/OS2 - Checked 19Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.ClearArea (X1, Y1, X2, Y2: Sw_Integer; Colour: Byte);
VAR
X, Y: Sw_Integer; ViewPort: ViewPortType;
Buf : TDrawBuffer;
BEGIN
GetViewSettings(ViewPort, TextModeGFV); { Get viewport }
If not TextModeGFV {and not UseFixedFont} Then Begin { GRAPHICAL GFV MODE }
SetFillStyle(SolidFill, Colour); { Set colour up }
Bar(RawOrigin.X+X1-ViewPort.X1, RawOrigin.Y+Y1-
ViewPort.Y1, RawOrigin.X+X2-ViewPort.X1,
RawOrigin.Y+Y2-ViewPort.Y1); { Clear the area }
{ Force redraw if something new is written after }
if UseFixedFont and assigned(OldVideoBuf) then
begin
X1 := (RawOrigin.X+X1) DIV SysFontWidth;
Y1 := (RawOrigin.Y+Y1) DIV SysFontHeight;
X2 := (RawOrigin.X+X2-1) DIV SysFontWidth;
Y2 := (RawOrigin.Y+Y2-1) DIV SysFontHeight;
For Y := Y1 To Y2 Do
For X := X1 To X2 Do
begin
VideoBuf^[Y*TextScreenWidth+X]:=0;
OldVideoBuf^[Y*TextScreenWidth+X]:=0;
end;
end;
End Else Begin { TEXT MODE GFV }
X1 := (RawOrigin.X+X1) DIV SysFontWidth;
Y1 := (RawOrigin.Y+Y1) DIV SysFontHeight;
X2 := (RawOrigin.X+X2-1) DIV SysFontWidth;
Y2 := (RawOrigin.Y+Y2-1) DIV SysFontHeight;
For X := X1 To X2 Do Begin
Buf[X-X1]:=(Colour shl 12) or $20;
End;
For Y := Y1 To Y2 Do
WriteAbs(X1,Y, X2-X1, Buf);
DrawScreenBuf;
End;
END;
PROCEDURE TView.GraphArc (Xc, Yc: Sw_Integer; Sa, Ea: Real; XRad, YRad: Sw_Integer;
Colour: Byte);
CONST RadConv = 57.2957795130823229; { Degrees per radian }
VAR X1, Y1, X2, Y2, X3, Y3: Sw_Integer; {$IFDEF OS_WINDOWS} ODc: hDc; {$ENDIF}
BEGIN
{$IFDEF NOT_IMPLEMENTED}
{$IFDEF OS_WINDOWS}
Xc := Xc - FrameSize;
Yc := Yc - CaptSize;
{$ENDIF}
While (Ea < -360) Do Ea := Ea + 360; { Max of a full circle }
While (Ea > 360) Do Ea := Ea - 360; { Max of a full circle }
Sa := Sa/RadConv; { Convert to radians }
Ea := Ea/RadConv; { Convert to radians }
X1 := Xc + Round(Sin(Sa)*XRad); { Calc 1st x value }
Y1 := Yc - Round(Cos(Sa)*YRad); { Calc 1st y value }
X2 := Xc + Round(Sin(Sa+Ea)*XRad); { Calc 2nd x value }
Y2 := Yc - Round(Cos(Sa+Ea)*YRad); { Calc 2nd y value }
X3 := X2; { Use X2 value }
Y3 := Y2; { Use Y2 value }
If (Abs(Ea) > Pi) Then Begin
X3 := Xc + Round(Sin(Sa+Pi)*XRad); { Calc 3rd x value }
Y3 := Yc - Round(Cos(Sa+Pi)*YRad); { Calc 3rd y value }
End;
{$IFDEF OS_WINDOWS}
If (HWindow <> 0) Then Begin { Valid window }
ODc := Dc; { Hold device context }
If (Dc = 0) Then Dc := GetDC(HWindow); { Create a context }
SelectObject(Dc, ColPen[Colour]); { Pen colour }
If (Abs(X1-X3) > 1) OR (Abs(Y1-Y3) > 1) { Must exceed 2x2 arc }
Then Begin
If (Ea < 0) Then
Arc(Dc, Xc-XRad, Yc-YRad, Xc+XRad, Yc+YRad,
X1, Y1, X2, Y2) Else { Draw c/clkwise arc }
Arc(Dc, Xc-XRad, Yc-YRad, Xc+XRad, Yc+YRad,
X2, Y2, X1, Y1); { Draw clockwise arc }
End;
If (ODc = 0) Then ReleaseDC(HWindow, Dc); { Release context }
Dc := ODc; { Reset held context }
End;
{$ENDIF}
{$ENDIF NOT_IMPLEMENTED}
END;
PROCEDURE TView.FilletArc (Xc, Yc: Sw_Integer; Sa, Ea: Real; XRad, YRad, Ht: Sw_Integer;
Colour: Byte);
CONST RadConv = 57.2957795130823229; { Degrees per radian }
{$IFDEF OS_WINDOWS} VAR X1, Y1, X2, Y2, X3, Y3, X4, Y4: Sw_Integer; ODc: hDc; {$ENDIF}
BEGIN
{$IFDEF NOT_IMPLEMENTED}
{$IFDEF OS_WINDOWS}
If (HWindow <> 0) Then Begin { Valid window }
Xc := Xc - FrameSize;
Yc := Yc - CaptSize;
ODc := Dc; { Hold device context }
If (Dc = 0) Then Dc := GetDC(HWindow); { Create a context }
Ea := (Ea-Sa);
While (Ea<-360) Do Ea := Ea+360; { One lap only }
While (Ea>360) Do Ea := Ea-360; { One lap only }
X1 := Round(Sin(Sa/RadConv)*XRad);
Y1 := -Round(Cos(Sa/RadConv)*YRad); { Calc 1st values }
X2 := Round(Sin((Sa+Ea)/RadConv)*XRad);
Y2 := -Round(Cos((Sa+Ea)/RadConv)*YRad); { Calc 2nd values }
X3 := Round(Sin(Sa/RadConv)*(XRad+Ht));
Y3 := -Round(Cos(Sa/RadConv)*(YRad+Ht)); { Calc 3rd values }
X4 := Round(Sin((Sa+Ea)/RadConv)*(XRad+Ht));
Y4 := -Round(Cos((Sa+Ea)/RadConv)*(YRad+Ht)); { Calc 4th values }
SelectObject(Dc, ColPen[Colour]); { Pen colour }
{$IFDEF WIN32}
MoveToEx(Dc, Xc+X1, Yc+Y1, Nil); { Move to first point }
{$ELSE}
WinProcs.MoveTo(Dc, Xc+X1, Yc+Y1); { Move to first point }
{$ENDIF}
LineTo(Dc, Xc+X3, Yc+Y3);
{$IFDEF WIN32}
MoveToEx(Dc, Xc+X2, Yc+Y2, Nil);
{$ELSE}
WinProcs.MoveTo(Dc, Xc+X2, Yc+Y2);
{$ENDIF}
LineTo(Dc, Xc+X4, Yc+Y4);
If (Ea < 0) Then
Arc(Dc, Xc-XRad-Ht, Yc-YRad-Ht, Xc+XRad+Ht, Yc+YRad+Ht,
Xc+X1, Yc+Y1, Xc+X2, Yc+Y2) Else
Arc(Dc, Xc-XRad-Ht, Yc-YRad-Ht, Xc+XRad+Ht, Yc+YRad+Ht,
Xc+X2, Yc+Y2, Xc+X1, Yc+Y1); { Draw arc }
If (Ea < 0) Then
Arc(Dc, Xc-XRad, Yc-YRad, Xc+XRad, Yc+YRad,
Xc+X3, Yc+Y3, Xc+X4, Yc+Y4) Else
Arc(Dc, Xc-XRad, Yc-YRad, Xc+XRad, Yc+YRad,
Xc+X4, Yc+Y4, Xc+X3, Yc+Y3); { Draw arc }
If (ODc = 0) Then ReleaseDC(HWindow, Dc); { Release context }
Dc := ODc; { Reset held context }
End;
{$ENDIF}
{$ENDIF NOT_IMPLEMENTED}
END;
{--TView--------------------------------------------------------------------}
{ BiColorRectangle -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.BicolorRectangle (X1, Y1, X2, Y2: Sw_Integer; Light, Dark: Byte;
Down: Boolean);
VAR UpperLeft, RightDown: Byte;
BEGIN
If Down Then Begin
UpperLeft := Dark; { Dark upper left }
RightDown := Light; { Light down }
End Else Begin
UpperLeft := Light; { Light upper left }
RightDown := Dark; { Dark down }
End;
GraphLine(X1, Y1, X1, Y2, UpperLeft); { Draw left side }
GraphLine(X1, Y1, X2, Y1, UpperLeft); { Draw top line }
GraphLine(X1, Y2, X2, Y2, RightDown); { Draw bottom line }
GraphLine(X2, Y1, X2, Y2, RightDown); { Draw right line }
END;
PROCEDURE TView.WriteBuf (X, Y, W, H: Sw_Integer; Var Buf);
VAR I, J, K, L, CW: Sw_Integer; P: PDrawBuffer;
Tix, Tiy: Sw_Integer; ViewPort: ViewPortType;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfIconised = 0) AND { View is not icon}
(State AND sfExposed <> 0) AND (W > 0) AND (H > 0) { View is exposed }
then begin
P := @TDrawBuffer(Buf); { Set draw buffer ptr }
L := 0; { Set buffer position }
If (X >= 0) AND (Y >= 0) AND ((GOptions and (goGraphical or goGraphView))=0) Then Begin
X := RawOrigin.X+X*FontWidth; { X position }
Y := RawOrigin.Y+Y*FontHeight; { Y position }
End Else Begin
X := RawOrigin.X + Abs(X);
Y := RawOrigin.Y + Abs(Y);
End;
If TextModeGFV or UseFixedFont then Begin
X := X DIV SysFontWidth;
Y := Y DIV SysFontHeight;
End;
GetViewSettings(ViewPort, TextModeGFV); { Get current viewport }
If not TextModeGFV and not UseFixedFont then Begin
X := X - ViewPort.X1; { Calc x position }
Y := Y - ViewPort.Y1; { Calc y position }
End;
For J := 1 To H Do Begin { For each line }
If (TextModeGFV) or UseFixedFont Then Begin { TEXT MODE GFV }
WriteAbs(X,Y,W,P^[L]);
Inc(Y);
Inc(L,W);
End Else Begin
K := X; { Reset x position }
For I := 0 To (W-1) Do Begin { For each character }
Cw := TextWidth(Chr(Lo(P^[L]))); { Width of this char }
SetFillStyle(SolidFill, Hi(P^[L]) AND
$F0 SHR 4); { Set back colour }
SetColor(Hi(P^[L]) AND $0F); { Set text colour }
Bar(K, Y, K+Cw, Y+FontHeight-1); { Clear text backing }
OutTextXY(K, Y+2, Chr(Lo(P^[L]))); { Write text char }
Inc(K,Cw);
Inc(L); { Next character }
End;
Y := Y + SysFontHeight; { Next line down }
end;
DrawScreenBuf;
End;
end;
END;
PROCEDURE TView.WriteLine (X, Y, W, H: Sw_Integer; Var Buf);
VAR I, J, K, Cw: Sw_Integer; P: PDrawBuffer;
Tix, Tiy: Sw_Integer; ViewPort: ViewPortType;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfIconised = 0) AND { View is not icon}
(State AND sfExposed <> 0) AND (W > 0) AND (H > 0) { View is exposed }
then begin
P := @TDrawBuffer(Buf); { Set draw buffer ptr }
If (X >= 0) AND (Y >= 0) AND ((GOptions and (goGraphical or goGraphView))=0) Then Begin
X := RawOrigin.X+X*FontWidth; { X position }
Y := RawOrigin.Y+Y*FontHeight; { Y position }
End Else Begin
X := RawOrigin.X + Abs(X);
Y := RawOrigin.Y + Abs(Y);
End;
If TextModeGFV or UseFixedFont then Begin
X := X DIV SysFontWidth;
Y := Y DIV SysFontHeight;
End;
GetViewSettings(ViewPort, TextModeGFV); { Get current viewport }
If not TextModeGFV and not UseFixedFont then Begin
X := X - ViewPort.X1; { Calc x position }
Y := Y - ViewPort.Y1; { Calc y position }
End;
For J := 1 To H Do Begin { For each line }
If (TextModeGFV) or UseFixedFont Then Begin { TEXT MODE GFV }
WriteAbs(X,Y,W,P^);
Inc(Y);
End Else Begin
K := X; { Reset x position }
For I := 0 To (W-1) Do Begin { For each character }
Cw := TextWidth(Chr(Lo(P^[I]))); { Width of this char }
SetFillStyle(SolidFill, Hi(P^[I]) AND
$F0 SHR 4); { Set back colour }
SetColor(Hi(P^[I]) AND $0F); { Set text colour }
Bar(K, Y, K+Cw, Y+FontHeight-1); { Clear text backing }
{$IFDEF GRAPH_API}
SetTextJustify(LeftText,TopText);
{$ENDIF GRAPH_API}
OutTextXY(K, Y+2, Chr(Lo(P^[I]))); { Write text char }
Inc(K,Cw);
End;
Y := Y + SysFontHeight; { Next line down }
End;
end;
If TextModeGFV or UseFixedFont then
DrawScreenBuf;
End;
END;
{--TView--------------------------------------------------------------------}
{ MakeLocal -> Platforms DOS/DPMI/WIN/OS2 - Checked 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.MakeLocal (Source: TPoint; Var Dest: TPoint);
BEGIN
If (Options AND ofGFVModeView <> 0) Then Begin { GFV MODE TVIEW }
Dest.X := (Source.X-RawOrigin.X) DIV FontWidth; { Local x value }
Dest.Y := (Source.Y-RawOrigin.Y) DIV FontHeight; { Local y value }
End Else Begin { OLD MODE TVIEW }
Dest.X := Source.X - Origin.X; { Local x value }
Dest.Y := Source.Y - Origin.Y; { Local y value }
End;
END;
{--TView--------------------------------------------------------------------}
{ MakeGlobal -> Platforms DOS/DPMI/WIN/OS2 - Checked 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.MakeGlobal (Source: TPoint; Var Dest: TPoint);
BEGIN
If (Options AND ofGFVModeView <> 0) Then Begin { GFV MODE TVIEW }
Dest.X := Source.X*FontWidth + RawOrigin.X; { Global x value }
Dest.Y := Source.Y*FontHeight + RawOrigin.Y; { Global y value }
End Else Begin { OLD MODE TVIEW }
Dest.X := Source.X + Origin.X; { Global x value }
Dest.Y := Source.Y + Origin.Y; { Global y value }
End;
END;
PROCEDURE TView.WriteCStr (X, Y: Sw_Integer; Str: String; Color1, Color2 : Byte);
VAR I, J, Fc, Bc, B: Byte; X1, Y1, X2, Y2: Sw_Integer;
Xw, Yw, TiBuf, Tix, Tiy, Ti: Sw_Integer; ViewPort: ViewPortType;
Buf : TDrawBuffer;
FoundSwap : boolean;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) AND { View is exposed }
(State AND sfIconised = 0) AND { View not iconized }
(Length(Str) > 0) Then Begin { String is valid }
j:=1;
repeat
FoundSwap:=false;
i:=PosIdx('~',Str,j);
if i>0 then
FoundSwap:=true
else
i:=Length(Str)+1;
Fc := GetColor(Color1); { Get view color }
Bc := Fc AND $F0 SHR 4; { Calc back colour }
Fc := Fc AND $0F; { Calc text colour }
If RevCol Then Begin
B := Bc;
Bc := Fc;
Fc := B;
End;
If (X >= 0) AND (Y >= 0) AND ((GOptions and goGraphView)=0) Then Begin
Xw := RawOrigin.X+X*FontWidth; { X position }
Yw := RawOrigin.Y+Y*FontHeight; { Y position }
End Else Begin
Xw := RawOrigin.X + Abs(X);
Yw := RawOrigin.Y + Abs(Y);
End;
GetViewSettings(ViewPort, TextModeGFV);
If not TextModeGFV and not UseFixedFont Then Begin { GRAPHICAL MODE GFV }
SetFillStyle(SolidFill, Bc); { Set fill style }
Bar(Xw-ViewPort.X1, Yw-ViewPort.Y1,
Xw-ViewPort.X1+Length(Str)*FontWidth,
Yw-ViewPort.Y1+FontHeight-1);
SetColor(Fc);
OutTextXY(Xw-ViewPort.X1, Yw-ViewPort.Y1+2, Copy(Str,j,i-j));{ Write text char }
End Else Begin { TEXT MODE GFV }
Tix := Xw DIV SysFontWidth;
Tiy := Yw DIV SysFontHeight;
TiBuf := 0;
For Ti := j To i-1 Do Begin
Buf[TiBuf]:=((Fc or (Bc shl 4)) shl 8) or Ord(Str[Ti]);
inc(TiBuf);
end;
WriteAbs(Tix,TiY,i-j,Buf);
End;
{ increase position on screen }
If (X >= 0) AND (Y >= 0) AND ((GOptions and goGraphView)=0) Then
inc(X,(i-j))
else if X>0 then
inc(X,(i-j)*FontWidth)
else
dec(X,(i-j)*FontWidth);
{ Swap colors }
if FoundSwap then
begin
{ Swap color1 and color2 }
B := Color1;
Color1 := Color2;
Color2 := B;
{ increase position in string }
j:=i+1;
{ we're at the last char }
if (j>length(Str)) then
break;
end;
until not FoundSwap;
If TextModeGFV then
DrawScreenBuf;
End;
END;
PROCEDURE TView.WriteStr (X, Y: Sw_Integer; Str: String; Color: Byte);
VAR Fc, Bc, B: Byte; X1, Y1, X2, Y2: Sw_Integer;
Tix, Tiy, Ti: Sw_Integer; ViewPort: ViewPortType;
Buf : TDrawBuffer;
BEGIN
If (State AND sfVisible <> 0) AND { View is visible }
(State AND sfExposed <> 0) AND { View is exposed }
(State AND sfIconised = 0) AND { View not iconized }
(Length(Str) > 0) Then Begin { String is valid }
Fc := GetColor(Color); { Get view color }
Bc := Fc AND $F0 SHR 4; { Calc back colour }
Fc := Fc AND $0F; { Calc text colour }
If RevCol Then Begin
B := Bc;
Bc := Fc;
Fc := B;
End;
If (X >= 0) AND (Y >= 0) AND ((GOptions and goGraphView)=0) Then Begin
X := RawOrigin.X+X*FontWidth; { X position }
Y := RawOrigin.Y+Y*FontHeight; { Y position }
End Else Begin
X := RawOrigin.X + Abs(X);
Y := RawOrigin.Y + Abs(Y);
End;
GetViewSettings(ViewPort, TextModeGFV);
If not TextModeGFV and not UseFixedFont Then Begin { GRAPHICAL MODE GFV }
SetFillStyle(SolidFill, Bc); { Set fill style }
Bar(X-ViewPort.X1, Y-ViewPort.Y1,
X-ViewPort.X1+Length(Str)*FontWidth,
Y-ViewPort.Y1+FontHeight-1);
SetColor(Fc);
OutTextXY(X-ViewPort.X1, Y-ViewPort.Y1+2, Str);{ Write text char }
End Else Begin { TEXT MODE GFV }
Tix := X DIV SysFontWidth;
Tiy := Y DIV SysFontHeight;
For Ti := 1 To length(Str) Do Begin
Buf[Ti-1]:=(GetColor(Color) shl 8) or Ord(Str[Ti]);
end;
WriteAbs(Tix,TiY,Length(Str),Buf);
End;
If TextModeGFV or UseFixedFont then
DrawScreenBuf;
End;
END;
PROCEDURE TView.WriteChar (X, Y: Sw_Integer; C: Char; Color: Byte;
Count: Sw_Integer);
VAR Fc, Bc, B: Byte; I, Ti, Tix, Tiy: Sw_Integer; Col: Word; S: String; ViewPort: ViewPortType;
Buf : TDrawBuffer;
BEGIN
If (State AND sfVisible <> 0) AND { View visible }
(State AND sfExposed <> 0) Then Begin { View exposed }
GetViewSettings(ViewPort, TextModeGFV);
Col := GetColor(Color); { Get view color }
Fc := Col AND $0F; { Foreground colour }
Bc := Col AND $F0 SHR 4; { Background colour }
If RevCol Then Begin
B := Bc;
Bc := Fc;
Fc := B;
End;
If (X >= 0) AND (Y >= 0) AND ((GOptions and goGraphView)=0) Then Begin
X := RawOrigin.X+X*FontWidth; { X position }
Y := RawOrigin.Y+Y*FontHeight; { Y position }
End Else Begin
X := RawOrigin.X + Abs(X);
Y := RawOrigin.Y + Abs(Y);
End;
FillChar(S[1], 255, C); { Fill the string }
While (Count>0) Do Begin
If (Count>Size.X) Then I := Size.X Else I := Count; { Size to make }
S[0] := Chr(I); { Set string length }
If not TextModeGFV and not UseFixedFont Then Begin { GRAPHICAL MODE GFV }
SetFillStyle(SolidFill, Bc); { Set fill style }
Bar(X-ViewPort.X1, Y-ViewPort.Y1,
X-ViewPort.X1+I*FontWidth,
Y-ViewPort.Y1+FontHeight-1);
SetColor(Fc);
OutTextXY(X-ViewPort.X1, Y-ViewPort.Y1+2, S); { Write text char }
End Else Begin { TEXT MODE GFV }
Tix := X DIV SysFontWidth;
Tiy := Y DIV SysFontHeight;
For Ti := 1 To I Do Begin
Buf[Ti-1]:=(GetColor(Color) shl 8) or Ord(S[Ti]);
End;
WriteAbs(TiX,TiY,Length(S),Buf);
End;
Count := Count - I; { Subtract count }
If TextModeGFV or UseFixedFont then
X := X + I { Move x position }
else
X := X + I*FontWidth; { Move x position }
End;
If TextModeGFV or UseFixedFont then
DrawScreenBuf;
End;
END;
PROCEDURE TView.WriteAbs(X, Y, L : Sw_Integer; Var Buf);
VAR
P: PGroup;
PrevP,PP : PView;
CurOrigin : TPoint;
I,XI : longint;
ViewPort : ViewPortType;
Skip : boolean;
BEGIN
{$ifdef DEBUG}
if WriteDebugInfo then
Begin
Writeln(stderr,'TView(',hexstr(longint(@self),8),')');
Writeln(stderr,'Object Type(',hexstr(plongint(@self)^,8),')');
Writeln(stderr,'WriteAbs(',X,',',Y,',',L,',',hexstr(longint(@Buf),8),')');
End;
{$endif DEBUG}
{ Direct wrong method }
GetViewSettings(ViewPort, TextModeGFV or UseFixedFont); { Get set viewport }
{ Pedestrian character method }
{ Must be in area }
If (X+L<ViewPort.X1) OR (Y<ViewPort.Y1) OR
(X>=ViewPort.X2) OR (Y>=ViewPort.Y2) Then
Exit;
For I:=0 to L-1 do Begin
P:=Owner;
PrevP :=@Self;
XI:=X+I;
{ Must be in area }
If (XI<ViewPort.X1) OR
(XI>=ViewPort.X2) Then
Continue;
Skip:=false;
While Assigned(P) do Begin
{ If parent not visible or
position outside parent's limit then skip }
if not assigned(P^.Buffer) AND
(((P^.State AND sfVisible) = 0) OR
(XI<P^.Origin.X) OR (XI>=P^.Origin.X+P^.Size.X) OR
(Y<P^.Origin.Y) OR (Y>=P^.Origin.Y+P^.Size.Y)) then
Begin
Skip:=true;
Break;
End;
{ Here we must check if X,Y is exposed for this view }
PP:=P^.Last;
{ move to first }
If Assigned(PP) then
PP:=PP^.Next;
While Assigned(PP) and (PP<>P^.Last) and (PP<>PrevP) do Begin
{ If position is owned by another view that is before self
then skip }
If ((PP^.State AND sfVisible) <> 0) AND
(XI>=PP^.Origin.X) AND
(XI<PP^.Origin.X+PP^.Size.X) AND
(Y>=PP^.Origin.Y) AND
(Y<PP^.Origin.Y+PP^.Size.Y) then
Begin
Skip:=true;
break;
End;
PP:=PP^.Next;
End;
If Not Skip and Assigned(P^.Buffer) then Begin
begin
P^.Buffer^[(Y-P^.Origin.Y)*P^.size.X+(XI-P^.Origin.X)]:=TDrawBuffer(Buf)[I];
{$IFDEF GRAPH_API}
If (pointer(P^.Buffer)=pointer(VideoBuf)) and (SpVideoBuf^[Y*TextScreenWidth+XI]=EmptyVideoBufCell) then
OldVideoBuf^[Y*TextScreenWidth+XI]:=0;
{$ENDIF GRAPH_API}
end;
End;
PrevP:=P;
If Skip then
P:=Nil
else
P:=P^.Owner;
End;
End;
END;
{define DirectWriteShadow}
PROCEDURE TView.WriteShadow(X1, Y1, X2, Y2 : Sw_Integer);
VAR
P: PGroup;
PrevP,PP : PView;
CurOrigin : TPoint;
I,J : longint;
Col,OrigCol : byte;
B : Word;
ViewPort : ViewPortType;
Skip : boolean;
BEGIN
GetViewSettings(ViewPort, TextModeGFV); { Get set viewport }
{ Pedestrian character method }
{ Must be in area }
{If (X+L<ViewPort.X1) OR (Y<ViewPort.Y1) OR
(X>=ViewPort.X2) OR (Y>=ViewPort.Y2) Then
Exit;}
If Y2>ScreenHeight then
Y2:=ScreenHeight;
If X2>ScreenWidth then
X2:=ScreenWidth;
For J:=Y1 to Y2-1 do Begin
For i:=X1 to X2-1 do Begin
P:=Owner;
PrevP :=@Self;
{ Must be in area
If (XI<ViewPort.X1) OR
(XI>=ViewPort.X2) Then
Continue; }
Skip:=false;
While Assigned(P) do Begin
if not assigned(P^.Buffer) AND
(((P^.State AND sfVisible) = 0) OR
(I<P^.Origin.X) OR (I>=P^.Origin.X+P^.Size.X) OR
(J<P^.Origin.Y) OR (J>=P^.Origin.Y+P^.Size.Y)) then
Begin
Skip:=true;
Break;
End;
{ Here we must check if X,Y is exposed for this view }
PP:=P^.Last;
{ move to first }
If Assigned(PP) then
PP:=PP^.Next;
While Assigned(PP) and (PP<>P^.Last) and (PP<>PrevP) do Begin
If ((PP^.State AND sfVisible) <> 0) AND
(I>=PP^.Origin.X) AND
(I<PP^.Origin.X+PP^.Size.X) AND
(J>=PP^.Origin.Y) AND
(J<PP^.Origin.Y+PP^.Size.Y) then
Begin
Skip:=true;
Break;
End;
PP:=PP^.Next;
End;
If not Skip and Assigned(P^.Buffer) then Begin
B:=P^.Buffer^[(J-P^.Origin.Y)*P^.size.X+(I-P^.Origin.X)];
OrigCol:=B shr 8;
if OrigCol and $F >= 8 then
Col:=OrigCol and $7
else
Col:=0;
P^.Buffer^[(J-P^.Origin.Y)*P^.size.X+(I-P^.Origin.X)]:= (col shl 8) or (B and $FF);
End;
PrevP:=P;
If Skip then
P:=Nil
else
P:=P^.Owner;
End;
End;
End;
END;
PROCEDURE TView.DragView (Event: TEvent; Mode: Byte; Var Limits: TRect;
MinSize, MaxSize: TPoint);
VAR PState: Word; Mouse, Q, R, P, S, Op1, Op2: TPoint; SaveBounds: TRect;
PROCEDURE MoveGrow (P, S: TPoint);
VAR R: TRect;
BEGIN
S.X := Min(Max(S.X, MinSize.X), MaxSize.X); { Minimum S.X value }
S.Y := Min(Max(S.Y, MinSize.Y), MaxSize.Y); { Minimum S.Y value }
P.X := Min(Max(P.X, Limits.A.X - S.X + 1),
Limits.B.X - 1); { Minimum P.X value }
P.Y := Min(Max(P.Y, Limits.A.Y - S.Y + 1),
Limits.B.Y - 1); { Mimimum P.Y value }
If (Mode AND dmLimitLoX <> 0) Then
P.X := Max(P.X, Limits.A.X); { Left side move }
If (Mode AND dmLimitLoY <> 0) Then
P.Y := Max(P.Y, Limits.A.Y); { Top side move }
If (Mode AND dmLimitHiX <> 0) Then
P.X := Min(P.X, Limits.B.X - S.X); { Right side move }
If (Mode AND dmLimitHiY <> 0) Then
P.Y := Min(P.Y, Limits.B.Y - S.Y); { Bottom side move }
R.Assign(P.X, P.Y, P.X + S.X, P.Y + S.Y); { Assign area }
Locate(R); { Locate view }
END;
PROCEDURE Change (DX, DY: Sw_Integer);
BEGIN
If (Mode AND dmDragMove <> 0) AND
(GetShiftState AND $03 = 0) Then Begin
Inc(P.X, DX); Inc(P.Y, DY); { Adjust values }
End Else If (Mode AND dmDragGrow <> 0) AND
(GetShiftState AND $03 <> 0) Then Begin
Inc(S.X, DX); Inc(S.Y, DY); { Adjust values }
End;
END;
PROCEDURE Update (X, Y: Sw_Integer);
BEGIN
If (Mode AND dmDragMove <> 0) Then Begin
P.X := X; P.Y := Y; { Adjust values }
End;
END;
BEGIN
SetState(sfDragging, True); { Set drag state }
If (Event.What = evMouseDown) Then Begin { Mouse down event }
Q.X := Event.Where.X DIV FontWidth - Origin.X; { Offset mouse x origin }
Q.Y := Event.Where.Y DIV FontHeight - Origin.Y; { Offset mouse y origin }
Op1.X := RawOrigin.X; Op1.Y := RawOrigin.Y; { Hold origin point }
Op2.X := RawOrigin.X+RawSize.X; { Right side x value }
Op2.Y := RawOrigin.Y+RawSize.Y; { Right side y value }
PState := State; { Hold current state }
if not TextModeGFV then
State := State AND NOT sfVisible; { Temp not visible }
HideMouseCursor; { Hide the mouse }
SetWriteMode(XORPut, TextModeGFV);
GraphRectangle(0, 0, RawSize.X, RawSize.Y, Red);
SetWriteMode(NormalPut, TextModeGFV);
ShowMouseCursor; { Show the mouse }
Repeat
Mouse.X := Round(Event.Where.X/FontWidth)-Q.X; { New x origin point }
Mouse.Y := Round(Event.Where.Y/FontHeight)-Q.Y;{ New y origin point }
If (Mode AND dmDragMove<>0) Then Begin
If (Owner<>Nil) Then Begin
Dec(Mouse.X, Owner^.Origin.X); { Sub owner x origin }
Dec(Mouse.Y, Owner^.Origin.Y); { Sub owner y origin }
End;
R := Mouse; Mouse := Size; { Exchange values }
End Else Begin
R := Origin; { Start at origin }
If (Owner<>Nil) Then Begin
Dec(R.X, Owner^.Origin.X); { Sub owner x origin }
Dec(R.Y, Owner^.Origin.Y); { Sub owner y origin }
End;
Mouse.X := Mouse.X+Q.X-Origin.X;
Mouse.Y := Mouse.Y+Q.Y-Origin.Y;
End;
HideMouseCursor; { Hide the mouse }
if not TextModeGFV then
begin
SetWriteMode(XORPut, TextModeGFV);
GraphRectangle(0, 0, RawSize.X, RawSize.Y, Red);
SetWriteMode(NormalPut, TextModeGFV);
MoveGrow(R, Mouse); { Resize the view }
SetWriteMode(XORPut, TextModeGFV);
GraphRectangle(0, 0, RawSize.X, RawSize.Y, Red);
SetWriteMode(NormalPut, TextModeGFV);
end
else
begin
MoveGrow(R, Mouse); { Resize the view }
end;
ShowMouseCursor; { Show the mouse }
Until NOT MouseEvent(Event, evMouseMove); { Finished moving }
State := PState; { Restore view state }
If (Owner<>Nil) Then
Owner^.ReDrawArea(Op1.X, Op1.Y, Op2.X, Op2.Y); { Redraw old area }
SetState(sfDragging, False); { Clr dragging flag }
DrawView; { Now redraw the view }
End Else Begin
GetBounds(SaveBounds); { Get current bounds }
Repeat
P := Origin; S := Size; { Set values }
If Assigned(Owner) then
Begin
Dec(P.X,Owner^.Origin.X);
Dec(P.Y,Owner^.Origin.Y);
End;
KeyEvent(Event); { Get key event }
Case Event.KeyCode AND $FF00 Of
kbLeft: Change(-1, 0); { Move left }
kbRight: Change(1, 0); { Move right }
kbUp: Change(0, -1); { Move up }
kbDown: Change(0, 1); { Move down }
kbCtrlLeft: Change(-8, 0);
kbCtrlRight: Change(8, 0);
kbHome: Update(Limits.A.X, P.Y);
kbEnd: Update(Limits.B.X - S.X, P.Y);
kbPgUp: Update(P.X, Limits.A.Y);
kbPgDn: Update(P.X, Limits.B.Y - S.Y);
End;
MoveGrow(P, S); { Now move the view }
Until (Event.KeyCode = kbEnter) OR
(Event.KeyCode = kbEsc);
If (Event.KeyCode=kbEsc) Then Locate(SaveBounds);{ Restore original }
End;
SetState(sfDragging, False); { Clr dragging flag }
END;
FUNCTION TView.FontWidth: Sw_Integer;
BEGIN
FontWidth := SysFontWidth;
END;
FUNCTION TView.FontHeight: Sw_Integer;
BEGIN
FontHeight := SysFontHeight;
END;
{***************************************************************************}
{ TScroller OBJECT METHODS }
{***************************************************************************}
PROCEDURE TScroller.ScrollDraw;
VAR D: TPoint;
BEGIN
If (HScrollBar<>Nil) Then D.X := HScrollBar^.Value
Else D.X := 0; { Horz scroll value }
If (VScrollBar<>Nil) Then D.Y := VScrollBar^.Value
Else D.Y := 0; { Vert scroll value }
If (D.X<>Delta.X) OR (D.Y<>Delta.Y) Then Begin { View has moved }
SetCursor(Cursor.X+Delta.X-D.X,
Cursor.Y+Delta.Y-D.Y); { Move the cursor }
Delta := D; { Set new delta }
If (DrawLock<>0) Then DrawFlag := True { Draw will need draw }
Else DrawView; { Redraw the view }
End;
END;
PROCEDURE TScroller.SetLimit (X, Y: Sw_Integer);
VAR PState: Word;
BEGIN
Limit.X := X; { Hold x limit }
Limit.Y := Y; { Hold y limit }
Inc(DrawLock); { Set draw lock }
If (HScrollBar<>Nil) Then Begin
PState := HScrollBar^.State; { Hold bar state }
HScrollBar^.State := PState AND NOT sfVisible; { Temp not visible }
HScrollBar^.SetParams(HScrollBar^.Value, 0,
X-Size.X, Size.X-1, HScrollBar^.ArStep); { Set horz scrollbar }
HScrollBar^.State := PState; { Restore bar state }
End;
If (VScrollBar<>Nil) Then Begin
PState := VScrollBar^.State; { Hold bar state }
VScrollBar^.State := PState AND NOT sfVisible; { Temp not visible }
VScrollBar^.SetParams(VScrollBar^.Value, 0,
Y-Size.Y, Size.Y-1, VScrollBar^.ArStep); { Set vert scrollbar }
VScrollBar^.State := PState; { Restore bar state }
End;
Dec(DrawLock); { Release draw lock }
CheckDraw; { Check need to draw }
END;
{***************************************************************************}
{ TScroller OBJECT PRIVATE METHODS }
{***************************************************************************}
PROCEDURE TScroller.CheckDraw;
BEGIN
If (DrawLock = 0) AND DrawFlag Then Begin { Clear & draw needed }
DrawFlag := False; { Clear draw flag }
DrawView; { Draw now }
End;
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ TGroup OBJECT METHODS }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{--TGroup-------------------------------------------------------------------}
{ Lock -> Platforms DOS/DPMI/WIN/OS2 - Checked 23Sep97 LdB }
{---------------------------------------------------------------------------}
{$ifndef NoLock}
{$define UseLock}
{$endif ndef NoLock}
PROCEDURE TGroup.Lock;
BEGIN
{$ifdef UseLock}
{If (Buffer <> Nil) OR (LockFlag <> 0)
Then} Inc(LockFlag); { Increment count }
{$endif UseLock}
END;
{--TGroup-------------------------------------------------------------------}
{ UnLock -> Platforms DOS/DPMI/WIN/OS2 - Checked 23Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Unlock;
BEGIN
{$ifdef UseLock}
If (LockFlag <> 0) Then Begin
Dec(LockFlag); { Decrement count }
If (LockFlag = 0) Then DrawView; { Lock release draw }
End;
{$endif UseLock}
END;
PROCEDURE TWindow.DrawBorder;
const
LargeC:array[boolean] of char=('^',#24);
RestoreC:array[boolean] of char=('|',#18);
ClickC:array[boolean] of char=('*',#15);
VAR Fc, Bc: Byte; X, Y: Sw_Integer; S: String;
ViewPort: ViewPortType;
I : Sw_Integer;
LeftUpCorner,
RightUpCorner,
HorizontalBar,
VerticalBar,
LeftLowCorner,
RightLowCorner,C : Char;
Color : Byte;
Focused : Boolean;
Min, Max: TPoint;
NP : PView;
BEGIN
Fc := GetColor(2) AND $0F; { Foreground colour }
Bc := (GetColor(2) AND $70) SHR 4; { Background colour }
If TextModeGFV then
Y:=0 else
begin
Y:=0;
(* If (Options AND ofFramed<>0) Then Y := 1
Else Y := 0; { Initial value }
If (GOptions AND goThickFramed<>0) Then Inc(Y, 3); { Adjust position }
*)
end;
ClearArea(0, Y, RawSize.X, Y+FontHeight-1, Bc); { Clear background }
If not TextModeGFV then
Inherited DrawBorder
Else Begin { TEXT GFV MODE }
{Focused:=(State AND (sfSelected + sfModal)<>0);
if Assigned(Owner) then
Focused := Focused AND (@Self = Owner^.Current); }
Focused:=(State AND sfActive)<>0;
If not Focused or (GOptions AND goThickFramed = 0) then
begin
LeftUpCorner:='<27>';
RightUpCorner:='<27>';
HorizontalBar:='<27>';
VerticalBar:='<27>';
LeftLowCorner:='<27>';
RightLowCorner:='<27>';
end
else
begin
LeftUpCorner:='<27>';
RightUpCorner:='<27>';
HorizontalBar:='<27>';
VerticalBar:='<27>';
LeftLowCorner:='<27>';
RightLowCorner:='<27>';
end;
if (State AND sfDragging)<>0 then
Color := 5
else if Focused then
Color := 2
else
Color := 1;
WriteChar(0,0,LeftUpCorner,Color,1);
WriteChar(1,0,HorizontalBar,Color,Size.X-2);
WriteChar(Size.X-1,0,RightUpcorner,Color,1);
For i:=1 to Size.Y -1 do
begin
WriteChar(0,i,VerticalBar,Color,1);
WriteChar(Size.X-1,i,VerticalBar,Color,1);
end;
WriteChar(0,Size.Y-1,LeftLowCorner,Color,1);
WriteChar(1,Size.Y-1,HorizontalBar,Color,Size.X-2);
WriteChar(Size.X-1,Size.Y-1,RightLowCorner,Color,1);
End;
If not TextModeGFV then
GOptions := GOptions OR goGraphView; { Graphics co-ords mode }
If (Title<>Nil) AND (GOptions AND goTitled<>0)
Then Begin { View has a title }
GetViewSettings(ViewPort, TextModeGFV);
X := (RawSize.X DIV 2); { Half way point }
X := X - ((Length(Title^)+2)*FontWidth) DIV 2; { Calc start point }
If (TextModeGFV <> TRUE) Then Begin { GRAPHICS MODE GFV }
(* SetColor(Fc);
OutTextXY(RawOrigin.X+X-ViewPort.X1,
RawOrigin.Y+Y+1-ViewPort.Y1+2, ' '+Title^+' '); { Write the title }*)
WriteStr(X,Y+1,' '+Title^+' ',Color);
End Else Begin { LEON??? }
WriteStr(X div SysFontWidth,0,' '+Title^+' ',Color);
End;
End;
If (Number>0) AND (Number<10) Then Begin { Valid number }
Str(Number, S); { Make number string }
If (Flags and wfZoom)<>0 then
I:=7
else
I:=3;
If (TextModeGFV <> True) Then Begin { GRAPHICS MODE GFV }
(* SetColor(GetColor(2) AND $0F);
OutTextXY(RawOrigin.X+RawSize.X-I*FontWidth-ViewPort.X1,
RawOrigin.Y+Y+1-ViewPort.Y1+2, S); { Write number } *)
WriteCStr(RawSize.X-I*FontWidth,Y+1,S,1,Color);
End Else Begin { LEON ????? }
WriteCStr(Size.X-I,0,S,1,Color);
End;
End;
If Focused and (Flags AND wfClose<>0) Then Begin { Close icon request }
If (TextModeGFV <> True) Then Begin { GRAPHICS MODE GFV }
(*SetColor(Fc);
OutTextXY(RawOrigin.X+Y+FontWidth-ViewPort.X1,
RawOrigin.Y+Y+1-ViewPort.Y1+2, '[*]'); { Write close icon } *)
WriteCStr(2*FontWidth,Y+1,'[~'+ClickC[LowAscii]+'~]', 2, 3);
End Else Begin { LEON??? }
WriteCStr(2,0,'[~'+ClickC[LowAscii]+'~]', 2, 3);
End;
End;
If Focused and (Flags AND wfZoom<>0) Then Begin
if assigned(Owner) and
(Size.X=Owner^.Size.X) and (Size.Y=Owner^.Size.Y) then
C:=RestoreC[LowAscii]
else
C:=LargeC[LowAscii];
If (TextModeGFV <> True) Then Begin { GRAPHICS MODE GFV }
(* SetColor(GetColor(2) AND $0F);
OutTextXY(RawOrigin.X+RawSize.X-4*FontWidth-Y-ViewPort.X1,
RawOrigin.Y+Y+1-ViewPort.Y1+2, '['+C+']'); { Write zoom icon } *)
WriteCStr(RawSize.X-5*FontWidth,Y+1,'[~'+C+'~]', 2, 3);
WriteCStr(RawSize.X-2*FontWidth,RawSize.Y-FontHeight+Y+1,'~<7E><>~',2, 3);
End Else Begin { LEON??? }
WriteCStr(Size.X-5,0,'[~'+C+'~]', 2, 3);
WriteCStr(Size.X-2,Size.Y-1,'~<7E><>~',2, 3);
End;
End;
If not TextModeGFV then
begin
BiColorRectangle(Y+1, Y+1, RawSize.X-Y-1, Y+FontHeight,
White, DarkGray, False); { Draw 3d effect }
BiColorRectangle(Y+1, Y+1, RawSize.X-Y-2, Y+FontHeight-1,
White, DarkGray, False); { Draw 3d effect }
GOptions := GOptions AND NOT goGraphView; { Return to normal mode }
end;
{ Ensure that the scrollers are repainted }
NP:=Last;
while assigned(NP) do
begin
If (NP^.Origin.X<=Origin.X) or
(NP^.Origin.Y<=Origin.Y) or
(NP^.Origin.X>=Origin.X+Size.X) or
(NP^.Origin.Y>=Origin.Y+Size.Y) then
begin
NP^.ReDrawArea(RawOrigin.X,RawOrigin.Y,
RawOrigin.X+FontWidth*Size.X,RawOrigin.Y+FontHeight);
NP^.ReDrawArea(RawOrigin.X,RawOrigin.Y+FontHeight*(Size.Y-1),
RawOrigin.X+FontWidth*Size.X,RawOrigin.Y+FontHeight*Size.Y);
NP^.ReDrawArea(RawOrigin.X,RawOrigin.Y+FontHeight,
RawOrigin.X+FontWidth,RawOrigin.Y+FontHeight*(Size.Y-1));
NP^.ReDrawArea(RawOrigin.X+FontWidth*(Size.X-1),RawOrigin.Y+FontHeight,
RawOrigin.X+FontWidth*Size.X,RawOrigin.Y+FontHeight*(Size.Y-1));
end;
NP:=NP^.Prevview;
end;
END;
{***************************************************************************}
{ INTERFACE ROUTINES }
{***************************************************************************}
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ WINDOW MESSAGE ROUTINES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{---------------------------------------------------------------------------}
{ Message -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION Message (Receiver: PView; What, Command: Word;
InfoPtr: Pointer): Pointer;
VAR Event: TEvent;
BEGIN
Message := Nil; { Preset nil }
If (Receiver <> Nil) Then Begin { Valid receiver }
Event.What := What; { Set what }
Event.Command := Command; { Set command }
Event.Id := 0; { Zero id field }
Event.Data := 0; { Zero data field }
Event.InfoPtr := InfoPtr; { Set info ptr }
Receiver^.HandleEvent(Event); { Pass to handler }
If (Event.What = evNothing) Then
Message := Event.InfoPtr; { Return handler }
End;
END;
{---------------------------------------------------------------------------}
{ NewMessage -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Sep97 LdB }
{---------------------------------------------------------------------------}
FUNCTION NewMessage (P: PView; What, Command: Word; Id: Sw_Integer;
Data: Real; InfoPtr: Pointer): Pointer;
VAR Event: TEvent;
BEGIN
NewMessage := Nil; { Preset failure }
If (P <> Nil) Then Begin
Event.What := What; { Set what }
Event.Command := Command; { Set event command }
Event.Id := Id; { Set up Id }
Event.Data := Data; { Set up data }
Event.InfoPtr := InfoPtr; { Set up event ptr }
P^.HandleEvent(Event); { Send to view }
If (Event.What = evNothing) Then
NewMessage := Event.InfoPtr; { Return handler }
End;
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ NEW VIEW ROUTINES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{---------------------------------------------------------------------------}
{ CreateIdScrollBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Checked 22May97 LdB }
{---------------------------------------------------------------------------}
FUNCTION CreateIdScrollBar (X, Y, Size, Id: Sw_Integer; Horz: Boolean): PScrollBar;
VAR R: TRect; P: PScrollBar;
BEGIN
If Horz Then R.Assign(X, Y, X+Size, Y+1) Else { Horizontal bar }
R.Assign(X, Y, X+1, Y+Size); { Vertical bar }
P := New(PScrollBar, Init(R)); { Create scrollbar }
If (P <> Nil) Then Begin
P^.Id := Id; { Set scrollbar id }
P^.Options := P^.Options OR ofPostProcess; { Set post processing }
End;
CreateIdScrollBar := P; { Return scrollbar }
END;
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{ OBJECT REGISTRATION PROCEDURES }
{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
{---------------------------------------------------------------------------}
{ RegisterViews -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE RegisterViews;
BEGIN
RegisterType(RView); { Register views }
RegisterType(RFrame); { Register frame }
RegisterType(RScrollBar); { Register scrollbar }
RegisterType(RScroller); { Register scroller }
RegisterType(RListViewer); { Register listview }
RegisterType(RGroup); { Register group }
RegisterType(RWindow); { Register window }
END;
END.
{
$Log$
Revision 1.40 2002-10-17 11:24:17 pierre
* Clean up the Load/Store routines so they are endian independent
Revision 1.39 2002/09/22 19:42:21 hajny
+ FPC/2 support added
Revision 1.38 2002/09/12 12:03:13 pierre
* handle unix mouse differently as it uses video buffer
Revision 1.37 2002/09/09 08:06:33 pierre
* remove other warnings
Revision 1.36 2002/09/09 08:04:06 pierre
* remove all warnings about far
Revision 1.35 2002/09/07 15:06:38 peter
* old logs removed and tabs fixed
Revision 1.34 2002/08/22 13:40:49 pierre
* several graphic mode improovements
Revision 1.33 2002/06/10 13:47:38 pierre
* correct the check for drawing a double line border
Revision 1.32 2002/06/10 12:39:43 pierre
* always call ScrooDraw if TscrollBar.value filed is changed
Revision 1.31 2002/06/06 06:42:21 pierre
+ use gfvgraph cursor functions for UseFixedFont
Revision 1.30 2002/05/31 13:36:42 pierre
* avoid SIGSEGV in owner^.close code by removing virtual attribute to ForEach method
Revision 1.29 2002/05/31 12:40:48 pierre
* several fixes + graph enhancements
Revision 1.28 2002/05/30 22:28:33 pierre
* tried to get a faster RedrawArea method
Revision 1.27 2002/05/30 14:53:54 pierre
* try to follow TV better
Revision 1.26 2002/05/29 19:36:52 pierre
* fix UseFixedFont related code
Revision 1.25 2002/05/28 19:15:16 pierre
* adapt to new GraphUpdateScreen function
Revision 1.24 2002/05/25 23:30:47 pierre
* partly fix the scrollbar behavior
Revision 1.23 2002/05/24 13:16:11 pierre
* add window number and resize handle
Revision 1.22 2002/05/23 10:27:12 pierre
* avoid problems with shadows when moving or resizing a window
Revision 1.21 2002/05/23 09:06:01 pierre
* force views to have raworigin multiples of cell width and height
Revision 1.20 2002/05/21 11:47:36 pierre
* avoid infinite recursions in graphic mode
Revision 1.19 2002/05/16 21:23:34 pierre
* fix some display problems
}