Index: trunk/SophyaPI/PI/pi3dwdg.cc
===================================================================
--- trunk/SophyaPI/PI/pi3dwdg.cc	(revision 2527)
+++ trunk/SophyaPI/PI/pi3dwdg.cc	(revision 2528)
@@ -61,6 +61,6 @@
 // long	 kind()
 //	Renvoie le type de l'objet ("=PIDraw3DWdg::ClassId")
-// int AddDrawer3D(PIDrawer3D*, bool ad=false)
-//	Ajoute un Drawer3D
+// int AddDrawer3D(PIDrawer3D*, bool ad=false, bool lock=false)
+//	Ajoute un Drawer3D. Voir *PIBaseWdg::AddDrawer()* pour les flags "ad,lock".
 //--
 
@@ -79,5 +79,5 @@
   //  AddDrawer(mBDrw, 0.12, 0.12, 0.88, 0.88, true, false, false);
   mBDrw->SetLimits(0.,1.,0.,1.,kAxeDirLtoR,kAxeDirDownUp);
-  AddDrawer3D(mBDrw, false);
+  AddDrawer3D(mBDrw, false, true);
   mBDrw->SetAxesFlags(kStdAxes);
   vfixed = false; // Il faut laisser le premier Drawer3D fixer les limites et la vue 3D
@@ -204,5 +204,5 @@
 
 /* --Methode-- */
-int PIDraw3DWdg::AddDrawer3D(PIDrawer3D* dr3, bool ad)
+int PIDraw3DWdg::AddDrawer3D(PIDrawer3D* dr3, bool ad, bool lock)
 {
 if ((!vfixed) && (dr3 != mBDrw))  { 
@@ -221,5 +221,5 @@
   else  dr3->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, co, psi);
   }
-int id = AddDrawer(dr3, false, false, ad);
+int id = AddDrawer(dr3, false, false, ad, lock);
 if (dr3 != mBDrw) dr3->SetAxesFlags(kAxesNone);
 m3DrIl.push_back(id);
Index: trunk/SophyaPI/PI/pi3dwdg.h
===================================================================
--- trunk/SophyaPI/PI/pi3dwdg.h	(revision 2527)
+++ trunk/SophyaPI/PI/pi3dwdg.h	(revision 2528)
@@ -46,5 +46,5 @@
 
 // Ajoute un Drawer 
-  int                   AddDrawer3D(PIDrawer3D*, bool ad=false);   
+  int                   AddDrawer3D(PIDrawer3D*, bool ad=false, bool lock=false);   
 
 //  Pour tenir trace des Drawers-3D qui sont detruits 
Index: trunk/SophyaPI/PI/pibwdggen.cc
===================================================================
--- trunk/SophyaPI/PI/pibwdggen.cc	(revision 2527)
+++ trunk/SophyaPI/PI/pibwdggen.cc	(revision 2528)
@@ -306,9 +306,13 @@
 //--
 //++
-// void  SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz=true)
+// void  SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool elastic=true)
 //	Définition du rectangle d'attachement par défaut. "(x1,y1)" et "(x2,y2)" determinent
 //	les positions des deux coins opposés.
-//	si "psz=true", les coordonnées sont supposées être des facteurs multiplicatifs 
+//	si "elastic=true", les coordonnées sont supposées être des facteurs multiplicatifs 
 //	des dimensions de l'objet.
+// void  GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+//	Retourne le rectangle d'attachement par défaut. "(x1,y1)" et "(x2,y2)" determinent
+//	les positions des deux coins opposés."elastic=true": Pos/Taille spécifiées en fraction 
+//	de la taille du PIBaseWdg.
 // void  SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax, -
 //                              int axrl=kAxeDirSame, int ayud=kAxeDirSame)
@@ -322,8 +326,15 @@
 
 /* --Methode-- */
-void PIBaseWdgGen::SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz)
+void PIBaseWdgGen::SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool elastic)
 {
 mDrX1 = x1;  mDrY1 = y1;
-mDrX2 = x2;  mDrY2 = y2;   mDrElastic = psz;
+mDrX2 = x2;  mDrY2 = y2;   mDrElastic = elastic;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+{
+x1 = mDrX1;  y1 = mDrY1;
+x2 = mDrX2;  y2 = mDrY2;   elastic = mDrElastic;
 }
 
@@ -347,5 +358,5 @@
 //++
 // int  AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, -
-//                bool psz=true, bool clip=true, bool ad=false)
+//                bool psz=true, bool clip=true, bool ad=false, bool lock=false)
 //	Attachement d'un "PIDrawer" au rectangle défini les coordonnées des deux coins opposés.
 //	si "psz=true", les coordonnées sont supposées être des facteurs multiplicatifs 
@@ -354,6 +365,7 @@
 //	d'attachement.
 //	si "ad=true", le "PIDrawer* drw" est détruit lors de la destruction de l'objet PIBaseWdg.
+//	si "lock=true", le drawer ne peut être détaché suite à une requête interactive.
 //	La méthode retourne l'identificateur du drawer attaché.
-// int  AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false)
+// int  AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false, bool lock=false)
 //	Ajout d'un "PIDrawer" au rectangle d'attachement par défaut. 
 //	Si "autolim=true", l'objet "PIBaseWdg" impose l'espace de coordonnées utilisateur
@@ -362,4 +374,5 @@
 //	d'attachement.
 //	si "ad=true", le "PIDrawer* drw" est détruit lors de la destruction de l'objet PIBaseWdg.
+//	si "lock=true", le drawer ne peut être détaché suite à une requête interactive.
 //	La méthode retourne l'identificateur du drawer attaché.
 //--
@@ -367,5 +380,5 @@
 /* --Methode-- */
 int PIBaseWdgGen::AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1,  
-                            PIGrCoord x2, PIGrCoord y2, bool psz, bool clip, bool ad)
+                            PIGrCoord x2, PIGrCoord y2, bool psz, bool clip, bool ad, bool lock)
 {
 if (drw == NULL)   return(0);
@@ -377,4 +390,5 @@
 did.elastic = psz;  did.clip = clip;
 did.id = mDrwId;  did.ad = ad; 
+did.lock = lock;
 did.drw = drw;
 mDrwList.push_back(did);
@@ -385,5 +399,5 @@
 
 /* --Methode-- */
-int PIBaseWdgGen::AddDrawer(PIDrawer* drw, bool autolim, bool clip, bool ad)
+int PIBaseWdgGen::AddDrawer(PIDrawer* drw, bool autolim, bool clip, bool ad, bool lock)
 {
 if (drw == NULL)   return(0);
@@ -394,5 +408,6 @@
 did.autoszp = true;   did.autolim = autolim;   
 did.elastic = false;   did.clip = clip;
-did.id = mDrwId;  did.ad = ad; 
+did.id = mDrwId;  did.ad = ad;
+did.lock = lock; 
 did.drw = drw;
 mDrwList.push_back(did);
@@ -404,9 +419,9 @@
 
 //++
-// void  MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz=true)
+// void  MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool elastic=true)
 //	Modification du rectangle d'attachement du PIDrawer avec l'identificateur "id" , retourné
-//	par "AddDrawer()"
+//	par "AddDrawer()". Si "elatic=true", taille/pos spécifiée en fraction de la taille du PIBaseWdg.
 // void  RemoveDrawer(int id)
-//	Ote le drawer "id" de la liste. 
+//	Ote le drawer "id" de la liste des drawers du PIBaseWdg.
 // void  DeleteDrawers()
 //	Ote tous les drawers de la liste. Détruit ceux ajoutés avec l'option "ad=true" 
@@ -414,5 +429,5 @@
 
 /* --Methode-- */
-void PIBaseWdgGen::MoveResizeDrawer(int id,  PIGrCoord x1, PIGrCoord y1,  PIGrCoord x2, PIGrCoord y2, bool psz)
+void PIBaseWdgGen::MoveResizeDrawer(int id,  PIGrCoord x1, PIGrCoord y1,  PIGrCoord x2, PIGrCoord y2, bool elastic)
 {
 vector<BWDrwId>::iterator it;
@@ -421,5 +436,5 @@
     (*it).x1 = x1;  (*it).y1 = y1;
     (*it).x2 = x2;  (*it).y2 = y2;
-    (*it).elastic = psz;
+    (*it).elastic = elastic;
     break;
   }
@@ -462,13 +477,25 @@
 //	Retourne le nombre de PIDrawer attachés
 // PIDrawer*  GetDrawerId(int id)
-//	Retourne le PIDrawer avec l'identificateur id
+//	Retourne le PIDrawer avec l'identificateur "id".
 // PIDrawer*  GetDrawer(int n)
 //	Retourne le PIDrawer "n=0..NbDrawers()-1" de la liste
-//--
-
-/* --Methode-- */
-int PIBaseWdgGen::NbDrawers()
-{
-return(mDrwList.size());
+// int  GetDrawerIdFromNum(int n)
+//	Retourne l'identificateur du drawer numero "n=0..NbDrawers()-1". 
+// bool IsDrawerLockedId(int id)
+//	Retourne le flag "lock" pour le PIDrawer avec l'identificateur "id".
+//	si "true", le drawer ne doit être détaché suite à une requête interactive.
+// bool IsDrawerAutoSizePos(int id)
+//	Retourne "true" si le  PIDrawer (Identificateur= "id") est positionné
+//	dans le rectangle par défaut.
+// void GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+//	Retourne le rectangle d'attachement du PIDrawer avec l'identificateur "id".
+//	"elastic=true": position et taille spécifiées en fraction de la taille du PIBaseWdg.
+//--
+
+/* --Methode-- */
+int PIBaseWdgGen::GetDrawerIdFromNum(int n)
+{
+if ( (n < 0) || (n >= mDrwList.size()) ) return(-1);
+return(mDrwList[n].id);
 }
 
@@ -490,4 +517,38 @@
 }
 
+/* --Methode-- */
+bool PIBaseWdgGen::IsDrawerLockedId(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id)  return((*it).lock);
+return true;
+}
+
+/* --Methode-- */
+bool PIBaseWdgGen::IsDrawerAutoSizePos(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id)  return(! (*it).autoszp );
+return false;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, 
+				     PIGrCoord& x2, PIGrCoord& y2, bool& elastic)
+{
+x1 = y1 = x2 = y2 = 0;
+elastic = false;
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id) { 
+    x1 = (*it).x1;  y1 = (*it).y1;
+    x2 = (*it).x2;  y2 = (*it).y2;
+    elastic = (*it).elastic;
+    break;
+  }
+return;
+}
 
 //++
Index: trunk/SophyaPI/PI/pibwdggen.h
===================================================================
--- trunk/SophyaPI/PI/pibwdggen.h	(revision 2527)
+++ trunk/SophyaPI/PI/pibwdggen.h	(revision 2528)
@@ -80,4 +80,6 @@
   virtual void       SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, 
                                              PIGrCoord x2, PIGrCoord y2, bool psz=true); 
+  virtual void       GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, 
+                                             PIGrCoord& x2, PIGrCoord& y2, bool& psz);
   virtual void       SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax,
                                             int axrl=kAxeDirSame, int ayud=kAxeDirSame); 
@@ -88,22 +90,29 @@
   virtual int        AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1, 
                                PIGrCoord x2, PIGrCoord y2, 
-                               bool psz=true, bool clip=true, bool ad=false);
-  virtual int        AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false);
+                               bool psz=true, bool clip=true, 
+			       bool ad=false, bool lock=false);
+  virtual int        AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, 
+			       bool ad=false, bool lock=false);
   virtual void       MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, 
-                                      PIGrCoord x2, PIGrCoord y2, bool psz=true);
+                                      PIGrCoord x2, PIGrCoord y2, bool elastic=true);
   virtual void       RemoveDrawer(int id);       // Ote un drawer de la liste
   virtual void       DeleteDrawers();            // Ote tous les drawers, delete des drawers ajoute avec ad=true
+
 // Acces aux drawers 
-  virtual int        NbDrawers();
-  virtual PIDrawer*  GetDrawerId(int id);   
-  virtual PIDrawer*  GetDrawer(int n); 
-  
+  inline  int        NbDrawers() { return mDrwList.size(); } 
+          int        GetDrawerIdFromNum(int n); 
+          PIDrawer*  GetDrawerId(int id);   
+          PIDrawer*  GetDrawer(int n); 
+          bool       IsDrawerLockedId(int id);
+          bool       IsDrawerAutoSizePos(int id);
+          void       GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, 
+				       PIGrCoord& x2, PIGrCoord& y2, bool& elastic);
+
 // Quel est le drawer actif
-  virtual void       SetActiveDrawerId(int id);   
-  virtual void       SetActiveDrawer(int n);   
-  virtual int        GetActiveDrawerId();   
-  virtual int        GetActiveDrawerNum();   
-
-  virtual PIDrawer*  GetActiveDrawer();   
+          void       SetActiveDrawerId(int id);   
+          void       SetActiveDrawer(int n);   
+          int        GetActiveDrawerId();   
+          int        GetActiveDrawerNum();   
+          PIDrawer*  GetActiveDrawer();   
 
 // Recherche du plus proche Drawer
@@ -114,11 +123,22 @@
   virtual void       CallDrawer(int id);
 
-// Devrait etre protected - mis ici a cause de cxx  11/07/97  Reza
-  struct BWDrwId { int id; PIGrCoord x1, y1, x2, y2; bool autoszp, autolim, elastic, clip, ad;  PIDrawer* drw; };
-
   virtual PIGraphic*  WindowGraphic();
 
-// -------------- Variables membre protegees -------------------
+// -------------- Variables membres protegees -------------------
 protected:
+// ..... Structure de la liste de gestion des drawers .....
+  struct BWDrwId { 
+    int id;          // Drawer Identifier
+    PIGrCoord x1, y1, x2, y2;  // Drawer Position(/Size) in Widget
+    // autoszp/autolim=true, Size/Limits imposed by widget - 
+    // elastic=true: Pos/Size = fraction of wdget size
+    bool autoszp, autolim, elastic; 
+    bool clip, ad;  // clip=true : No graphic draw outside Drawer rectangle
+    // ad=true: Delete Drawer when delete of PIBaseWdg
+    bool lock;  // lock=true: cannot be detached/deleted
+    PIDrawer* drw;   // Pointer to drawer itself
+  };
+// ...........................................................
+
   PIGraphicWin* mWGrC;  // PIGraphic (Contexte graphique) associe a la fenetre
   bool mAdfg;           // Pour la gestion de DeleteDrawers() quand appele par delete de PIBaseWdg
Index: trunk/SophyaPI/PI/pidrwtools.cc
===================================================================
--- trunk/SophyaPI/PI/pidrwtools.cc	(revision 2527)
+++ trunk/SophyaPI/PI/pidrwtools.cc	(revision 2528)
@@ -863,2 +863,381 @@
   }
 }
+
+//++
+// Class	PI
+// Lib		PIDrwMgrMenu
+// include	pidrwtools.h
+//
+//	Classe de menu (pop-up) permettant d'interagir avec les drawers
+//	attachés aux "PIBaseWdg".
+//--
+// Links	Parents
+// PIMenu
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+// PIBaseWdg
+//--
+
+//------------------------------------------------------------
+//------- Classe Event handler pour move/resize 
+class PIDrwPosSizeEvH : public PIEventHandler {
+public: 
+  PIDrwPosSizeEvH(PIBaseWdg* bwdg);
+  virtual void    ProcessEvent(); 
+protected:
+  PIBaseWdg* mBWdg;
+  int _x1, _y1, _x2, _y2;
+  bool _elastic;
+  int _ipx, _ipy;
+  int _cpx, _cpy;
+  bool _defrect;  // true -> modification DefaultRectangle
+  bool _rsz; // true -> resize option
+  bool _okend;
+};
+
+/* --Methode-- */
+PIDrwPosSizeEvH::PIDrwPosSizeEvH(PIBaseWdg* bwdg)
+{
+  mBWdg = bwdg;
+  _x1 = _y1 = _x2 = _y2 = -1;
+  _ipx = _ipy = -1;
+  _cpx = _cpy = -1;
+  _defrect = false;
+  _rsz = false;
+  _okend = false;
+  if (bwdg == NULL) return;
+  int aid = bwdg->GetActiveDrawerId();
+  if (aid < 0) return;
+  PIGrCoord x1, y1, x2, y2;
+  
+  _elastic = false;
+  if (mBWdg->IsDrawerAutoSizePos(aid)) {
+    mBWdg->GetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
+    _defrect = true; 
+  }
+  else { 
+    mBWdg->GetDrawerPosition(aid, x1, y1, x2, y2, _elastic);
+    _defrect = false; 
+  }
+    
+  if (_elastic) {
+    _x1 = (double)x1*(double)mBWdg->XSize();
+    _x2 = (double)x2*(double)mBWdg->XSize();
+    _y1 = (double)y1*(double)mBWdg->YSize();
+    _y2 = (double)y2*(double)mBWdg->YSize();
+  }
+  else {
+    _x1 = x1; _x2 = x2;
+    _y1 = y1; _y2 = y2;
+  }
+  _x2 -= _x1;  _y2 -= _y1;
+  cout << "DBG: x1=" << _x1 << " y1=" << _y1 << " x2=" << _x2 << " y2=" << _y2 << endl;
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+  
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+  gr->SelForeground(PI_Magenta);
+  gr->SelGOMode(PI_GOXOR);
+  gr->SelLine(PI_ThinLine);
+  gr->DrawBox(x1,y1, x2, y2);
+  x1 = _x1+0.9*(_x2-_x1);
+  y1 = _y1+0.9*(_y2-_y1);
+  gr->DrawFBox(x1,y1, x2, y2);
+  x1 = _x1+0.4*(_x2-_x1);
+  x2 = _x2-0.4*(_x2-_x1);
+  y1 = _y1+0.4*(_y2-_y1);
+  y2 = _y2-0.4*(_y2-_y1);
+  gr->DrawBox(x1,y1, x2, y2);
+  gr->SelGOMode(gmod);
+  gr->SelLine(gline);
+  gr->SelForeground(gcol);
+
+  cout << "DBG- Adding Event-Handler " << endl;
+  mBWdg->AddEventHandler(this, PIEvent_But1Press|PIEvent_Ptr1Move|PIEvent_But1Release);
+}
+
+/* --Methode-- */
+void PIDrwPosSizeEvH::ProcessEvent()
+{
+  int delx, dely;
+  PIGrCoord x1,y1,x2,y2;
+  x1 = _x1; x2 = _x2;
+  y1 = _y1; y2 = _y2;
+  bool fgok = false;
+  int aid = -1;
+
+  PIGraphic* gr = mBWdg->WindowGraphic();
+
+  PIGOMode gmod =  gr->GetGOMode();
+  PILineAtt gline = gr->GetLineAtt();
+  PIColors gcol = gr->GetForeground();
+
+  cout << " DBG - PIDrwPosSizeEvH::ProcessEvent() EventType=" << EventType() << endl;
+  switch (EventType()) {
+    case PIEvent_But1Press :
+      // Zone de changement de taille 
+      x1 = _x1+0.9*(_x2-_x1);
+      y1 = _y1+0.9*(_y2-_y1);
+      if ( (GetPosX() >= (int)x1) && (GetPosX() <= (int)x2) && 
+	   (GetPosY() >= (int)y1) && ((GetPosY() <= (int)y2) ) ) 
+	{ fgok = true; _rsz = true; }		 
+      x1 = _x1+0.4*(_x2-_x1);
+      x2 = _x2-0.4*(_x2-_x1);
+      y1 = _y1+0.4*(_y2-_y1);
+      y2 = _y2-0.4*(_y2-_y1);
+      if ( (GetPosX() >= (int)x1) && (GetPosX() <= (int)x2) && 
+	   (GetPosY() >= (int)y1) && ((GetPosY() <= (int)y2) ) ) 
+	{ fgok = true; _rsz = false; }
+      cout << " DBG-GetPosX()= " << GetPosX() << " GetPosY()= " << GetPosY() << endl;
+      if (GetPosX() < 5) fgok = false;
+      if (!fgok) _okend = true;
+      else { 
+	_cpx = _ipx = GetPosX();
+	_cpy = _ipy = GetPosY();
+      }
+      break;
+
+    case  PIEvent_Ptr1Move :
+      if (_okend) return; 
+      if (_ipx < 0)  return;
+      delx = GetPosX()-_cpx;
+      dely = GetPosY()-_cpy;
+      _cpx = GetPosX(); 
+      _cpy = GetPosY(); 
+      
+      gr->SelForeground(PI_Magenta);
+      gr->SelGOMode(PI_GOXOR);
+      gr->SelLine(PI_ThinLine);
+
+      gr->DrawBox(x1,y1, x2, y2);
+      x1 = _x1+0.9*(_x2-_x1);
+      y1 = _y1+0.9*(_y2-_y1);
+      gr->DrawFBox(x1,y1, x2, y2);
+      x1 = _x1+0.4*(_x2-_x1);
+      x2 = _x2-0.4*(_x2-_x1);
+      y1 = _y1+0.4*(_y2-_y1);
+      y2 = _y2-0.4*(_y2-_y1);
+      gr->DrawBox(x1,y1, x2, y2);
+
+      // Nouvelle position / taille 
+      _x2 += delx;
+      _y2 += dely;
+      if (!_rsz) { _x1 += delx;  _y1 += dely; }
+
+      x1 = _x1; x2 = _x2;
+      y1 = _y1; y2 = _y2;
+      gr->DrawBox(x1,y1, x2, y2);
+      x1 = _x1+0.9*(_x2-_x1);
+      y1 = _y1+0.9*(_y2-_y1);
+      gr->DrawFBox(x1,y1, x2, y2);
+      x1 = _x1+0.4*(_x2-_x1);
+      x2 = _x2-0.4*(_x2-_x1);
+      y1 = _y1+0.4*(_y2-_y1);
+      y2 = _y2-0.4*(_y2-_y1);
+      gr->DrawBox(x1,y1, x2, y2);      
+      gr->SelGOMode(gmod);
+      gr->SelLine(gline);
+      gr->SelForeground(gcol);
+
+      break;
+
+    case  PIEvent_But1Release :
+      if (_okend) {
+	// On enleve le handler et on efface de rectangle de resize/move
+	
+	gr->SelForeground(PI_Magenta);
+	gr->SelGOMode(PI_GOXOR);
+	gr->SelLine(PI_ThinLine);
+	
+	gr->DrawBox(x1,y1, x2, y2);
+	x1 = _x1+0.9*(_x2-_x1);
+	y1 = _y1+0.9*(_y2-_y1);
+	gr->DrawFBox(x1,y1, x2, y2);
+	x1 = _x1+0.4*(_x2-_x1);
+	x2 = _x2-0.4*(_x2-_x1);
+	y1 = _y1+0.4*(_y2-_y1);
+	y2 = _y2-0.4*(_y2-_y1);
+	gr->DrawBox(x1,y1, x2, y2);
+	gr->SelGOMode(gmod);
+	gr->SelLine(gline);
+	gr->SelForeground(gcol);
+
+	cout << " DBG- 	mBWdg->RemoveEventHandler(this); " << endl;
+	mBWdg->RemoveEventHandler(this);
+
+	return;
+      }
+
+      if (_ipx < 0)  return;
+      delx = GetPosX()-_cpx;
+      dely = GetPosY()-_cpy;
+
+      gr->SelForeground(PI_Magenta);
+      gr->SelGOMode(PI_GOXOR);
+      gr->SelLine(PI_ThinLine);
+
+      gr->DrawBox(x1,y1, x2, y2);
+      x1 = _x1+0.9*(_x2-_x1);
+      y1 = _y1+0.9*(_y2-_y1);
+      gr->DrawFBox(x1,y1, x2, y2);
+      x1 = _x1+0.4*(_x2-_x1);
+      x2 = _x2-0.4*(_x2-_x1);
+      y1 = _y1+0.4*(_y2-_y1);
+      y2 = _y2-0.4*(_y2-_y1);
+      gr->DrawBox(x1,y1, x2, y2);
+      gr->SelGOMode(gmod);
+      gr->SelLine(gline);
+      gr->SelForeground(gcol);
+
+      // Nouvelle position / taille 
+      _x2 += delx;
+      _y2 += dely;
+      if (!_rsz) { _x1 += delx;  _y1 += dely; }
+
+      x1 = _x1; x2 = _x2;
+      y1 = _y1; y2 = _y2;
+      gr->DrawBox(x1,y1, x2, y2);
+      x1 = _x1+0.9*(_x2-_x1);
+      y1 = _y1+0.9*(_y2-_y1);
+      gr->DrawFBox(x1,y1, x2, y2);
+      x1 = _x1+0.4*(_x2-_x1);
+      x2 = _x2-0.4*(_x2-_x1);
+      y1 = _y1+0.4*(_y2-_y1);
+      y2 = _y2-0.4*(_y2-_y1);
+      gr->DrawBox(x1,y1, x2, y2);      
+      gr->RestoreGraphicAtt();
+
+      aid = mBWdg->GetActiveDrawerId();
+      if (aid < 0) return;
+
+      if (_elastic) {
+	x1 = (double)_x1/(double)mBWdg->XSize();
+	x2 = (double)_x2/(double)mBWdg->XSize()+(double)_x1;
+	y1 = (double)_y1/(double)mBWdg->YSize();
+	y2 = (double)_y2/(double)mBWdg->YSize()+(double)_y1;
+      }
+      else {
+	x1 = _x1; x2 = _x2+_x1;
+	y1 = _y1; y2 = _y2+_y1;
+      }
+      if (_defrect) 
+	//	mBWdg->SetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
+	cout << "DBG-SetDefaultDrawRectangle() x1,y1=" << _x1 << "," << _y1 
+	     << " x2,y2=" << _x2 << "," << _y2 << endl;
+      else // mBWdg->MoveResizeDrawer(aid, x1, y1, x2, y2, _elastic);
+	cout << "DBG-MoveResizeDrawer() x1,y1=" << _x1 << "," << _y1 
+	     << " x2,y2=" << _x2 << "," << _y2 << endl;
+	
+      mBWdg->Refresh();
+      break; 
+
+    default :
+      break;
+  }
+  
+}
+
+//------------------------------------------------------------
+/* --Methode-- */
+PIDrwMgrMenu::PIDrwMgrMenu(PIBaseWdg* bwdg) 
+  : PIMenu(bwdg, "PIDrwMgrMenu", k_PopupMenu)
+{
+  mBWdg = bwdg;
+  mListDrw = NULL;
+  mEvH = NULL;
+
+  if (bwdg == NULL) return;
+
+  AppendItem("GraphicAttTools", 401);
+  AppendItem("OptionStringWin", 402);
+  AppendItem("ControlWin", 403);
+  AppendItem("Move/ReSize", 404);
+  AppendSeparator();
+  AppendItem("Detach", 405);
+  AppendItem("Highlight", 406);
+  AppendItem("Refresh", 407);
+  int aid = bwdg->GetActiveDrawerId();
+  if (aid < 0) {
+    for(int i=1; i<=6; i++)
+      SetSensitivityMsg(400+i, false);
+  }
+  else {
+    if ( !(bwdg->GetActiveDrawer()->HasSpecificControlWindow()) ) 
+      SetSensitivityMsg(403, false);
+    if ( bwdg->IsDrawerLockedId(aid)) 
+      SetSensitivityMsg(405, false);
+  }
+  if (bwdg->NbDrawers() > 0) {
+    AppendSeparator();
+    mListDrw = new PIMenu(this, "SelActiveDrw", k_PulldownMenu);
+    for(int k=0; k<bwdg->NbDrawers(); k++) {
+      char buff[16];
+      sprintf(buff, "%d- ", k);
+      string mit = buff;
+      mit += bwdg->GetDrawer(k)->Name();
+      mListDrw->AppendItem(mit.c_str(), 1000+k);
+    }
+    AppendPDMenu(mListDrw);
+  }
+}
+
+/* --Methode-- */
+PIDrwMgrMenu::~PIDrwMgrMenu() 
+{
+  if (mListDrw) delete mListDrw;
+  if (mEvH) delete mEvH;
+}
+
+/* --Methode-- */
+void PIDrwMgrMenu::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{  
+  if (mBWdg == NULL) return;
+  int aid = mBWdg->GetActiveDrawerId();
+  PIDrawer* actdrw = mBWdg->GetActiveDrawer();
+  PIMessage mod = ModMsg(msg);
+  msg = UserMsg(msg);
+  switch (msg) {
+    case 401 :
+      if (aid >= 0)  PIDrwTools::ShowPIDrwTools(mBWdg);
+      //	if (actdrw != NULL) actdrw->HighLight(false);
+      break;
+    case 402 :
+      if (actdrw != NULL) { 
+	PIDrwOptionStringWindow::ShowDrwOptionStringWindow(actdrw);
+	//	actdrw->HighLight(false);
+      }
+      break;
+    case 403 :
+      if (actdrw != NULL) { 
+	actdrw->ShowControlWindow(mBWdg);
+	// actdrw->HighLight(false);
+      }
+      break;
+    case 404 :
+      if (mEvH) delete mEvH;
+      mEvH = new PIDrwPosSizeEvH(mBWdg);
+      break;
+    case 405 :
+      if (aid >= 0) { 
+	mBWdg->RemoveDrawer(aid);
+	mBWdg->Refresh();
+      }
+      break;
+    case 406 :
+      if (actdrw != NULL)  actdrw->HighLight(true);
+      break;
+    case 407 :
+      mBWdg->Refresh();
+      break;
+    default :
+      //      if (actdrw != NULL) actdrw->HighLight(false);
+      if (msg >= 1000)
+	mBWdg->SetActiveDrawer(msg-1000);
+      break;
+  }
+
+}
Index: trunk/SophyaPI/PI/pidrwtools.h
===================================================================
--- trunk/SophyaPI/PI/pidrwtools.h	(revision 2527)
+++ trunk/SophyaPI/PI/pidrwtools.h	(revision 2528)
@@ -8,4 +8,5 @@
 #include "pisysdep.h"
 #include PISTDWDG_H
+#include PIMENU_H
 #include PIOPTMENU_H
 #include PIWIN_H
@@ -80,3 +81,19 @@
 };
 
+//-------------------------------------------------------------------------------------------
+// Classe de menu specifique de manipulation interactive des drawers attaches a un PIBaseWdg
+//-------------------------------------------------------------------------------------------
+class PIDrwPosSizeEvH;  // Event Handler pour le deplacement/resize des drawers 
+
+class PIDrwMgrMenu : public PIMenu {
+public:
+                  PIDrwMgrMenu(PIBaseWdg* bwdg);
+  virtual         ~PIDrwMgrMenu();
+  virtual void    Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+protected:
+  PIMenu*  mListDrw;
+  PIBaseWdg* mBWdg;
+  PIDrwPosSizeEvH* mEvH;
+};
+
 #endif
Index: trunk/SophyaPI/PI/piimage.cc
===================================================================
--- trunk/SophyaPI/PI/piimage.cc	(revision 2527)
+++ trunk/SophyaPI/PI/piimage.cc	(revision 2528)
@@ -143,5 +143,5 @@
  mdrw->SetAxesFlags(kAxesNone);
 gvdrw = new PIElDrawer();
-AddDrawer(mdrw, true, false, false);
+AddDrawer(mdrw, true, false, false, false);
 
 SetLut(-9.e19, 9.e19, kLutType_Lin, 0, false);
Index: trunk/SophyaPI/PI/piscdrawwdg.cc
===================================================================
--- trunk/SophyaPI/PI/piscdrawwdg.cc	(revision 2527)
+++ trunk/SophyaPI/PI/piscdrawwdg.cc	(revision 2528)
@@ -70,5 +70,5 @@
 // void  SetAxesFlags(unsigned int flags=kAxesDflt)
 //	Définit les attributs des axes.
-// int  AddScDrawer(PIDrawer*, bool ad=false)
+// int  AddScDrawer(PIDrawer*, bool ad=false, bool lock=false)
 //	Ajoute un Drawer.
 //--
@@ -96,5 +96,5 @@
   FreeLimits();
   xEndDrag = yEndDrag = xBegDrag = yBegDrag = 0;
-  AddDrawer(mBDrw, true, false, false);
+  AddDrawer(mBDrw, true, false, false, false);
 
 //  Pour afficher les coordonnees courante (click-bouton-1)  
@@ -106,4 +106,7 @@
   mInfoW = NULL;
   mInfoTxt = NULL;
+
+// Menu pour la manipulation des drawers 
+  mDrwMen = NULL;
 
   ActivateKeyboard();
@@ -125,4 +128,5 @@
     PIAxesTools::SetCurrentScDrawWdg(NULL);
   // Pour PIDrwTools, c'est fait par le destructeur de PIBaseWdgGen
+  if (mDrwMen) delete mDrwMen;
 }
 
@@ -152,5 +156,9 @@
     PIAxesTools::ShowPIAxesTools();  // Fenetre de gestion des axes
   }
-  
+  else if (key == 'D' || key == 'd') {
+    if (mDrwMen) delete mDrwMen;
+    mDrwMen = new PIDrwMgrMenu(this);
+    mDrwMen->Show();
+  }  
   else if (key == 'I' || key == 'i') UpdateInfoWindow();  // Fenetre Text-Info 
   }
@@ -290,5 +298,5 @@
 
 int 
-PIScDrawWdg::AddScDrawer(PIDrawer* d, bool ad)
+PIScDrawWdg::AddScDrawer(PIDrawer* d, bool ad, bool lock)
 {
   if (d == NULL)  return(-1);
@@ -301,5 +309,5 @@
     SetLimits(d->XMin(), d->XMax(), d->YMin(), d->YMax(), mDXdir, mDYdir);
   }
-  return(AddDrawer(d, true, true, ad));
+  return(AddDrawer(d, true, true, ad, lock));
 }
 
@@ -469,4 +477,7 @@
     if (actdr) { 
       actdr->HighLight(false);
+      if (mDrwMen) delete mDrwMen;
+      mDrwMen = new PIDrwMgrMenu(this);
+      mDrwMen->Show(this, x, y);
     }
     return;
Index: trunk/SophyaPI/PI/piscdrawwdg.h
===================================================================
--- trunk/SophyaPI/PI/piscdrawwdg.h	(revision 2527)
+++ trunk/SophyaPI/PI/piscdrawwdg.h	(revision 2528)
@@ -16,4 +16,5 @@
 
 // PIScDrawWdg, Gestionnaire de traceur 2D 
+class PIDrwMgrMenu;
 
 class PIScDrawWdg : public PIBaseWdg {
@@ -47,5 +48,5 @@
 
 // Ajoute un Drawer en auto 
-  int                AddScDrawer(PIDrawer*, bool ad=false);   
+  int                AddScDrawer(PIDrawer*, bool ad=false, bool lock=false);   
 
   inline PIElDrawer* BaseDrawer() { return mBDrw; };
@@ -120,4 +121,7 @@
   PIText * mInfoTxt;
 
+// Menu pour la manipulation des drawers 
+  PIDrwMgrMenu* mDrwMen;
+
 private:
   void  UpdateText(int xp, int yp);
Index: trunk/SophyaPI/PI/piwdgx.cc
===================================================================
--- trunk/SophyaPI/PI/piwdgx.cc	(revision 2527)
+++ trunk/SophyaPI/PI/piwdgx.cc	(revision 2528)
@@ -917,5 +917,6 @@
 {
 PIWdgGen::AddDrawHandler(drwh, ad);
-XtInsertEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this, XtListTail);
+if (mDHlist.size() == 1)
+  XtInsertEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this, XtListTail);
 }
 
@@ -924,5 +925,5 @@
 {
 PIWdgGen::RemoveDrawHandler(drwh);
-if (mEHlist.size() <= 0) XtRemoveEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this);
+if (mDHlist.size() == 0) XtRemoveEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this);
 }
 
@@ -946,5 +947,5 @@
 if (evtmask & PIEvent_Ptr3Move)  mask |= (PointerMotionHintMask | Button3MotionMask);
 if (evtmask & PIEvent_Keyboard)  mask |= KeyPressMask;
-printf("PIWdgX::AddEventHandler() Mask = %lx \n", (long)mask);
+// printf("PIWdgX::AddEventHandler() Mask = %lx \n", (long)mask);
 XtInsertEventHandler( XtWdg(), mask, FALSE, evthandler_piwdgx, this, XtListTail);
 }
@@ -954,4 +955,6 @@
 {
 PIWdgGen::RemoveEventHandler(evh);
+//cout << "DBG-PIWdgX::RemoveEventHandler( " << hex << evh << dec << ") mEHlist.size()="
+//      << mEHlist.size() << endl;
 if (mEHlist.size() > 0) return; 
 EventMask mask = EnterNotify;
@@ -992,8 +995,16 @@
                                int k, int km, unsigned long tm)
 {
+//cout << "DBG-PIWdgX:CallEventHandlers() - mEHlist.size()=" << mEHlist.size() << endl;
 PIEventHandler* eh;
 list<EvHand>::iterator it;
-for(it= mEHlist.begin(); it != mEHlist.end(); it++) {
+// On fait d'abord une copie pour eviter les problemes
+// lies a l'ajout ou la supression d'event-handler par un ProcessEvent()
+list<EvHand> cEHlist;
+for(it= mEHlist.begin(); it != mEHlist.end(); it++) { 
   if (!((*it).mask & evt))  continue; 
+  cEHlist.push_back(*it);
+}
+// Et on refait la boucle sur la liste copiee ...
+for(it= cEHlist.begin(); it != cEHlist.end(); it++) { 
   eh = (*it).evh;
   eh->SetCurrentWdg(this);
