#define Top(%Rect) $LI(%Rect,1) #define Left(%Rect) $LI(%Rect,2) #define Bottom(%Rect) $LI(%Rect,3) #define Right(%Rect) $LI(%Rect,4) #define VertPos(%Rect) $LI(%Rect,5) Set %Screen=##class(UI.TNT.TScreen).Create() Set BGRect(1)=$LB(2,7,20,70) ; Background Set FGRect(1)=$LB(5,10,10,20) ; Foreground Set Rect=$LB(6,10,6,100,1) ; Te controlerenRectangle Write "Background " Do DispRect(BGRect) Write "Forground " Do DispRect(FGRect) Write "Rectangle " Do DispRect(Rect) Quit #Include UI.TNT.System Test(Control) New aBGRects,aFGRects Do WL^vhDBG("") Do WL^vhDBG("=== "_$$$GetDebugControlName(Control)_" ===") If $$GetPaintRects(Control,.aBGRects,.aFGRects) Do . Do HiddenRemoval(Control.GetRect(0)_$LB(1),.aBGRects,.aFGRects,.Rects) . Do DispRects(.Rects) Else Do . Do WL^vhDBG("Failed") Quit // Geef een control op en de background + foreground rectangles terug GetPaintRects(Control,aBGRects,aFGRects) Quit:(Control="") 0 Quit:('Control.Visible) 0 ;Background rects (eventuele frames en form onder control) New Nr,ParentForm,ParentNotVisible Set Nr=0, ParentForm="", AParentIsNotVisible=0 For Set Control=Control.Parent Quit:(Control="") Do Quit:(AParentIsNotVisible) . Set:(Control.HasControls) Nr=Nr+1, aBGRects(Nr)=Control.GetRect(0) . Set:('Control.Visible) AParentIsNotVisible=1 . Set:(Control.Parent="") ParentForm=Control Quit:(AParentIsNotVisible) 0 Quit:(ParentForm="") 0 ;Foreground rects, rects die (mogelijk) voor de huidige control (en dus parentform) vertoeven New Key,Found,tmpForm Set Key="", Found=0, aFGRects="", Nr=0 For Set tmpForm=%Screen.FormZOrderList.GetPrevious(.Key) Quit:(Key="") Do . If Found Do .. Set Nr=Nr+1, aFGRects(Nr)=tmpForm.GetRect(0) . Else Do .. Set:(tmpForm=ParentForm) Found=1 ;Indien de form niet werd terugvonden in bovenstaand zaakje, dan is deze niet zichtbaar, komt normaliter niet voor Quit:('Found) 0 Quit 1 ; Clipping reduceert de initieele rectangle tot de background ; EN splits/reduceert de rectangle tot wat niet verborgen wordt door bovenliggende (forground forms) rectangle ; InitRect : Initiele Rechthoek ; BGRects bevat alle frames en de form waarop de control staat. Via .Local doorgeven ; FGRects bevat alle forms die boven op de form, waarop de control staat, liggen. Via .Local doorgeven ; ResultRects geeft als resultaat de rectanges terug die kunnen getekend worden. Via .Local doorgeven ; Alle Rects zijn $LB(Top,Left,Bottom,Right) waarbij de InitRect en de ResultRects nog een vijfde element hebben VertPos HiddenRemoval(InitRect,BGRects,FGRects,ResultRects) New VolgNr,Rects ; Background Clipping Set VolgNr="" For Set VolgNr=$O(BGRects(VolgNr)) Quit:VolgNr="" Do . Do ClippingBackground(BGRects(VolgNr),.InitRect) Quit:InitRect="" ; De rectangle valt volledig buiten de background ; Hidden removal Set Rects=1 Set Rects(Rects)=InitRect Set VolgNr="" For Set VolgNr=$O(FGRects(VolgNr)) Quit:VolgNr="" Do Quit:$D(Rects)<10 ; Stoppen als er geen rectangles meer zijn, allen zijn verborgen . Do ClippingHorizontaal(FGRects(VolgNr),.Rects) . Do ClippingVertikaal(FGRects(VolgNr),.Rects) ; Compacteren Result Kill ResultRects Set ResultRects=0 Set VolgNr="" For Set VolgNr=$O(Rects(VolgNr)) Quit:VolgNr="" Set ResultRects($I(ResultRects))=Rects(VolgNr) Quit ClippingBackground(BGRect,Rect) ; Top Left Set:$$$Top(BGRect)>$$$Top(Rect) $$$Top(Rect)=$$$Top(BGRect) Set:$$$Left(BGRect)>$$$Left(Rect) $$$VertPos(Rect)=$$$VertPos(Rect)+$$$Left(BGRect)-$$$Left(Rect),$$$Left(Rect)=$$$Left(BGRect) ; Rechts onder Set:$$$Bottom(BGRect)<$$$Bottom(Rect) $$$Bottom(Rect)=$$$Bottom(BGRect) Set:$$$Right(BGRect)<$$$Right(Rect) $$$Right(Rect)=$$$Right(BGRect) ; Controle of de rectangle nog zinvol is Set:($$$Bottom(Rect)<$$$Top(Rect))||($$$Right(Rect)<$$$Left(Rect)) Rect="" Quit ClippingHorizontaal(FGRect,Rects) New I,Rect,NewRect For I=1:1:Rects Do . Set Rect=$G(Rects(I)) . Quit:Rect="" ; Er kunnen gaten en lege Rects ontstaan . ; Controle of het disjunct is . If ($$$Top(FGRect)>$$$Bottom(Rect)) || ($$$Bottom(FGRect)<$$$Top(Rect)) || ($$$Left(FGRect)>$$$Right(Rect)) || ($$$Right(FGRect)<$$$Left(Rect)) Quit . ; Controle of het volledig verborgen is . If $$IsHidden(FGRect,Rect) Kill Rects(I) Quit . ; Controle op horizontale snijlijnen . If $$$Top(FGRect)>$$$Top(Rect) Do ; De top ligt hoger dan de FG top, er wordt een NewRect aangemaakt en Rect wordt verkleind . . Set NewRect=Rect . . Set $$$Bottom(NewRect)=$$$Top(FGRect)-1 ; volledig vrij boven FGrect . . Set $$$Top(Rect)=$$$Top(FGRect) ; verder onderzoeken . . ;Set:'$$IsHidden(FGRect,NewRect) Rects($I(Rects))=NewRect . . Set Rects($I(Rects))=NewRect . . Set Rects(I)=Rect . If $$$Bottom(FGRect)<$$$Bottom(Rect) Do ; De bottom ligt lager dan de FG bottom, er wordt een NewRect aangemaakt en Rect wordt verkleind . . Set NewRect=Rect . . Set $$$Top(NewRect)=$$$Bottom(FGRect)+1 ; volledig vrij onder FGrect . . Set $$$Bottom(Rect)=$$$Bottom(FGRect) ; tussen top en bottom van FGRect . . ;Set:'$$IsHidden(FGRect,NewRect) Rects($I(Rects))=NewRect . . Set Rects($I(Rects))=NewRect . . Set Rects(I)=Rect . If $$IsHidden(FGRect,Rect) Kill Rects(I) Quit ClippingVertikaal(FGRect,Rects) For I=1:1:Rects Do . Set Rect=$G(Rects(I)) . Quit:Rect="" ; Er kunnen gaten en lege Rects ontstaan . ; Controle of het disjunct is . If ($$$Top(FGRect)>$$$Bottom(Rect)) || ($$$Bottom(FGRect)<$$$Top(Rect)) || ($$$Left(FGRect)>$$$Right(Rect)) || ($$$Right(FGRect)<$$$Left(Rect)) Quit . ; Controle of het volledig verborgen is . If $$IsHidden(FGRect,Rect) Kill Rects(I) Quit . ; Controle op horizontale snijlijnen . If $$$Left(FGRect)>$$$Left(Rect) Do ; De top ligt hoger dan de FG top, er wordt een NewRect aangemaakt en Rect wordt verkleind . . Set NewRect=Rect . . Set $$$Right(NewRect)=$$$Left(FGRect)-1 ; volledig vrij links van FGrect . . Set $$$Left(Rect)=$$$Left(FGRect) ; verder onderzoeken . . Set $$$VertPos(Rect)=$$$VertPos(Rect)+$$$Left(Rect)-$$$Left(NewRect) ; de vertikale positie verplaatsten (nodig voor TextOut) . . ;Set:'$$IsHidden(FGRect,NewRect) Rects($I(Rects))=NewRect . . Set Rects($I(Rects))=NewRect . . Set Rects(I)=Rect . If $$$Right(FGRect)<$$$Right(Rect) Do ; De bottom ligt lager dan de FG bottom, er wordt een NewRect aangemaakt en Rect wordt verkleind . . Set NewRect=Rect . . Set $$$Left(NewRect)=$$$Right(FGRect)+1 ; volledig vrij rechts van FGrect . . Set $$$Right(Rect)=$$$Right(FGRect) ; tussen links en rechts van FGRect . . ;Set:'$$IsHidden(FGRect,NewRect) Rects($I(Rects))=NewRect . . Set $$$VertPos(NewRect)=$$$VertPos(Rect)+$$$Left(NewRect)-$$$Left(Rect) . . Set Rects($I(Rects))=NewRect . . Set Rects(I)=Rect . If $$IsHidden(FGRect,Rect) Kill Rects(I) Quit IsHidden(FGRect,Rect) Quit ($$$Top(FGRect)'>$$$Top(Rect)) && ($$$Bottom(FGRect)'<$$$Bottom(Rect)) && ($$$Left(FGRect)'>$$$Left(Rect)) && ($$$Right(FGRect)'<$$$Right(Rect)) DispRects(Rects) For I=1:1:Rects Do . Do W^vhDBG("["_I_"] ") . Do DispRect($G(Rects(I))) Quit DispRect(Rect) IF Rect="" Do WL^vhDBG("Empty Rect") Quit Do WL^vhDBG("Top:"_$$$Top(Rect)_" Left:"_$$$Left(Rect)_" Bottom:"_$$$Bottom(Rect)_" Right:"_$$$Right(Rect)_$S($LD(Rect,5):" VertPos:"_$$$VertPos(Rect),1:"")) Quit