{********[ 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 ]******************} { } { Only Free Pascal Compiler supported } { } {**********************************************************} UNIT Views; {$CODEPAGE cp437} {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>} 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 } Os2Def, DosCalls, PmWin, {$ENDIF} Objects, FVCommon, Drivers, fvconsts; { 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 } {---------------------------------------------------------------------------} { 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 << 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 = 255; { 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 = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} PACKED {$endif FPC_REQUIRES_PROPER_ALIGNMENT} 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 } 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 } Origin : TPoint; { View origin } Size : TPoint; { View size } Cursor : TPoint; { Cursor position } 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 MapColor (color:byte):byte; FUNCTION GetColor (Color: Word): Word; FUNCTION Valid (Command: Word): Boolean; Virtual; FUNCTION GetState (AState: Word): Boolean; FUNCTION TextWidth (const Txt: String): Sw_Integer; FUNCTION CTextWidth (const 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 DrawCursor; Virtual; PROCEDURE HideCursor; PROCEDURE ShowCursor; PROCEDURE BlockCursor; PROCEDURE NormalCursor; PROCEDURE FocusFromTop; Virtual; PROCEDURE MoveTo (X, Y: Sw_Integer); PROCEDURE GrowTo (X, Y: Sw_Integer); PROCEDURE EndModal (Command: Word); Virtual; PROCEDURE SetCursor (X, Y: Sw_Integer); PROCEDURE PutInFrontOf (Target: PView); PROCEDURE SetCommands (Commands: TCommandSet); 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 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 WriteChar (X, Y: Sw_Integer; C: Char; Color: Byte; Count: Sw_Integer); PROCEDURE DragView (Event: TEvent; Mode: Byte; Var Limits: TRect; MinSize, MaxSize: TPoint); private procedure CursorChanged; procedure DrawHide(LastView: PView); procedure DrawShow(LastView: PView); procedure DrawUnderRect(var R: TRect; LastView: PView); procedure DrawUnderView(DoShadow: Boolean; LastView: PView); procedure do_WriteView(x1,x2,y:Sw_Integer; var Buf); procedure do_WriteViewRec1(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer); procedure do_WriteViewRec2(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer); function do_ExposedRec1(x1,x2:Sw_integer; p:PView):boolean; function do_ExposedRec2(x1,x2:Sw_integer; p:PView):boolean; 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 Lock; PROCEDURE UnLock; PROCEDURE ResetCursor; Virtual; PROCEDURE Awaken; Virtual; PROCEDURE ReDraw; 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 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); function ClipChilds: boolean; virtual; procedure BeforeInsert(P: PView); virtual; procedure AfterInsert(P: PView); virtual; procedure BeforeDelete(P: PView); virtual; procedure AfterDelete(P: PView); virtual; 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); procedure DrawSubViews(P, Bottom: PView); END; {---------------------------------------------------------------------------} { TFrame OBJECT - FRAME VIEW OBJECT } {---------------------------------------------------------------------------} TYPE TFrame = OBJECT (TView) CONSTRUCTOR Init (Var Bounds: TRect); FUNCTION GetPalette: PPalette; Virtual; procedure Draw; virtual; procedure HandleEvent(var Event: TEvent); virtual; procedure SetState(AState: Word; Enable: Boolean); virtual; private FrameMode: Word; procedure FrameLine(var FrameBuf; Y, N: Sw_Integer; Color: Byte); 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 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); 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 Draw; 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 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: idView; { Register id = 1 } VmtLink: TypeOf(TView); { Alt style VMT link } Load: @TView.Load; { Object load method } Store: @TView.Store { Object store method } ); {---------------------------------------------------------------------------} { TFrame STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RFrame: TStreamRec = ( ObjType: idFrame; { Register id = 2 } VmtLink: TypeOf(TFrame); { Alt style VMT link } Load: @TFrame.Load; { Frame load method } Store: @TFrame.Store { Frame store method } ); {---------------------------------------------------------------------------} { TScrollBar STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RScrollBar: TStreamRec = ( ObjType: idScrollBar; { Register id = 3 } VmtLink: TypeOf(TScrollBar); { Alt style VMT link } Load: @TScrollBar.Load; { Object load method } Store: @TScrollBar.Store { Object store method } ); {---------------------------------------------------------------------------} { TScroller STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RScroller: TStreamRec = ( ObjType: idScroller; { Register id = 4 } VmtLink: TypeOf(TScroller); { Alt style VMT link } Load: @TScroller.Load; { Object load method } Store: @TScroller.Store { Object store method } ); {---------------------------------------------------------------------------} { TListViewer STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RListViewer: TStreamRec = ( ObjType: idListViewer; { Register id = 5 } VmtLink: TypeOf(TListViewer); { Alt style VMT link } Load: @TListViewer.Load; { Object load method } Store: @TLIstViewer.Store { Object store method } ); {---------------------------------------------------------------------------} { TGroup STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RGroup: TStreamRec = ( ObjType: idGroup; { Register id = 6 } VmtLink: TypeOf(TGroup); { Alt style VMT link } Load: @TGroup.Load; { Object load method } Store: @TGroup.Store { Object store method } ); {---------------------------------------------------------------------------} { TWindow STREAM REGISTRATION } {---------------------------------------------------------------------------} CONST RWindow: TStreamRec = ( ObjType: idWindow; { Register id = 7 } VmtLink: TypeOf(TWindow); { Alt style VMT link } Load: @TWindow.Load; { Object load method } Store: @TWindow.Store { Object store method } ); {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>} IMPLEMENTATION {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>} USES Video; {***************************************************************************} { 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 } { Flags for TFrame } fmCloseClicked = $01; fmZoomClicked = $02; type TstatVar2 = record target : PView; offset,y : integer; end; var staticVar1 : PDrawBuffer; staticVar2 : TstatVar2; {***************************************************************************} { 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(force:boolean); begin if (GetLockScreenCount=0) then begin { If MouseUsesVideoBuf then begin LockScreenUpdate; HideMouse; ShowMouse; UnlockScreenUpdate; end else HideMouse;} UpdateScreen(force); { If not MouseUsesVideoBuf then ShowMouse;} end; end; {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} { VIEW PORT CONTROL ROUTINES } {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} TYPE ViewPortType = RECORD X1, Y1, X2, Y2: Integer; { Corners of viewport } Clip : Boolean; { Clip status } END; var ViewPort : ViewPortType; {---------------------------------------------------------------------------} { GetViewSettings -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Dec2000 LdB } {---------------------------------------------------------------------------} PROCEDURE GetViewSettings (Var CurrentViewPort: ViewPortType); BEGIN CurrentViewPort := ViewPort; { Textmode viewport } END; {---------------------------------------------------------------------------} { SetViewPort -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Dec2000 LdB } {---------------------------------------------------------------------------} PROCEDURE SetViewPort (X1, Y1, X2, Y2: Integer; Clip: Boolean); BEGIN If (X1 < 0) Then X1 := 0; { X1 negative fix } If (X1 >ScreenWidth) Then X1 := ScreenWidth; { X1 off screen fix } If (Y1 < 0) Then Y1 := 0; { Y1 negative fix } If (Y1 > ScreenHeight) Then Y1 := ScreenHeight; { Y1 off screen fix } If (X2 < 0) Then X2 := 0; { X2 negative fix } If (X2 > ScreenWidth) Then X2 := ScreenWidth; { X2 off screen fix } If (Y2 < 0) Then Y2 := 0; { Y2 negative fix } If (Y2 > ScreenHeight) Then Y2 := ScreenHeight; { Y2 off screen fix } ViewPort.X1 := X1; { Set X1 port value } ViewPort.Y1 := Y1; { Set Y1 port value } ViewPort.X2 := X2; { Set X2 port value } ViewPort.Y2 := Y2; { Set Y2 port value } ViewPort.Clip := Clip; { Set port clip value } { $ifdef DEBUG If WriteDebugInfo then Writeln(stderr,'New ViewPort(',X1,',',Y1,',',X2,',',Y2,')'); $endif DEBUG} 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 } 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 } 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--------------------------------------------------------------------} { MapColor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB } {---------------------------------------------------------------------------} function TView.MapColor(color:byte):byte; var cur : PView; p : PPalette; begin if color=0 then MapColor:=errorAttr else begin cur:=@Self; repeat p:=cur^.GetPalette; if (p<>Nil) then if ord(p^[0])<>0 then begin if color>ord(p^[0]) then begin MapColor:=errorAttr; Exit; end; color:=ord(p^[color]); if color=0 then begin MapColor:=errorAttr; Exit; end; end; cur:=cur^.Owner; until (cur=Nil); MapColor:=color; end; 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 (const Txt: String): Sw_Integer; BEGIN TextWidth := Length(Txt); { Calc text length } END; FUNCTION TView.CTextWidth (const 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 } CTextWidth := Length(S); { Calc text length } END; {--TView--------------------------------------------------------------------} { MouseInView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB } {---------------------------------------------------------------------------} FUNCTION TView.MouseInView (Point: TPoint): Boolean; BEGIN MakeLocal(Point,Point); MouseInView := (Point.X >= 0) and (Point.Y >= 0) and (Point.X < Size.X) and (Point.Y < Size.Y); 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 (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 } 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; VAR B : TDrawBuffer; BEGIN MoveChar(B, ' ', GetColor(1), Size.X); WriteLine(0, 0, Size.X, Size.Y, B); 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^.origin.y) and (cur.y
=p^.size.x) or
(cur.y<0) or (cur.y>=p^.size.y) then
break;
inc(cur.X,p^.origin.X);
inc(cur.Y,p^.origin.Y);
p2:=p;
G:=p^.owner;
if G=Nil then { top view }
begin
Video.SetCursorPos(cur.x,cur.y);
if (state and sfCursorIns)<>0 then
Video.SetCursorType(crBlock)
else
Video.SetCursorType(crUnderline);
exit;
end;
if (G^.state and sfVisible)=0 then
break;
p:=G^.Last;
if Check0 then
break;
end; { while }
end; { if }
Video.SetCursorType(crHidden);
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--------------------------------------------------------------------}
{ 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--------------------------------------------------------------------}
{ DrawCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.DrawCursor;
BEGIN { Abstract method }
if State and sfFocused <> 0 then
ResetCursor;
END;
procedure TView.DrawHide(LastView: PView);
begin
TView.DrawCursor;
DrawUnderView(State and sfShadow <> 0, LastView);
end;
procedure TView.DrawShow(LastView: PView);
begin
DrawView;
if State and sfShadow <> 0 then
DrawUnderView(True, LastView);
end;
procedure TView.DrawUnderRect(var R: TRect; LastView: PView);
begin
Owner^.Clip.Intersect(R);
Owner^.DrawSubViews(NextView, LastView);
Owner^.GetExtent(Owner^.Clip);
end;
procedure TView.DrawUnderView(DoShadow: Boolean; LastView: PView);
var
R: TRect;
begin
GetBounds(R);
if DoShadow then
begin
inc(R.B.X,ShadowSize.X);
inc(R.B.Y,ShadowSize.Y);
end;
DrawUnderRect(R, LastView);
end;
procedure TView.DrawView;
begin
if Exposed then
begin
LockScreenUpdate; { don't update the screen yet }
Draw;
UnLockScreenUpdate;
DrawScreenBuf(false);
TView.DrawCursor;
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--------------------------------------------------------------------}
{ 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--------------------------------------------------------------------}
{ 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
if (Cursor.X<>X) or (Cursor.Y<>Y) then
begin
Cursor.X := X;
Cursor.Y := Y;
CursorChanged;
end;
TView.DrawCursor;
END;
procedure TView.CursorChanged;
begin
Message(Owner,evBroadcast,cmCursorChanged,@Self);
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
DrawHide(LastView);
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
DrawShow(LastView);
If (Options AND ofSelectable <> 0) Then { View is selectable }
begin
Owner^.ResetCurrent; { Reset current }
Owner^.ResetCursor;
end;
Owner^.Unlock;
End;
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--------------------------------------------------------------------}
{ 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
Command: Word;
OState : Word;
begin
OState:=State;
if Enable then
State := State or AState
else
State := State and not AState;
if Owner <> nil then
case AState of
sfVisible:
begin
if Owner^.State and sfExposed <> 0 then
SetState(sfExposed, Enable);
if Enable then
DrawShow(nil)
else
DrawHide(nil);
if Options and ofSelectable <> 0 then
Owner^.ResetCurrent;
end;
sfCursorVis,
sfCursorIns:
TView.DrawCursor;
sfShadow:
DrawUnderView(True, nil);
sfFocused:
begin
ResetCursor;
if Enable then
Command := cmReceivedFocus
else
Command := cmReleasedFocus;
Message(Owner, evBroadcast, Command, @Self);
end;
end;
if ((OState xor State) and (sfCursorVis+sfCursorIns+sfFocused))<>0 then
CursorChanged;
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 }
{---------------------------------------------------------------------------}
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 }
State := SaveState; { Reset state masks }
END;
{--TView--------------------------------------------------------------------}
{ Locate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TView.Locate (Var Bounds: TRect);
VAR
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
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
begin
if State and sfShadow <> 0 then
begin
R.Union(Bounds);
Inc(R.B.X, ShadowSize.X);
Inc(R.B.Y, ShadowSize.Y);
end;
DrawUnderRect(R, nil);
end;
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 }
END;
{--TView--------------------------------------------------------------------}
{ SetBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
{---------------------------------------------------------------------------}
procedure TView.SetBounds(var Bounds: TRect);
begin
Origin := Bounds.A; { Get first corner }
Size := Bounds.B; { Get second corner }
Dec(Size.X,Origin.X);
Dec(Size.Y,Origin.Y);
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 }
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) and(Owner^.ClipChilds) Then
Max := Owner^.Size
else { Max owner size }
Begin
Max.X := high(sw_integer); { Max possible x size }
Max.Y := high(sw_integer); { Max possible y size }
End;
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 }
GetExtent(Clip); { Get clip extents }
EventMask := $FFFF; { See all events }
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,
{ On most systems, locals are accessed relative to base pointer,
but for MIPS cpu, they are accessed relative to stack pointer.
This needs adaptation for so low level routines,
like MethodPointerLocal and related objects unit functions. }
{$ifndef FPC_LOCALS_ARE_STACK_REG_RELATIVE}
get_caller_frame(get_frame,get_pc_addr)
{$else}
get_frame
{$endif}
,@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;
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;
procedure TGroup.DrawSubViews(P, Bottom: PView);
begin
if P <> nil then
while P <> Bottom do
begin
P^.DrawView;
P := P^.NextView;
end;
end;
{--TGroup-------------------------------------------------------------------}
{ ReDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 2Jun06 DM }
{---------------------------------------------------------------------------}
procedure TGroup.Redraw;
begin
{Lock to prevent screen update.}
lockscreenupdate;
DrawSubViews(First, nil);
unlockscreenupdate;
{Draw all views at once, forced update.}
drawscreenbuf(true);
end;
PROCEDURE TGroup.ResetCursor;
BEGIN
if (Current<>nil) then
Current^.ResetCursor;
END;
{--TGroup-------------------------------------------------------------------}
{ Awaken -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Awaken;
PROCEDURE DoAwaken (P: PView);
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
DrawSubViews(First, nil)
else
WriteBuf(0,0,Size.X,Size.Y,Buffer);
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;
function TGroup.ClipChilds: boolean;
begin
ClipChilds:=true;
end;
procedure TGroup.BeforeInsert(P: PView);
begin
{ abstract }
end;
procedure TGroup.AfterInsert(P: PView);
begin
{ abstract }
end;
procedure TGroup.BeforeDelete(P: PView);
begin
{ abstract }
end;
procedure TGroup.AfterDelete(P: PView);
begin
{ abstract }
end;
{--TGroup-------------------------------------------------------------------}
{ Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Insert (P: PView);
BEGIN
BeforeInsert(P);
InsertBefore(P, First);
AfterInsert(P);
END;
{--TGroup-------------------------------------------------------------------}
{ Delete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
{---------------------------------------------------------------------------}
PROCEDURE TGroup.Delete (P: PView);
VAR SaveState: Word;
BEGIN
BeforeDelete(P);
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 }
if SaveState and sfVisible <> 0 then
P^.Show;
AfterDelete(P);
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,
{ On most systems, locals are accessed relative to base pointer,
but for MIPS cpu, they are accessed relative to stack pointer.
This needs adaptation for so low level routines,
like MethodPointerLocal and related objects unit functions. }
{$ifndef FPC_LOCALS_ARE_STACK_REG_RELATIVE}
get_caller_frame(get_frame,get_pc_addr)
{$else}
get_frame
{$endif}
,@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-------------------------------------------------------------------}
{ 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;
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 { Centre on x axis }
P^.Origin.X := (Size.X - P^.Size.X) div 2;
If (P^.Options AND ofCenterY <> 0) Then { Centre on y axis }
P^.Origin.Y := (Size.Y - P^.Size.Y) div 2;
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);
BEGIN
If (P <> Nil) Then P^.SetState(AState, Enable); { Set subview state }
END;
PROCEDURE DoExpose (P: PView);
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 }
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);
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;
BEGIN
ContainsMouse := (P^.State AND sfVisible <> 0) { Is view visible }
AND P^.MouseInView(Event.Where); { Is point in view }
END;
PROCEDURE DoHandleEvent (P: PView);
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);
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 }
{ Force redraw }
ReDraw; { 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: Sw_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)) 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;
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;
procedure TFrame.FrameLine(var FrameBuf; Y, N: Sw_Integer; Color: Byte);
const
InitFrame: array[0..17] of Byte =
($06, $0A, $0C, $05, $00, $05, $03, $0A, $09,
$16, $1A, $1C, $15, $00, $15, $13, $1A, $19);
FrameChars_437: array[0..31] of Char =
' À ³Úà ÙÄÁ¿´ÂÅ È ºÉÇ ¼ÍÏ»¶ÑÎ';
FrameChars_850: array[0..31] of Char =
' À ³Úà ÙÄÁ¿´ÂÅ È ºÉº ¼ÍÍ»ºÍÎ';
var
FrameMask : array[0..MaxViewWidth-1] of Byte;
ColorMask : word;
i,j,k : {Sw_ lo and hi are used !! }integer;
CurrView : PView;
p : Pchar;
begin
FrameMask[0]:=InitFrame[n];
FillChar(FrameMask[1],Size.X-2,InitFrame[n+1]);
FrameMask[Size.X-1]:=InitFrame[n+2];
CurrView:=Owner^.Last^.Next;
while (CurrView<>PView(@Self)) do
begin
if ((CurrView^.Options and ofFramed)<>0) and
((CurrView^.State and sfVisible)<>0) then
begin
i:=Y-CurrView^.Origin.Y;
if (i<0) then
begin
inc(i);
if i=0 then
i:=$0a06
else
i:=0;
end
else
begin
if i 0) and (staticVar2.y>=p^.origin.y+shadowSize.y) then
if (x1>dx) then
continue
else
begin
inc(shadowCounter);
if (x2<=dx) then
continue
else
begin
do_writeViewRec1(x1,dx,p,shadowCounter);
x1:=dx;
dec(shadowCounter);
continue;
end;
end
else
continue;
end;
if ((p^.state and sfShadow)<>0) and (staticVar2.y =dx then
continue;
inc(shadowCounter);
if x2<=dx then
continue
else
begin
do_writeViewRec1(x1,dx,p,shadowCounter);
x1:=dx;
dec(shadowCounter);
end;
end;
end;
until false;
end;
procedure TView.do_writeViewRec2(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer);
var
savedStatics : TstatVar2;
dx : Sw_integer;
G : PGroup;
begin
G:=P^.Owner;
if ((p^.State and sfVisible) <> 0) and (G<>Nil) then
begin
savedStatics:=staticVar2;
inc(staticVar2.y,p^.Origin.Y);
dx:=p^.Origin.X;
inc(x1,dx);
inc(x2,dx);
inc(staticVar2.offset,dx);
staticVar2.target:=p;
if (staticVar2.y >= G^.clip.a.y) and (staticVar2.y < G^.clip.b.y) then
begin
if (x1