/******************************************************************************************************/ /* Obj2d Library written by J.DUMAY */ /* some extensions by Marc Barilley */ /******************************************************************************************************/ /* Container */ /* */ /* O2D_CrContainer constructeur */ /* O2D_DsContainer destructeur */ /* O2D_CleanContainer (Container) vide un container de tous ses objets sans le détruire */ /* O2D_SetContainerMoveReflex la definition des reflexes du container */ /* O2D_SetContainerResizingReflex */ /* O2D_SetContainerFocusReflex */ /* O2D_SetContainerKillFocusReflex */ /* O2D_SetContainerDestroyReflex */ /* O2D_SetContainerClickReflex */ /* O2D_SetContainerUnclickReflex */ /* O2D_SetContainerCursorMoveReflex */ /* O2D_SetContainerDblClickReflex */ /* O2D_SetContainerKeyDownReflex */ /* O2D_SetContainerKeyUpReflex */ /* */ /* O2D_GetContainerWindow */ /* */ /* O2D_RedrawContainer */ /* O2D_RedrawArea */ /******************************************************************************************************/ /* Objet 2d */ /* */ /* O2D_NewObject constructeur */ /* O2D_DelObject destructeur */ /* O2D_GetObject */ /* O2D_GetFather */ /* O2D_GetFirstChild */ /* O2D_GetBrother */ /* O2D_GetObjCoordinates */ /* O2D_ChangeObjDisplayFlag */ /* O2D_ChangeObjCoordinates */ /* les methodes */ /* */ /* O2D_CBDsObject destruction de l'objet */ /* O2D_CBPaint repeindre l'objet */ /* O2D_CBPaintPart repeindre une partie de l'objet */ /* O2D_CBIsMouseOnDisplayObject la souris est-elle sur l'objet */ /* O2D_CBUserClickAllowed le reflexe container click est autorise */ /* O2D_CBUserUnClickAllowed le reflexe container unclick est autorise */ /* O2D_CBCursorMoveOut la souris sort de l'objet */ /* O2D_CBCursorMoveIn la souris rentre dans l'objet */ /* O2D_CBCursorMoveInWithButtonPush la souris entre dans l'objet avec un bouton presse */ /* O2D_CBCursorMoveOutWithButtonPush la souris sort de l'objet avec un bouton presse */ /* O2D_CBObjectClickIn clic sur l'objet */ /* O2D_CBObjectClickOut clic en dehors de l'objet */ /* O2D_CBObjectUnClickIn unclic dans l'objet */ /* O2D_CBObjectUnClickOut unclic en dehors de l'objet */ /* O2D_CBObjectDblClickIn double clic dans l'objet */ /* */ /* O2D_RectangleIncludingObject detremine le rectangle englobant d'un objet */ /* */ /******************************************************************************************************/ /* librairies utilisees: _jint2d.pkg */ /* */ /******************************************************************************************************/ var O2D_ENABLE=1;; /* objet enable */ var O2D_HIDE=4;; /* objet cache ainsi que ts ses fils*/ /* Arbre d'affichage des Objets: DNVal:L'objet 2d DNCoordinates:coordonees de l'objet par rapport a son pere DNFlags:Flag d'affichage (O2D_ENABLE,O2D_DISABLE,O2D_HIDE) DNFather:node pere DNFirstChild:node premier fils DNNextBrother:node frere suivant DNPreviousBrother:node frere precedent */ struct DisplayNode=[ DNVal:Obj2D, DNCoordinates:[I I], DNFather:DisplayNode, DNFirstChild:DisplayNode, DNNextBrother:DisplayNode, DNPreviousBrother:DisplayNode ] MkDisplayNode;; /*L'Objet 2d: O2Dname : nom de l'objet O2Dx : position x globale dans la container O2Dy : position y globale dans la container O2Dw : largeur de l'objet O2Dh : hauteur de l'objet O2DParentContainer : container de l'objet O2DDisplayNode : node d'affichage de l'objet les methodes O2DDsObject : destruction de l'objet O2DPaintObject : affichage de l'objet O2DPaintPartOfObject : affichage d'une partie de l'objet O2DIsMouseOnDisplayObject : renvoie 1 si la sourie est sur l'objet 0 sinon O2DUserClickAllowed : le callback du click container est autorise O2DUserUnClickAllowed : le callback du unclick container est autorise O2DCursorMoveIn : le curseur entre de l'objet O2DCursorMoveOut : le curseur sort dans l'objet O2DCursorMoveInWithButtonPush : le curseur entre de l'objet avec un bouton presse O2DCursorMoveOutWithButtonPush : le curseur sort de l'objet avec un bouton presse O2DObjectClickIn : clic sur l'objet O2DObjectClickOut : clic en dehors de l'objet O2DObjectUnClickIn : unclic sur l'objet O2DObjectUnClickOut : unclic en dehors de l'objet O2DObjectDblClickIn : dblclic sur l'objet O2DObjectChangeRecord : change un record de l'objet (entier) */ struct Obj2D=[ O2Dname:S, O2Dx:I, O2Dy:I, O2Dw:I, O2Dh:I, O2DFlags:I, O2DParentContainer:ContainerType, O2DDisplayNode:DisplayNode, O2DDsObject:fun [] I, /*les methodes */ O2DPaintObject:fun [] [ObjBitmap I I I I I], O2DPaintPartOfObject:fun [Rectangle2D] [ObjBitmap I I I I I], O2DIsMouseOnDisplayObject:fun [I I] I, O2DUserClickAllowed:fun [] I, O2DUserUnClickAllowed:fun [] I, O2DCursorMove:fun [I I I] I, O2DCursorMoveIn:fun [I I I] I, O2DCursorMoveOut:fun [I I I] I, O2DCursorMoveInWithButtonPush:fun [I I I] I, O2DCursorMoveOutWithButtonPush:fun [I I I] I, O2DObjectClickIn:fun [I I I] I, O2DObjectClickOut:fun [I I I] I, O2DObjectUnClickIn:fun [I I I] I, O2DObjectUnClickOut:fun [I I I] I, O2DObjectDblClickIn:fun [I I I] I, O2DObjectKeyUp:fun [I] I, O2DObjectKeyDown:fun [I I] I ] MkObj2D;; /* Le Container: CoObjWin:fenetre CoWorkingBitmap:bitmap de travail utilise ds le repaint CoChannel:canal du container CoParent:fentre parente CoXCoord:X coordonnee du container CoYCoord:Y coordonnee du container CoXSize:largeur du container CoYSize:hauteur du container CoWindowFlag:flag de creation CoName:nom du container CoBackgroundColor:couleur de fond CoArbre:arbre d'affichage des objets CoHandledObject:objet courant CoObjectUnderMouse:objet courant sous la souris CoUserMoveIsAllowed:le callback move du container est autorise si 1 0 Sinon CoContainerMoveReflex:callback utilisateur lors du move du container CoContainerResizingReflex:callback utilisateur lors du resize du container CoContainerFocusReflex:callback utilisateur lors du focus du container CoContainerKillFocusReflex:callback utilisateur lors de la perte du focus du container CoContainerDestroyReflex:callback utilisateur lors de la destruction du container CoContainerPaintReflex:callback utilisateur lors du repaint du container CoClickReflex:callback utilisateur lors du click sur le container CoUnclickReflex:callback utilisateur lors du unclick sur le container CoCursorMoveReflex:callback utilisateur lors du deplacement de la souris ds le container CoDblClickReflex:callback utilisateur lors du dblclick ds le container */ struct ContainerType=[ CoObjWin:ObjWin, CoWorkingBitmap:ObjBitmap, CoChannel:Chn, CoParent:ContainerType, CoXCoord:I, CoYCoord:I, CoXSize:I, CoYSize:I, CoContainerFlag:I, CoName:S, CoBackgroundColor:I, CoArbre:DisplayNode, CoHandledObject:Obj2D, CoFocusedObject:Obj2D, CoUserMoveIsAllowed:I, CoOutPushedAlreadySent : I, CoInPushedAlreadySent : I, CoLocked : I, CoContainerMoveReflex:fun [ContainerType I I] ContainerType, CoContainerResizingReflex:fun [ContainerType I I] ContainerType, CoContainerFocusReflex:fun [ContainerType] ContainerType, CoContainerKillFocusReflex:fun [ContainerType] ContainerType, CoContainerDestroyReflex:fun [ContainerType] ContainerType, CoContainerPaintReflex:fun [ContainerType] ContainerType, CoClickReflex:fun [ContainerType I I I] ContainerType, CoUnclickReflex:fun [ContainerType I I I] ContainerType, CoCursorMoveReflex:fun [ContainerType I I I] ContainerType, CoDblClickReflex:fun [ContainerType I I I] ContainerType, CoDragAndDropReflex:fun [ContainerType I I [P r1]] ContainerType, CoKeyDownReflex:fun [ContainerType I I] ContainerType, CoKeyUpReflex:fun [ContainerType I] ContainerType ] MkContainerType;; proto O2D_RectangleIncludingObject=fun [Obj2D] Rectangle2D;; proto O2D_RedrawArea =fun [ContainerType Rectangle2D I] ContainerType;; proto O2D_RedrawContainer =fun [ContainerType I] ContainerType;; proto O2D_GetContainerWindow = fun [ContainerType] ObjWin;; /****************************************************************************************/ /* Fonctions de gestions de l'arbre d'affichage du container */ /****************************************************************************************/ fun ComputeCoordinates(Node)= if Node!=nil then let Node.DNCoordinates -> [X Y] in if Node.DNFather.DNVal==nil then { set Node.DNVal.O2Dx=X; set Node.DNVal.O2Dy=Y; } else { set Node.DNVal.O2Dx=Node.DNFather.DNVal.O2Dx+X; set Node.DNVal.O2Dy=Node.DNFather.DNVal.O2Dy+Y; } else nil;; fun ComputeDescentCoordinates(Node)= if Node==nil then nil else { ComputeCoordinates Node; ComputeDescentCoordinates Node.DNFirstChild; ComputeDescentCoordinates Node.DNNextBrother; }; 0;; fun O2D_search_object_under_mouse(Node,MouseCol,MouseLgn)= if Node==nil then nil else let O2D_search_object_under_mouse Node.DNNextBrother MouseCol MouseLgn -> BrotherResult in if BrotherResult==nil then let O2D_search_object_under_mouse Node.DNFirstChild MouseCol MouseLgn -> ChildResult in if ChildResult==nil then if (Node.DNVal!= nil) && IsPointInRectangle (MkInt2DPoint [MouseCol MouseLgn]) (O2D_RectangleIncludingObject Node.DNVal) then if !(Node.DNVal.O2DFlags & O2D_HIDE) && (exec Node.DNVal.O2DIsMouseOnDisplayObject with [MouseCol MouseLgn]) then Node else nil else nil else ChildResult else BrotherResult ;; fun O2D_search_in_tree(Node,f,Val)= if Node==nil then nil else if (exec f with [Node Val]) then Node else { let O2D_search_in_tree Node.DNFirstChild f Val -> ChildResult in if ChildResult!=nil then ChildResult else O2D_search_in_tree Node.DNNextBrother f Val };; /*****************************************************************************************/ /* */ /* Les reflexes Internes du Container */ /* */ /*****************************************************************************************/ proto O2D_DelObject=fun [Obj2D] I;; proto O2D_DsDisplayNode=fun [DisplayNode] DisplayNode;; /* Container destroy event function Window : Window that should be destroyed Container : Container that should be destroyed */ fun O2D_ContainerDestroyEvent(Window,Container)= O2D_DsDisplayNode Container.CoArbre.DNFirstChild; _DSbitmap Container.CoWorkingBitmap; set Container.CoName=nil; set Container.CoArbre=nil; set Container.CoContainerMoveReflex=nil; set Container.CoContainerResizingReflex=nil; set Container.CoContainerFocusReflex=nil; set Container.CoContainerKillFocusReflex=nil; set Container.CoContainerPaintReflex=nil; set Container.CoDblClickReflex=nil; set Container.CoClickReflex=nil; set Container.CoUnclickReflex=nil; set Container.CoCursorMoveReflex=nil; /* Call user destroy reflex function */ exec Container.CoContainerDestroyReflex with [Container]; set Container = nil ;; /* Container paint event function Window : Window that should be repainted Container : Bitmap window that should be repainted */ fun O2D_ContainerPaintEvent(Window,Container)= _BLTbitmap Window Container.CoWorkingBitmap 0 0; exec Container.CoContainerPaintReflex with [Container] ;; /* Container focus event function Window : Window the focus should be handles Container : Bitmap window the focus should be handles */ fun O2D_ContainerFocusEvent(Window,Container)= O2D_ContainerPaintEvent Window Container; exec Container.CoContainerFocusReflex with [Container] ;; /* Container kill focus event function Window : Window the kill focus should be handles Container : Container the kill focus should be handles */ fun O2D_ContainerKillFocusEvent(Window,Container)= exec Container.CoFocusedObject.O2DObjectClickOut with [nil nil nil]; set Container.CoHandledObject=nil; set Container.CoFocusedObject=nil; exec Container.CoContainerKillFocusReflex with [Container] ;; /* Container move event function Window : Window the move should be handles Container : Container the move should be handles XPos : New X position of the window YPos : New Y position of the window */ fun O2D_ContainerMoveEvent(Window,Container,XPos,YPos)= /* Reset the window coordinates */ set Container.CoXCoord=XPos; set Container.CoYCoord=YPos; /* Call the user window move reflex function */ exec Container.CoContainerMoveReflex with [Container XPos YPos] ;; /* Container resizing event function Window : Window the resizing should be handles Container : Container the resizing should be handles Width : New width of the window Height : New height of the window */ fun O2D_ContainerResizingEvent(Window,Container,Width,Height)= if Width && Height then { /* Reallocate the working bitmap */ let [Container.CoWorkingBitmap (_CRbitmap Container.CoChannel Width Height)] -> [OldWorkingBitmap NewWorkingBitmap] in ( _CPbitmap16 NewWorkingBitmap 0 0 OldWorkingBitmap 0 0 Container.CoXSize Container.CoYSize nil; set Container.CoWorkingBitmap=NewWorkingBitmap; set Container.CoXSize=Width; set Container.CoYSize=Height; _DSbitmap OldWorkingBitmap ); /* Repaint the window */ O2D_RedrawContainer Container 1; /* Call the user window resizing reflex function */ exec Container.CoContainerResizingReflex with [Container Width Height] } else nil ;; /* Container cursor dble click event function Window : Window the move event occured at Container : container the move cursor event occured at MouseCol : Mouse column MouseLgn : Mouse Lgn MouseButtons : Mouse buttons state */ fun O2D_ContainerDblClickEvent(Window,Container,MouseCol,MouseLgn,MouseButtons)= _SETfocus Container.CoObjWin; if Container.CoLocked then nil else let O2D_search_object_under_mouse Container.CoArbre MouseCol MouseLgn -> NodeUnderMouse in { /* Look if object under the mouse is the focused object */ if NodeUnderMouse.DNVal != Container.CoFocusedObject then { /* mouse is out of the focused object */ exec Container.CoFocusedObject.O2DObjectClickOut with [MouseCol MouseLgn MouseButtons]; if NodeUnderMouse.DNVal != nil then set Container.CoInPushedAlreadySent = 1 else nil; } else nil; /* mouse is in the focused object */ /* sets the new focused object */ set Container.CoFocusedObject = NodeUnderMouse.DNVal; if Container.CoFocusedObject.O2DFlags & O2D_ENABLE then exec Container.CoHandledObject.O2DObjectDblClickIn with [MouseCol MouseLgn MouseButtons] else nil; /* Call user dblclick reflex function if no element has been clicked */ if Container.CoFocusedObject!=nil then exec Container.CoDblClickReflex with [Container MouseCol MouseLgn MouseButtons] else nil; }; Window ;; fun O2D_ContainerClickEvent(Window,Container,MouseCol,MouseLgn,MouseButtons)= _SETfocus Container.CoObjWin; if Container.CoLocked then nil else let O2D_search_object_under_mouse Container.CoArbre MouseCol MouseLgn -> NodeUnderMouse in let NodeUnderMouse.DNVal -> ObjUnderMouse in { /* Look if object under the mouse is the focused object */ if ObjUnderMouse != Container.CoFocusedObject then /* mouse is out of the focused object */ { exec Container.CoFocusedObject.O2DObjectClickOut with [MouseCol MouseLgn MouseButtons]; if ObjUnderMouse != nil then set Container.CoInPushedAlreadySent = 1 else nil; } else nil; /* mouse is in the focused object */ if ObjUnderMouse != nil then { /* sets the new focused object */ set Container.CoFocusedObject = ObjUnderMouse; if Container.CoFocusedObject.O2DFlags & O2D_ENABLE then exec Container.CoFocusedObject.O2DObjectClickIn with [MouseCol MouseLgn MouseButtons] else nil } else { /* Call user click reflex function if no element has been clicked */ exec Container.CoClickReflex with [Container MouseCol MouseLgn MouseButtons]; 0 } }; Window ;; /* Container unclick event function Window : Window the unclick event occured at Container : Container the unclick event occured at MouseCol : Mouse column MouseLgn : Mouse Lgn MouseButtons : Mouse buttons state */ fun O2D_ContainerUnClickEvent(Window,Container,MouseCol,MouseLgn,MouseButtons)= if Container.CoLocked then nil else let 1 -> UserUnClickAllowed in let O2D_search_object_under_mouse Container.CoArbre MouseCol MouseLgn -> NodeUnderMouse in { let 0 -> ShouldHandleNewMousePosition in { /* Set user move function as allowed by default */ set Container.CoUserMoveIsAllowed = 1; if (Container.CoFocusedObject != nil)&& (Container.CoFocusedObject != NodeUnderMouse.DNVal) then { if Container.CoFocusedObject.O2DFlags & O2D_ENABLE then exec Container.CoFocusedObject.O2DObjectUnClickOut with [MouseCol MouseLgn MouseButtons] else nil; set Container.CoOutPushedAlreadySent = 0; set Container.CoInPushedAlreadySent = 0; set Container.CoFocusedObject=nil; set Container.CoHandledObject=nil; set ShouldHandleNewMousePosition=1; } else { if Container.CoFocusedObject.O2DFlags & O2D_ENABLE then exec Container.CoFocusedObject.O2DObjectUnClickIn with [MouseCol MouseLgn MouseButtons] else nil; 0 }; /* Look the new mouse position should be handled */ if ShouldHandleNewMousePosition then { /* Set user move function as forbidden */ set UserUnClickAllowed = exec NodeUnderMouse.DNVal.O2DUserUnClickAllowed with []; set Container.CoUserMoveIsAllowed = 0; set Container.CoHandledObject = NodeUnderMouse.DNVal; if Container.CoHandledObject.O2DFlags & O2D_ENABLE then exec Container.CoHandledObject.O2DCursorMoveIn with [ MouseCol MouseLgn MouseButtons ] else nil; } else nil; /* do not handle new mouse position */ }; if UserUnClickAllowed then exec Container.CoUnclickReflex with [Container MouseCol MouseLgn MouseButtons] else nil; }; Window ;; /* Container cursor move event function Window : Window the move event occured at Container : container the move cursor event occured at MouseCol : Mouse column MouseLgn : Mouse Lgn MouseButtons : Mouse buttons state */ fun O2D_ContainerCursorMoveEvent (Window, Container, MouseCol, MouseLgn, MouseButtons)= if Container.CoLocked then nil else let O2D_search_object_under_mouse Container.CoArbre MouseCol MouseLgn -> NewHandled in /* Cursor going out of the handled object ? */ let (Container.CoHandledObject != nil) && (NewHandled.DNVal != Container.CoHandledObject) -> OutOfHandledObject in /* Cursor going into a new object ? */ let (NewHandled.DNVal != nil) && (NewHandled.DNVal != Container.CoHandledObject) -> IntoMouseObject in { if !IntoMouseObject && !OutOfHandledObject && (Container.CoHandledObject.O2DFlags & O2D_ENABLE) then exec Container.CoHandledObject.O2DCursorMove with [MouseCol MouseLgn MouseButtons] else nil; if OutOfHandledObject then { if MouseButtons==0 then if Container.CoHandledObject.O2DFlags & O2D_ENABLE then exec Container.CoHandledObject.O2DCursorMoveOut with [MouseCol MouseLgn MouseButtons] else nil else { set Container.CoOutPushedAlreadySent = 1; set Container.CoInPushedAlreadySent = 0; exec Container.CoFocusedObject.O2DCursorMoveOutWithButtonPush with [MouseCol MouseLgn MouseButtons]; }; set Container.CoHandledObject=nil } else nil; if IntoMouseObject then { if MouseButtons==0 then if NewHandled.DNVal.O2DFlags & O2D_ENABLE then exec NewHandled.DNVal.O2DCursorMoveIn with [MouseCol MouseLgn MouseButtons] else nil else { set Container.CoOutPushedAlreadySent = 0; set Container.CoInPushedAlreadySent = 1; exec Container.CoFocusedObject.O2DCursorMoveInWithButtonPush with [MouseCol MouseLgn MouseButtons]; }; set Container.CoHandledObject=NewHandled.DNVal } else nil; }; if Container.CoUserMoveIsAllowed then { exec Container.CoCursorMoveReflex with [Container MouseCol MouseLgn MouseButtons]; nil } else set Container.CoUserMoveIsAllowed=1; Window ;; fun O2D_NextHandledFather (Container, Node)= if Node==Container.CoArbre then Container.CoArbre.DNFirstChild else if Node.DNFather.DNNextBrother != nil then Node.DNFather.DNNextBrother else O2D_NextHandledFather Container Node.DNFather;; fun O2D_ContainerKeyDown(Window,Container,Key,VCode)= if Container.CoLocked then nil else /* if VCode == 9 then let if Container.CoHandledObject.O2DDisplayNode.DNFirstChild != nil then Container.CoHandledObject.O2DDisplayNode.DNFirstChild else if Container.CoHandledObject.O2DDisplayNode.DNNextBrother != nil then Container.CoHandledObject.O2DDisplayNode.DNNextBrother else O2D_NextHandledFather Container Container.CoHandledObject.O2DDisplayNode -> NewHandled in { if Container.CoHandledObject.O2DFlags & O2D_ENABLE then exec Container.CoHandledObject.O2DCursorMoveOut with [nil nil nil] else nil; if NewHandled.DNVal.O2DFlags & O2D_ENABLE then exec NewHandled.DNVal.O2DCursorMoveIn with [nil nil nil] else nil; set Container.CoHandledObject=NewHandled.DNVal; nil } else */ if Container.CoFocusedObject.O2DObjectKeyDown==nil then exec Container.CoKeyDownReflex with [Container Key VCode] else { exec Container.CoFocusedObject.O2DObjectKeyDown with [Key VCode]; Container }; Window ;; fun O2D_ContainerKeyUp(Window,Container,Key)= if Container.CoLocked then nil else if Container.CoFocusedObject.O2DObjectKeyUp==nil then exec Container.CoKeyUpReflex with [Container Key] else { exec Container.CoFocusedObject.O2DObjectKeyUp with [Key]; Container }; Window ;; fun O2D_ContainerDragAndDrop(Window,Container,MouseCol,MouseLgn,ListFichier)= if Container.CoLocked then nil else exec Container.CoDragAndDropReflex with [Container MouseCol MouseLgn ListFichier]; Window ;; fun ChangeDisplayFlag(Node,NewFlag)= if Node==nil then nil else let Node.DNVal -> Obj in { set Obj.O2DFlags=NewFlag; if !(NewFlag | O2D_ENABLE) then let _GETcursorPos Obj.O2DParentContainer.CoObjWin -> [MouseCol MouseLgn] in let O2D_search_object_under_mouse Obj.O2DParentContainer.CoArbre MouseCol MouseLgn -> NodeUnderMouse in if NodeUnderMouse.DNVal == Obj then O2D_ContainerCursorMoveEvent nil Obj.O2DParentContainer MouseCol MouseLgn 0 else nil else nil; }; Node;; /* Constructeur du Container Channel:canal du container Parent:fenetre parente XCoord:X Coordonnee du container YCoord:Y Coordonnee du container XSize:Largeur du container YSize:hauteur du container ContainerFlag:flag de creation du container Name:nom du container */ fun O2D_CrContainer(Channel,Parent,XCoord,YCoord,XSize,YSize,ContainerFlag,Name)= { let [ (_CRwindow Channel O2D_GetContainerWindow Parent XCoord YCoord XSize YSize ContainerFlag Name) (_CRbitmap Channel XSize YSize) ] -> [Window Bmp] in if (Window!=nil) && (Bmp!=nil) then { let MkContainerType [ Window /*CoObjWin*/ Bmp /*CoWorkingBitmap*/ Channel /*CoChannel*/ Parent /*CoParent*/ XCoord /*CoXCoord*/ YCoord /*CoYCoord*/ XSize /*CoXSize*/ YSize /*CoYSize*/ ContainerFlag /*ContainerFlag*/ Name /*CoName*/ 0 /*CoBackgroundColor*/ nil /*CoArbre*/ nil /*CoHandledObject*/ nil /*CoFocusedObject*/ 0 /*CoUserMoveIsAllowed*/ 0 /*CoOutPushedAlreadySent*/ 0 /*CoInPushedAlreadySent*/ 0 /*CoLocked*/ nil /*ContainerMoveReflex*/ nil /*ContainerResizingReflex*/ nil /*ContainerFocusReflex*/ nil /*ContainerKillFocusReflex*/ nil /*ContainerDestroyReflex*/ nil /*ContainerPaintReflex*/ nil /*CoClickReflex*/ nil /*CoUnclickReflex*/ nil /*CoCursorMoveReflex*/ nil /*CoDblClickReflex */ nil /*CoDragAndDropReflex*/ nil nil ] -> Container in { /* definition des reflexes de la fenetre */ let MkObj2D [ "root" 0 0 0 0 0 Container nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ] -> Elt in set Container.CoArbre=MkDisplayNode [Elt [0 0] nil nil nil nil]; _CBwinDestroy Window @O2D_ContainerDestroyEvent Container; _CBwinPaint Window @O2D_ContainerPaintEvent Container; _CBwinFocus Window @O2D_ContainerFocusEvent Container; _CBwinKillFocus Window @O2D_ContainerKillFocusEvent Container; _CBwinMove Window @O2D_ContainerMoveEvent Container; _CBwinSize Window @O2D_ContainerResizingEvent Container; _CBwinClick Window @O2D_ContainerClickEvent Container; _CBwinDClick Window @O2D_ContainerDblClickEvent Container; _CBwinUnclick Window @O2D_ContainerUnClickEvent Container; _CBcursorMove Window @O2D_ContainerCursorMoveEvent Container; _CBwinKeydown Window @O2D_ContainerKeyDown Container; _CBwinKeyup Window @O2D_ContainerKeyUp Container; if ContainerFlag&WN_DRAGDROP then _CBwinDropFile Window @O2D_ContainerDragAndDrop Container else nil; O2D_RedrawContainer Container 1; Container }; } else nil; };; /* Destructeur du container */ fun O2D_DsContainer(Container)= { if Container==nil then 0 else { O2D_DsDisplayNode Container.CoArbre.DNFirstChild; _DSbitmap Container.CoWorkingBitmap; _DSwindow Container.CoObjWin; set Container.CoArbre=nil; set Container.CoName=nil; set Container.CoContainerMoveReflex=nil; set Container.CoContainerResizingReflex=nil; set Container.CoContainerFocusReflex=nil; set Container.CoContainerKillFocusReflex=nil; set Container.CoContainerPaintReflex=nil; set Container.CoDblClickReflex=nil; set Container.CoClickReflex=nil; set Container.CoUnclickReflex=nil; set Container.CoCursorMoveReflex=nil; set Container=nil; O2D_RedrawContainer Container.CoParent 1; 1; }; };; fun O2D_CleanContainer (Container)= if Container==nil then nil else if Container.CoLocked then nil else { O2D_DsDisplayNode Container.CoArbre.DNFirstChild; Container };; /*************************************************************************************************************************/ /* Fonctions de definitions des Reflexes utilisateur du container */ /*************************************************************************************************************************/ fun O2D_SetContainerMoveReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoContainerMoveReflex=mkfun4 Function Parameter; Container };; fun O2D_SetContainerResizingReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoContainerResizingReflex=mkfun4 Function Parameter; Container };; fun O2D_SetContainerFocusReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoContainerFocusReflex=mkfun2 Function Parameter; Container };; fun O2D_SetContainerKillFocusReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoContainerKillFocusReflex=mkfun2 Function Parameter; Container };; fun O2D_SetContainerDestroyReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoContainerDestroyReflex=mkfun2 Function Parameter; Container };; fun O2D_SetContainerClickReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoClickReflex=mkfun5 Function Parameter; Container };; fun O2D_SetContainerUnclickReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoUnclickReflex=mkfun5 Function Parameter; Container };; fun O2D_SetContainerCursorMoveReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoCursorMoveReflex=mkfun5 Function Parameter; Container };; fun O2D_SetContainerDblClickReflex(Container,Function,Parameter)= if Container==nil then nil else{ set Container.CoDblClickReflex=mkfun5 Function Parameter; Container };; fun O2D_SetContainerDragAndDropReflex(Container,Function,Parameter)= if (Container==nil)||(!(Container.CoContainerFlag&WN_DRAGDROP)) then nil else{ set Container.CoDragAndDropReflex=mkfun5 Function Parameter; Container };; fun O2D_SetContainerKeyDownReflex(Container,Function,Parameter)= if (Container==nil) then nil else{ set Container.CoKeyDownReflex=mkfun4 Function Parameter; Container };; fun O2D_SetContainerKeyUpReflex(Container,Function,Parameter)= if (Container==nil) then nil else{ set Container.CoKeyUpReflex=mkfun3 Function Parameter; Container };; fun O2D_SetContainerBackgroundColor (Container, Color)= if Container==nil then nil else set Container.CoBackgroundColor = Color; Container;; fun O2D_GetContainerWindow (Container)= Container.CoObjWin;; /**************************************************************************************************************************/ /* Objet 2D */ /**************************************************************************************************************************/ /* Constructeur de l'objet 2D Container:container de l'objet ObjPere:objet pere de l'objet a creer Name:nom de l'objet xsize:largeur de l'objet ysize:hauteur de l'objet Coordinates:coordonee de l'objet par rapport au pere ObjFlag:flag de creation de l'objet (O2D_ENABLE,O2D_DISABLE,O2D_HIDE) */ fun O2D_NewObject(Container,ObjPere,Name,xsize,ysize,Coordinates,ObjFlag)= /* creation de l'objet */ let MkObj2D [ Name 0 0 xsize ysize ObjFlag Container nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ] -> Obj in /* creation du node de display */ let MkDisplayNode [Obj Coordinates nil nil nil nil] -> NodeToAdd in { /* on ajoute le nouveau node a la fin des fils de ObjPere */ let (if ObjPere==nil then Container.CoArbre else ObjPere.O2DDisplayNode) -> NodePere in let NodePere.DNFirstChild -> Last in let 0 -> Trouve in { if Last==nil then set NodePere.DNFirstChild=NodeToAdd else { while !Trouve do if Last.DNNextBrother==nil then { set Trouve=1; nil } else set Last=Last.DNNextBrother; set Last.DNNextBrother=NodeToAdd; set NodeToAdd.DNPreviousBrother=Last; }; set NodeToAdd.DNFather=NodePere; }; set Obj.O2DDisplayNode=NodeToAdd; ComputeCoordinates NodeToAdd; Obj };; /* Destructeur de l'objet */ fun O2D_DsDisplayNode(Node)= if Node==nil then nil else { O2D_DsDisplayNode Node.DNFirstChild; exec Node.DNVal.O2DDsObject with []; if Node.DNFather.DNFirstChild == Node then set Node.DNFather.DNFirstChild = Node.DNNextBrother else nil; set Node.DNPreviousBrother.DNNextBrother=Node.DNNextBrother; set Node.DNNextBrother.DNPreviousBrother=Node.DNPreviousBrother; O2D_DsDisplayNode Node.DNNextBrother; set Node=nil; };; fun O2D_DelObject(Obj)= if Obj!=nil then let Obj.O2DDisplayNode -> Node in { /* destruction recursive des fils du Node */ O2D_DsDisplayNode Node.DNFirstChild; exec Obj.O2DDsObject with []; /* destruction du node */ if Node.DNFather.DNFirstChild == Node then set Node.DNFather.DNFirstChild = Node.DNNextBrother else nil; set Node.DNPreviousBrother.DNNextBrother=Node.DNNextBrother; set Node.DNNextBrother.DNPreviousBrother=Node.DNPreviousBrother; set Node=nil; 0 } else nil;; fun ObjectNameEquality(Node,Name)= !((Node==nil)||(Name==nil)) || (!strcmp Node.DNVal.O2Dname Name) ;; /* Renvoie l'Obj2d dont le nom est Name */ fun O2D_GetObject(Container,Name)= let O2D_search_in_tree Container.CoArbre @ObjectNameEquality Name -> Node in if Node==nil then nil else Node.DNVal;; /* Renvoie le pere d'un objet */ fun O2D_GetFather(Obj)= Obj.O2DDisplayNode.DNFather.DNVal;; /* Renvoie le premier fils d'un objet */ fun O2D_GetFirstChild(Obj)= Obj.O2DDisplayNode.DNFirstChild.DNVal;; /* Renvoie le frere d'un objet */ fun O2D_GetBrother(Obj)= Obj.O2DDisplayNode.DNNextBrother.DNVal;; /* Renvoie les coordonnes d'un objet par rapport a son pere */ fun O2D_GetObjCoordinates(Obj)= Obj.O2DDisplayNode.DNCoordinates;; /* Change le flag d'affichage de l'objet Obj:Objet2d NewFlag:Nouveau flag (O2D_ENABLE,O2D_DISABLE,O2D_HIDE) RedrawFlag: RedrawFlag: flag pour savoir si le container doit etre redessine (1) ou pas (0) RepaintFlag: flag pour savoir si le container doit etre repaint (1) ou pas (0) */ fun O2D_ChangeObjDisplayFlag(Obj,NewFlag,RedrawFlag,RepaintFlag)= if Obj==nil then nil else { set Obj.O2DFlags=NewFlag; if (NewFlag & ~O2D_ENABLE) || (NewFlag & O2D_HIDE) then exec Obj.O2DObjectClickOut with [nil nil nil] else nil; if RedrawFlag then O2D_RedrawContainer Obj.O2DParentContainer RepaintFlag else nil; Obj } ;; fun O2D_SetFocus (Container, Obj)= _SETfocus Container.CoObjWin; exec Container.CoFocusedObject.O2DObjectClickOut with [nil nil nil]; exec Obj.O2DObjectClickIn with [nil nil nil]; set Container.CoFocusedObject = Obj; Container;; /* Change les coordonnes d'un objet par rapport a son pere Obj:Objet2d NewCoordinates:Nouvelles coordonnees RedrawFlag: RedrawtFlag: flag pour savoir si le container doit etre redessine (1) ou pas (0) RepaintFlag: flag pour savoir si le container doit etre repaint (1) ou pas (0) */ fun O2D_ChangeObjCoordinates(Obj,NewCoordinates,RedrawFlag,RepaintFlag)= set Obj.O2DDisplayNode.DNCoordinates=NewCoordinates; ComputeCoordinates Obj.O2DDisplayNode; ComputeDescentCoordinates Obj.O2DDisplayNode.DNFirstChild; if RedrawFlag then O2D_RedrawContainer Obj.O2DParentContainer RepaintFlag else nil; Obj;; /*************************************************************************************************************************/ /* Fonctions de definitions des methodes et des Reflexes de l'objet */ /*************************************************************************************************************************/ fun O2D_CBDsObject(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DDsObject=mkfun1 FunctionCallBack TypeObject; Object };; fun O2D_CBPaint(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DPaintObject=mkfun1 FunctionCallBack TypeObject; Object };; fun O2D_CBPaintPart(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DPaintPartOfObject=mkfun2 FunctionCallBack TypeObject; Object };; fun O2D_CBIsMouseOnDisplayObject(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DIsMouseOnDisplayObject=mkfun3 FunctionCallBack TypeObject; Object };; fun O2D_CBUserClickAllowed(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DUserClickAllowed=FunctionCallBack; Object };; fun O2D_CBUserUnClickAllowed(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DUserUnClickAllowed=FunctionCallBack; Object };; fun O2D_CBCursorMoveOut(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DCursorMoveOut=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBCursorMoveIn(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DCursorMoveIn=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBCursorMove(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DCursorMove=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBCursorMoveInWithButtonPush(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DCursorMoveInWithButtonPush=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBCursorMoveOutWithButtonPush(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DCursorMoveOutWithButtonPush=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectClickIn(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectClickIn=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectClickOut(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectClickOut=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectUnClickIn(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectUnClickIn=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectUnClickOut(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectUnClickOut=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectDblClickIn(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectDblClickIn=mkfun4 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectKeyUp(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectKeyUp=mkfun2 FunctionCallBack TypeObject; Object };; fun O2D_CBObjectKeyDown(Object,TypeObject,FunctionCallBack)= if Object==nil then nil else { set Object.O2DObjectKeyDown=mkfun3 FunctionCallBack TypeObject; Object };; /**********************************************************************************************************************/ /* Fonctions d'Affichages */ /**********************************************************************************************************************/ fun O2D_LockContainer (Container)= set Container.CoLocked = 1; Container;; fun O2D_UnlockContainer (Container)= set Container.CoLocked = 0; Container;; /* Renvoie le rectangle incluant l'objet */ fun O2D_RectangleIncludingObject(Object)= MkRectangle2D [ MkInt2DPoint [Object.O2Dx Object.O2Dy] MkInt2DPoint [Object.O2Dx+Object.O2Dw-1 Object.O2Dy+Object.O2Dh-1] ];; fun O2D_DisplayObjects(Container, Node)= if Node==nil then 0 else { let Node.DNVal -> obj in if obj!=nil then if !(obj.O2DFlags & O2D_HIDE) then { let exec obj.O2DPaintObject with [] -> [bitmap xb yb wb hb tc] in if (bitmap==nil) || (xb==nil) || (yb==nil) || (wb==nil) || (hb==nil) then nil else _CPbitmap16 Container.CoWorkingBitmap obj.O2Dx obj.O2Dy bitmap xb yb wb hb tc; O2D_DisplayObjects Container Node.DNFirstChild } else nil else nil; O2D_DisplayObjects Container Node.DNNextBrother; };; /* Redessine le container Container:le container RepaintFlag:flag pour savoir si le container doit etre repaint (1) ou non (0) */ fun O2D_RedrawContainer(Container,RepaintFlag)= if Container!=nil then { /* erase background */ /* _DRAWrectangle Container.CoWorkingBitmap 0 0 Container.CoXSize Container.CoYSize DRAW_SOLID 1 if Container.CoBackgroundColor != nil then Container.CoBackgroundColor else 0 DRAW_SOLID if Container.CoBackgroundColor != nil then Container.CoBackgroundColor else 0; */ /* redraw objects */ O2D_DisplayObjects Container Container.CoArbre.DNFirstChild; /* repaint container */ if RepaintFlag then _CPWbitmap Container.CoObjWin 0 0 Container.CoWorkingBitmap 0 0 Container.CoXSize Container.CoYSize else nil; Container } else nil;; /*window is invalid*/ fun O2D_ClearAreaIncludingObject(bmp,obj,color)= if color!=nil then { let O2D_RectangleIncludingObject obj -> Area in let SizeRectangle Area -> [AreaXSize AreaYSize] in _DRAWrectangle bmp Area.RctHG.iptX Area.RctHG.iptY AreaXSize+1 AreaYSize+1 DRAW_INVISIBLE 0 0 DRAW_SOLID color } else nil ;; fun O2D_DisplayObjectsInArea(Container,Node,AreaToRedraw)= if Node==nil then 0 else { let Node.DNVal -> obj in if (obj!=nil) && (!(obj.O2DFlags & O2D_HIDE)) then { let IntersectionRectangle AreaToRedraw O2D_RectangleIncludingObject obj -> partobjectoredraw in if partobjectoredraw != nil then let exec obj.O2DPaintPartOfObject with [MoveRectangleBy partobjectoredraw MkInt2DPoint [(-obj.O2Dx) (-obj.O2Dy)]] -> [bitmap xb yb wb hb tc] in if (bitmap==nil) || (xb==nil) || (yb==nil) || (wb==nil) || (hb==nil) then nil else if (wb>0) && (hb>0) then { _CPbitmap16 Container.CoWorkingBitmap partobjectoredraw.RctHG.iptX partobjectoredraw.RctHG.iptY bitmap xb yb wb hb tc; 0 } else nil else nil; O2D_DisplayObjectsInArea Container Node.DNFirstChild AreaToRedraw } else nil; O2D_DisplayObjectsInArea Container Node.DNNextBrother AreaToRedraw; };; /* Redessine l'espace delimite par un rectangle dans le container Container:le container a redessiner RedrawArea:Rectangle2d representant l'espace a redessiner RepaintFlag:flag pour savoir si le container doit etre repaint (1) ou non (0) */ fun O2D_RedrawArea(Container,RedrawArea,RepaintFlag)= if (Container!=nil)&&(RedrawArea!=nil) then /* Draw the area that fits into the window */ let IntersectionRectangle RedrawArea MkRectangle2D [ MkInt2DPoint [0 0] MkInt2DPoint [Container.CoXSize-1 Container.CoYSize-1] ] -> Area in { /* if Container.CoBackgroundColor != nil then { _DRAWrectangle Container.CoWorkingBitmap Area.RctHG.iptX Area.RctHG.iptY AreaXSize AreaYSize DRAW_SOLID 1 Container.CoBackgroundColor DRAW_SOLID Container.CoBackgroundColor } else nil; */ O2D_DisplayObjectsInArea Container Container.CoArbre.DNFirstChild Area; /* Repaint the area in the window if requested */ if RepaintFlag then let SizeRectangle Area -> [AreaXSize AreaYSize] in _CPWbitmap Container.CoObjWin Area.RctHG.iptX Area.RctHG.iptY Container.CoWorkingBitmap Area.RctHG.iptX Area.RctHG.iptY AreaXSize AreaYSize else nil; } else nil; Container;; fun O2D_RedrawObj (obj)= O2D_RedrawArea obj.O2DParentContainer O2D_RectangleIncludingObject obj 1;; fun O2D_GetContainerWorkingBitmap (container)= container.CoWorkingBitmap;; /* list */ fun makeSpace (i, l)= if i<= 0 then l else makeSpace (i-1) ('|)::l;; fun O2D_listObj (i, Node)= if Node==nil then nil else { O2D_listObj i+1 Node.DNFirstChild; O2D_listObj i Node.DNNextBrother; _fooS strcatn (listtostr makeSpace i nil)::Node.DNVal.O2Dname:: (if Node.DNVal.O2DFlags & O2D_ENABLE then " O2D_ENABLE" else nil):: (if Node.DNVal.O2DFlags & O2D_HIDE then " O2D_HIDE" else nil):: nil };; fun O2D_ContainerListObj (container)= if container!=nil then { _fooS strcat "List of obj in " container.CoName; O2D_listObj 1 container.CoArbre.DNFirstChild } else nil;; fun O2D_ContainerResize (container, width, height)= set container.CoXSize = width; set container.CoYSize = height; _SIZEwindow container.CoObjWin width height container.CoXCoord container.CoYCoord; container;; fun O2D_ContainerSetPosition (container, x, y)= set container.CoXCoord = x; set container.CoYCoord = y; _POSITIONwindow container.CoObjWin x y container.CoXSize container.CoYSize; container;;