+ wxEvtHandler *handlerA = m_eventHandler;
+ if ( handlerA )
+ {
+ wxEvtHandler *handlerB = handlerA->GetNextHandler();
+ handlerA->SetNextHandler((wxEvtHandler *)NULL);
+ m_eventHandler=handlerB;
+ if ( deleteHandler )
+ {
+ delete handlerA;
+ handlerA = (wxEvtHandler *)NULL;
+ }
+ }
+
+ return handlerA;
+}
+
+void wxCanvasObject::AppendEventHandler(wxEvtHandler *handler)
+{
+ GetEventHandler()->SetNextHandler(handler);
+}
+
+wxEvtHandler *wxCanvasObject::RemoveLastEventHandler(bool deleteHandler)
+{
+ //always the first in the row
+ wxEvtHandler *handlerA = m_eventHandler;
+ wxEvtHandler *handlerB=handlerA;
+ //goto the end
+ while ( handlerA->GetNextHandler() )
+ {
+ handlerB = handlerA;
+ handlerA = handlerA->GetNextHandler();
+ }
+
+ handlerB->SetNextHandler((wxEvtHandler *)NULL);
+ if ( deleteHandler )
+ {
+ delete handlerA;
+ }
+
+ return GetEventHandler();
+}
+
+wxRect wxCanvasObject::GetAbsoluteArea(const wxTransformMatrix& cworld)
+{
+ wxBoundingBox tmp=m_bbox;
+ tmp.MapBbox(cworld);
+
+ int x1 = m_admin->LogicalToDeviceX( tmp.GetMinX() );
+ int y1 = m_admin->LogicalToDeviceY( tmp.GetMinY() );
+ int x2 = m_admin->LogicalToDeviceX( tmp.GetMaxX() );
+ int y2 = m_admin->LogicalToDeviceY( tmp.GetMaxY() );
+
+ if (x1 > x2)
+ {
+ int tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+ if (y1 > y2)
+ {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ wxRect tmparea;
+ tmparea.x = x1;
+ tmparea.y = y1;
+ tmparea.width = x2-x1; // FIXME +1 ?
+ tmparea.height = y2-y1; // FIXME +1 ?
+
+ return tmparea;
+}
+
+void wxCanvasObject::MoveAbsolute( double x, double y )
+{
+ //save old position of boundingbox
+ double oldx = GetXMin();
+ double oldy = GetYMin();
+ double w = m_bbox.GetWidth();
+ double h = m_bbox.GetHeight();
+
+ SetPosXY(x,y);
+
+ double newx=GetXMin();
+ double newy=GetYMin();
+
+ double leftu,rightu,bottomu,topu ;
+ leftu = wxMin (oldx, newx ) ;
+ rightu = wxMax (oldx + w, newx + w) ;
+ topu = wxMin (oldy, newy) ;
+ bottomu = wxMax (oldy + h, newy + h) ;
+
+ if ( rightu - leftu < 2*w && bottomu - topu < 2*h )
+ {
+ m_admin->Update( this,leftu, topu, rightu - leftu, bottomu - topu);
+ }
+ else
+ {
+ m_admin->Update( this, oldx, oldy, w, h );
+ m_admin->Update( this, newx, newy, w, h );
+ }
+}
+
+void wxCanvasObject::MoveRelative( double x, double y )
+{
+ //save old position of boundingbox
+ double oldx = GetXMin();
+ double oldy = GetYMin();
+ double w = m_bbox.GetWidth();
+ double h = m_bbox.GetHeight();
+
+ TransLate(x,y);
+
+ double newx=GetXMin();
+ double newy=GetYMin();
+
+ double leftu,rightu,bottomu,topu ;
+ leftu = wxMin (oldx, newx ) ;
+ rightu = wxMax (oldx + w, newx + w) ;
+ topu = wxMin (oldy, newy) ;
+ bottomu = wxMax (oldy + h, newy + h) ;
+
+ if ( rightu - leftu < 2*w && bottomu - topu < 2*h )
+ {
+ m_admin->Update( this,leftu, topu, rightu - leftu, bottomu - topu);
+ }
+ else
+ {
+ m_admin->Update( this, oldx, oldy, w, h );
+ m_admin->Update( this, newx, newy, w, h );
+ }
+}
+
+
+void wxCanvasObject::DragStart()
+{
+ if (m_dragmode == wxDRAG_RECTANGLE)
+ {
+ this->SetVisible(FALSE);
+ wxTransformMatrix help;
+ double x = GetXMin();
+ double y = GetYMin();
+ double w = m_bbox.GetWidth();
+ double h = m_bbox.GetHeight();
+ m_admin->Update( this, x, y, w, h );
+ m_admin->UpdateNow();
+
+ wxRect recold=GetAbsoluteArea(help);
+ wxClientDC dc(m_admin->GetActive());
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxTRANSPARENT_BRUSH);
+ dc.SetLogicalFunction(wxINVERT);
+ dc.DrawRectangle(recold);
+ dc.SetBrush(wxNullBrush);
+ dc.SetPen(wxNullPen);
+ }
+ else if (m_dragmode != wxDRAG_REDRAW)
+ {
+ this->SetVisible(FALSE);
+ wxTransformMatrix help;
+ double x = GetXMin();
+ double y = GetYMin();
+ double w = m_bbox.GetWidth();
+ double h = m_bbox.GetHeight();
+
+ wxRect recnew=GetAbsoluteArea(help);
+
+ //redraw in buffer what should be there without this object
+ m_admin->Update( this, x, y, w, h );
+ m_admin->GetActive()->Freeze();
+
+ //save the drawing (without the object itself to a bitmap)
+ m_atnewpos = wxBitmap(recnew.width,recnew.height);
+ wxMemoryDC dcm;
+ dcm.SelectObject(*m_admin->GetActive()->GetBuffer());
+ wxMemoryDC tmp;
+ tmp.SelectObject(m_atnewpos);
+ tmp.Blit(0,0,recnew.width,recnew.height,&dcm,recnew.x,recnew.y,wxCOPY,FALSE);
+ tmp.SelectObject(wxNullBitmap);
+ dcm.SelectObject(wxNullBitmap);
+ }
+}
+
+
+void wxCanvasObject::DragRelative( double x, double y)
+{
+ if (m_dragmode == wxDRAG_RECTANGLE)
+ {
+ wxTransformMatrix help;
+
+ wxRect recold=GetAbsoluteArea(help);
+
+ TransLate(x,y);
+
+ wxRect recnew=GetAbsoluteArea(help);
+
+ wxClientDC dc(m_admin->GetActive());
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxTRANSPARENT_BRUSH);
+ dc.SetLogicalFunction(wxINVERT);
+ dc.DrawRectangle(recold);
+ dc.DrawRectangle(recnew);
+ dc.SetBrush(wxNullBrush);
+ dc.SetPen(wxNullPen);
+ }
+ else if (m_dragmode != wxDRAG_REDRAW)
+ {
+ wxClientDC dc(m_admin->GetActive());
+ wxMemoryDC tmp;
+
+ wxTransformMatrix help;
+ wxRect recold=GetAbsoluteArea(help);
+
+ //restore what was there (without the object itself)
+ wxMemoryDC dcm;
+ dcm.SelectObject(*m_admin->GetActive()->GetBuffer());
+ tmp.SelectObject(m_atnewpos);
+ dcm.Blit(recold.x,recold.y,recold.width,recold.height,&tmp,0,0,wxCOPY,FALSE);
+
+ TransLate(x,y);
+
+ wxRect recnew=GetAbsoluteArea(help);
+
+ //save the contents of the buffer at the new position
+ tmp.Blit(0,0,recnew.width,recnew.height,&dcm,recnew.x,recnew.y,wxCOPY,FALSE);
+ tmp.SelectObject(wxNullBitmap);
+
+ //m_atnewpos = m_admin->GetActive()->GetBuffer()->GetSubBitmap( recnew );
+
+ this->SetVisible(TRUE);
+ //redraw object into the buffer
+ m_admin->GetActive()->SetDC(&dcm);
+ Render(&help,recnew.x,recnew.y,recnew.width,recnew.height);
+
+ //draw the union or seperate to the canvas
+ double leftu,rightu,bottomu,topu ;
+ leftu = wxMin (recold.x, recnew.x ) ;
+ rightu = wxMax (recold.x + recold.width, recnew.x + recnew.width ) ;
+ topu = wxMin (recold.y, recnew.y) ;
+ bottomu = wxMax (recold.y + recold.height, recnew.y + recnew.height) ;
+
+ if ( rightu - leftu < 2*recold.width && bottomu - topu < 2*recold.height)
+ {
+ dc.Blit(leftu,topu,rightu - leftu,bottomu - topu,&dcm,leftu,topu,wxCOPY,FALSE);
+ }
+ else
+ {
+ //do them seperate
+ //first redraw what should be at the old position in the canvas
+ dc.Blit(recold.x,recold.y,recold.width,recold.height,&dcm,recold.x,recold.y,wxCOPY,FALSE);
+ //blit the new position of the object to the canvas
+ dc.Blit(recnew.x,recnew.y,recnew.width,recnew.height,&dcm,recnew.x,recnew.y,wxCOPY,FALSE);
+ }
+ dcm.SelectObject(wxNullBitmap);
+ this->SetVisible(FALSE);
+ }
+ else
+ MoveRelative(x,y);
+}
+
+
+void wxCanvasObject::DragEnd()
+{
+ m_atnewpos = wxBitmap(0,0);
+ m_admin->GetActive()->Thaw();
+ this->SetVisible(TRUE);
+ double x = GetXMin();
+ double y = GetYMin();
+ double w = m_bbox.GetWidth();
+ double h = m_bbox.GetHeight();
+ m_admin->Update( this, x, y, w, h );
+ m_admin->UpdateNow();
+}