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