MatOCAD Logo

Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

resizec.cpp

Go to the documentation of this file.
00001 
00002 // Name:        resizec.cpp
00003 // Purpose:     wxResizeableControl
00004 // Author:      Markus Greither
00005 // Modified by:
00006 // Created:     11/11/02
00007 // RCS-ID:      $Id:     1.06 2005/25/02 magr
00008 // Copyright:   (c) Markus Greither
00009 // Licence:     wxWindows license
00011 
00012 #ifdef __GNUG__
00013     #pragma implementation "resizec.h"
00014 #endif
00015 
00016 // For compilers that support precompilation, includes "wx.h".
00017 #include "wx/wxprec.h"
00018 
00019 #if defined(__BORLANDC__)
00020     #pragma hdrstop
00021 #endif
00022 
00023 #ifndef WX_PRECOMP
00024 #include "wx/wx.h"
00025 #endif
00026 
00027 #include "wx/image.h"
00028 #include "wx/metafile.h"
00029 #include "wx/clipbrd.h"
00030 #include "../../include/WidgetRidimensionabile/resizec.h"
00031 
00032 #ifdef __WXMSW__
00033 #include <windows.h>
00034 #include "wx/msw/winundef.h"
00035 #include "wx/msw/dib.h"
00036 #include "wx/msw/private.h"
00037 #endif
00038 
00039 // ----------------------------------------------------------------------------
00040 // Events
00041 // ----------------------------------------------------------------------------
00042 
00043 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHILD_CREATED)
00044 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHILD_MOVED)
00045 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHILD_CLOSED)
00046 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHILD_RESIZED)
00047 
00048 // ----------------------------------------------------------------------------
00049 // wxZoomData
00050 // ----------------------------------------------------------------------------
00051 
00052 void wxZoomData::SetSize(int width,int height)
00053 {
00054     if ((m_currRect.width != width) ||
00055         (m_currRect.height != height))
00056     {
00057         m_orgSize = wxSize(int(width/m_zoom),
00058                            int(height/m_zoom));
00059         m_currRect.width = width;
00060         m_currRect.height = height;
00061     }
00062 }
00063 
00064 void wxZoomData::Move(int xpos,int ypos)
00065 {
00066     if ((m_currRect.x != xpos) ||
00067         (m_currRect.x != ypos))
00068     {
00069         m_orgPos = wxPoint(int(xpos/m_zoom),
00070                            int(ypos/m_zoom));
00071         m_currRect.x = xpos;
00072         m_currRect.y = ypos;
00073     }
00074 }
00075 
00076 void wxZoomData::SetZoomRect(wxWindow *Window,float zoom,
00077                  int curxoffs,int curyoffs,
00078                  int newxoffs,int newyoffs)
00079 {
00080     m_currRect = wxRect(int((m_orgPos.x+curxoffs-newxoffs)*zoom),
00081                         int((m_orgPos.y+curyoffs-newyoffs)*zoom),
00082                         int(m_orgSize.x*zoom),int(m_orgSize.y*zoom));
00083     m_zoom = zoom;
00084     Window->SetSize(m_currRect);
00085 }
00086 
00087 // ----------------------------------------------------------------------------
00088 // wxResizeableControl
00089 // ----------------------------------------------------------------------------
00090 
00091 IMPLEMENT_DYNAMIC_CLASS(wxResizeableControl, wxScrolledWindow)
00092 
00093 wxResizeableControl::wxResizeableControl(wxWindow *AParent,
00094                                          int AnId,const wxPoint &pos,
00095                                          const wxSize &size,long style,
00096                                          const wxString &name)
00097  : wxScrolledWindow(AParent,AnId,pos,size,style,name),m_zoomData(size,pos),
00098    m_curId(-2),m_capt(0),m_movemode(wxResizeableControl::MoveWin),m_hasfocus(false)
00099 {
00100     wxCommandEvent cevent(wxEVT_COMMAND_CHILD_CREATED,GetId());
00101     if (GetParent())
00102         GetParent()->AddPendingEvent(cevent);
00103     SetScrollbars(0,0,0,0);
00104 
00105 }
00106 
00107 void wxResizeableControl::FocusRectCoord(wxDC &DC,wxCoord x1,wxCoord y1,
00108                                          wxCoord w,wxCoord h)
00109 {
00110     wxPen pen(*wxBLACK,1,wxDOT);
00111     const wxBrush &OldBr = DC.GetBrush();
00112     DC.SetBrush(*wxTRANSPARENT_BRUSH);
00113     DC.SetPen(pen);
00114     DC.SetLogicalFunction(wxINVERT);
00115     DC.DrawRectangle(x1,y1,w,h);
00116     DC.SetBrush(OldBr);
00117     DC.SetPen(wxNullPen);
00118     DC.SetLogicalFunction(wxCOPY);
00119 }
00120 
00121 // Draws the current window size
00122 void wxResizeableControl::DrawMoveRect(wxPoint hp,int Mode,float Ratio)
00123 {
00124     wxScreenDC dc;
00125     wxRect rect = NewRect(hp,Mode,Ratio);
00126     DrawFocusRect(dc,rect);
00127 }
00128 
00129 // FIXME: This doesn't work properly for windows that are
00130 // very small and the size rectangles overlap
00131 int wxResizeableControl::PointInSizeRect(wxPoint hp)
00132 {
00133     for (int i = 0;i < 8;i++)
00134     {
00135         int x = 6+GetSizeX(i)*(GetClientSize().x-11)/2;
00136         int y = 6+GetSizeY(i)*(GetClientSize().y-11)/2;
00137         wxRect rect(wxPoint(x-SizeXRad,y-SizeYRad),
00138                     wxPoint(x+SizeXRad,y+SizeYRad));
00139         if ((hp.x >= rect.x) && (hp.x <= rect.x+rect.width) &&
00140             (hp.y >= rect.y) && (hp.y <= rect.y+rect.height))
00141             return i;
00142     }
00143     return MoveWin;
00144 }
00145 
00146 // Calculates the current window size (Parent coordinates)
00147 wxRect wxResizeableControl::NewRect(wxPoint hp,int Mode,float Ratio)
00148 {
00149     wxSize size = GetClientSize();
00150     wxPoint pt(0,0);
00151     ClientToScreen(&pt.x,&pt.y);
00152     wxRect rect(pt,size);
00153     wxRect rect1(rect);
00154     wxPoint delta(hp.x-m_curpos.x,hp.y-m_curpos.y);
00155     switch (Mode)
00156     {
00157         case MoveWin : {rect.x += delta.x; rect.y += delta.y;}; break;
00158         case Top : rect.y += delta.y; rect.height -= delta.y; break;
00159         case Bottom : rect.height += delta.y; break;
00160         case Left : rect.x += delta.x; rect.width -= delta.x; break;
00161         case Right : rect.width += delta.x; break;
00162         case TopLeft :
00163             rect.x += delta.x;
00164             rect.y += delta.y;
00165             rect.width -= delta.x;
00166             rect.height -= delta.y;
00167             if (Ratio)
00168             {
00169               if (rect.GetWidth() < rect.GetHeight()*Ratio)
00170               {
00171                   int tmp = int(rect.GetHeight()*Ratio);
00172                   rect.x = rect.GetRight()-tmp+1;
00173                   rect.width = tmp;
00174               }
00175               else
00176               {
00177                   int tmp = int(rect.GetWidth()/Ratio);
00178                   rect.y = rect.GetBottom()-tmp+1;
00179                   rect.height = tmp;
00180               }
00181             }
00182             break;
00183         case TopRight :
00184             rect.width += delta.x;
00185             rect.y += delta.y;
00186             rect.height -= delta.y;
00187             if (Ratio)
00188             {
00189                 if (rect.GetWidth() < rect.GetHeight()*Ratio)
00190                     rect.width = int(rect.GetHeight()*Ratio);
00191                 else
00192                 {
00193                     int tmp = int(rect.GetWidth()/Ratio);
00194                     rect.y = rect.GetBottom()-tmp+1;
00195                     rect.height = tmp;
00196                 }
00197             }
00198             break;
00199         case BottomLeft :
00200             rect.x += delta.x;
00201             rect.width -= delta.x;
00202             rect.height += delta.y;
00203             if (Ratio)
00204             {
00205                 if (rect.GetWidth() < rect.GetHeight()*Ratio)
00206                 {
00207                     int tmp = int(rect.GetHeight()*Ratio);
00208                     rect.x = rect.GetRight()-tmp+1;
00209                     rect.width = tmp;
00210                 }
00211                 else
00212                     rect.height = int(rect.GetWidth()/Ratio);
00213             }
00214             break;
00215         case BottomRight :
00216             rect.width += delta.x;
00217             rect.height += delta.y;
00218             if (Ratio)
00219             {
00220                 if (rect.GetWidth() < rect.GetHeight()*Ratio)
00221                     rect.width = int(rect.GetHeight()*Ratio);
00222                 else
00223                     rect.height = int(rect.GetWidth()/Ratio);
00224             }
00225             break;
00226     }
00227     wxSize size1 = GetParent()->GetClientSize();
00228     wxPoint pt1(0,0);
00229     GetParent()->ClientToScreen(&pt1.x,&pt1.y);
00230     wxRect prect(pt1,size1);
00231     prect.Inflate(-30,-30);
00232     if ((((rect.x <= prect.GetRight()) &&
00233           (prect.x <= rect.GetRight())) &&
00234          ((rect.y <= prect.GetBottom()) &&
00235           (prect.y <= rect.GetBottom()))) &&
00236          (rect.GetWidth() >= 20) && (rect.GetHeight() >= 20))
00237         return rect;
00238     else
00239         return rect1;
00240 }
00241 
00242 // Draws the size rectangles
00243 void wxResizeableControl::DrawSizeRect(wxDC &dc)
00244 {   int AltROP = dc.GetLogicalFunction();
00245     dc.SetLogicalFunction(wxXOR);
00246     wxBrush brs(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW),wxSOLID);
00247     const wxBrush &OldBr = dc.GetBrush();
00248     dc.SetBrush(brs);
00249     wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW),1,wxSOLID);
00250 
00251     dc.SetPen(pen);
00252     for (int i = 0;i < 8;i++)
00253     {
00254         int x = 0,y = 0;
00255         switch (GetSizeX(i))
00256         {
00257             case 0 : x = SizeXRad; break;
00258             case 1 : x = GetClientSize().x/2; break;
00259             case 2 : x = GetClientSize().x; break;
00260         }
00261         switch (GetSizeY(i))
00262         {
00263             case 0 : y = SizeYRad; break;
00264             case 1 : y = GetClientSize().y/2; break;
00265             case 2 : y = GetClientSize().y; break;
00266         }
00267         dc.DrawRectangle(x-SizeXRad,y-SizeYRad,SizeXRad,SizeYRad);
00268     }
00269     dc.SetPen(wxNullPen);
00270     dc.SetBrush(OldBr);
00271     dc.SetLogicalFunction(AltROP);
00272 }
00273 
00274 void wxResizeableControl::OnSetCursor(wxSetCursorEvent &event)
00275 {
00276     long akcurid = -1;
00277     if (m_hasfocus)
00278     {
00279         wxPoint hp(event.GetX(),event.GetY()),point = hp;
00280         switch (PointInSizeRect(point))
00281         {
00282             case MoveWin :
00283                 akcurid = wxCURSOR_ARROW;
00284                 break;
00285             case Top :
00286             case Bottom :
00287                 akcurid = wxCURSOR_SIZENS;
00288                 break;
00289             case Left :
00290             case Right :
00291                 akcurid = wxCURSOR_SIZEWE;
00292                 break;
00293             case TopRight :
00294             case BottomLeft :
00295                 akcurid = wxCURSOR_SIZENESW;
00296                 break;
00297             case BottomRight :
00298             case TopLeft :
00299                 akcurid = wxCURSOR_SIZENWSE;
00300                 break;
00301             default :
00302                 m_csr = *wxSTANDARD_CURSOR;
00303         }
00304     }
00305     else
00306         akcurid = wxCURSOR_ARROW;
00307     if ((akcurid != m_curId) || (akcurid == -1))
00308     {
00309         m_curId = akcurid;
00310         if (m_curId != -1)
00311             m_csr = wxCursor(m_curId);
00312 #ifdef __WXGTK__
00313         SetCursor(m_csr);
00314 #endif
00315     }
00316 #ifdef __WXMSW__
00317     event.SetCursor(m_csr);
00318 #endif
00319 }
00320 
00321 void wxResizeableControl::OnLButtonDown(wxMouseEvent &event)
00322 {
00323      //Da rivedere
00324 
00325     wxPoint hp;
00326     hp.x = event.GetX();
00327     hp.y = event.GetY();
00328     ScreenToClient(hp);
00329     m_curpos = hp;
00330     m_lastcurpos = hp;
00331     SetFocusIgnoringChildren();
00332     if (!m_hasfocus)
00333     {
00334         SetFocusIgnoringChildren();
00335         m_hasfocus = true;
00336         m_movemode = MoveWin;
00337     }
00338     else
00339     {
00340         m_movemode = PointInSizeRect(hp);
00341     }
00342 
00343     CaptureMouse();
00344     m_capt = true;
00345     m_moved = false;
00346     event.Skip();
00347 }
00348 
00349 void wxResizeableControl::OnMouseMove(wxMouseEvent &event)
00350 {
00351     wxPoint hp;
00352     hp.x = event.GetX();
00353     hp.y = event.GetY();
00354     ScreenToClient(hp);
00355     if (hp != m_lastcurpos)
00356     {
00357         if (m_capt)
00358         {
00359             if (m_moved)
00360                 DrawMoveRect(m_lastcurpos,m_movemode,GetRatio());
00361             m_moved |= ((abs(m_curpos.x-hp.x) > 10) ||
00362                         (abs(m_curpos.y-hp.y) > 10));
00363             if (m_moved)
00364                 DrawMoveRect(hp,m_movemode,GetRatio());
00365         }
00366         m_lastcurpos = hp;
00367     }
00368 #ifdef __WXGTK__
00369     wxSetCursorEvent evt(hp.x,hp.y);
00370     OnSetCursor(evt);
00371 #endif
00372 }
00373 void wxResizeableControl::OnLButtonUp(wxMouseEvent &event)
00374 {
00375     wxPoint point;
00376     point.x = event.GetX();
00377     point.y = event.GetY();
00378     ScreenToClient(point);
00379     if (m_capt)
00380     {
00381         ReleaseMouse();
00382         m_capt = false;
00383         if (m_moved)
00384         {
00385             DrawMoveRect(m_lastcurpos,m_movemode,GetRatio());
00386             wxRect rect = NewRect(point,m_movemode,GetRatio());
00387             wxPoint pt = rect.GetPosition();
00388             GetParent()->ScreenToClient(&pt.x,&pt.y);
00389             rect.x = pt.x;
00390             rect.y = pt.y;
00391             SetSize(rect);
00392             Refresh();
00393         }
00394     }
00395     m_movemode = MoveWin;
00396 }
00397 
00398 int wxResizeableControl::GetSizeX(int Mode)
00399 {
00400     int Pos = -1;
00401     switch (Mode)
00402     {
00403         case Bottom :
00404         case Top : Pos = 1; break;
00405         case TopLeft :
00406         case BottomLeft :
00407         case Left : Pos = 0; break;
00408         case TopRight :
00409         case BottomRight :
00410         case Right : Pos = 2; break;
00411     }
00412     return Pos;
00413 }
00414 
00415 int wxResizeableControl::GetSizeY(int Mode)
00416 {
00417   int Pos = -1;
00418   switch (Mode)
00419   {
00420       case TopRight :
00421       case TopLeft :
00422       case Top : Pos = 0; break;
00423       case Left :
00424       case Right : Pos = 1; break;
00425       case BottomRight :
00426       case BottomLeft :
00427       case Bottom : Pos = 2; break;
00428   }
00429   return Pos;
00430 }
00431 
00432 bool wxResizeableControl::Destroy()
00433 {
00434     wxCommandEvent cevent(wxEVT_COMMAND_CHILD_CLOSED,GetId());
00435     if (GetParent())
00436         GetParent()->AddPendingEvent(cevent);
00437     return wxWindow::Destroy();
00438 }
00439 
00440 void wxResizeableControl::OnKillFocus(wxFocusEvent &)
00441 {
00442     if (m_hasfocus)
00443     {
00444         m_hasfocus = false;
00445         wxClientDC DC(this);
00446         DrawSizeRect(DC);
00447     }
00448 }
00449 void wxResizeableControl::OnP(wxPaintEvent &event)
00450 {
00451     wxPaintDC dc(this);
00452     wxSize size = GetClientSize();
00453     Paint(dc,false,size);
00454 
00455     if (m_hasfocus)
00456         DrawSizeRect(dc);
00457 }
00458 void wxResizeableControl::OnSetFocus(wxFocusEvent &)
00459 {
00460     if (!m_hasfocus)
00461     {
00462         Raise();
00463         Update();
00464         m_hasfocus = true;
00465 
00466         wxClientDC DC(this);
00467         DrawSizeRect(DC);
00468     }
00469 }
00470 
00471 /*void wxResizeableControl::OnKeyDown(wxKeyEvent &event)
00472 {
00473     if (event.AltDown())
00474     {
00475         event.Skip();
00476         return;
00477     }
00478     switch (event.GetKeyCode())
00479     {
00480         case WXK_DELETE :
00481         {
00482             Destroy();
00483             break;
00484         }
00485         case WXK_LEFT :
00486           if (event.ControlDown())
00487               if (event.ShiftDown())
00488                   SetSize(GetPosition().x,GetPosition().y,
00489                           GetSize().x-1,GetSize().y);
00490               else
00491                   Move(GetPosition().x-1,GetPosition().y);
00492           break;
00493         case WXK_RIGHT :
00494           if (event.ControlDown())
00495               if (event.ShiftDown())
00496                   SetSize(GetPosition().x,GetPosition().y,
00497                           GetSize().x+1,GetSize().y);
00498               else
00499                   Move(GetPosition().x+1,GetPosition().y);
00500           break;
00501         case WXK_UP :
00502           if (event.ControlDown())
00503               if (event.ShiftDown())
00504                   SetSize(GetPosition().x,GetPosition().y,
00505                           GetSize().x,GetSize().y-1);
00506               else
00507                   Move(GetPosition().x,GetPosition().y-1);
00508           break;
00509         case WXK_DOWN :
00510           if (event.ControlDown())
00511               if (event.ShiftDown())
00512                   SetSize(GetPosition().x,GetPosition().y,
00513                           GetSize().x,GetSize().y+1);
00514               else
00515                   Move(GetPosition().x,GetPosition().y+1);
00516           break;
00517         default:
00518           event.Skip();
00519     }
00520 }*/
00521 
00522 void wxResizeableControl::OnEditCut(wxCommandEvent &)
00523 {
00524     Destroy();
00525 }
00526 
00527 void wxResizeableControl::OnSize(wxSizeEvent &event)
00528 {
00529     wxCommandEvent cevent(wxEVT_COMMAND_CHILD_RESIZED,GetId());
00530     if (GetParent())
00531         GetParent()->AddPendingEvent(cevent);
00532     m_zoomData.SetSize(event.GetSize().x,event.GetSize().y);
00533 }
00534 
00535 void wxResizeableControl::OnMove(wxMoveEvent &event)
00536 {
00537     wxCommandEvent cevent(wxEVT_COMMAND_CHILD_MOVED,GetId());
00538     if (GetParent())
00539         GetParent()->AddPendingEvent(cevent);
00540     m_zoomData.Move(event.GetPosition().x,event.GetPosition().y);
00541 }
00542 
00543 BEGIN_EVENT_TABLE(wxResizeableControl,wxScrolledWindow)
00544     EVT_MENU(wxID_CUT,wxResizeableControl::OnEditCut)
00545     EVT_SET_FOCUS(wxResizeableControl::OnSetFocus)
00546     EVT_KILL_FOCUS(wxResizeableControl::OnKillFocus)
00547     EVT_MOTION(wxResizeableControl::OnMouseMove)
00548     EVT_SET_CURSOR(wxResizeableControl::OnSetCursor)
00549     EVT_LEFT_UP(wxResizeableControl::OnLButtonUp)
00550     EVT_LEFT_DOWN(wxResizeableControl::OnLButtonDown)
00551     //EVT_KEY_DOWN(wxResizeableControl::OnKeyDown)
00552     EVT_SIZE(wxResizeableControl::OnSize)
00553     EVT_MOVE(wxResizeableControl::OnMove)
00554     EVT_PAINT(wxResizeableControl::OnP)
00555 END_EVENT_TABLE()
00556 
00557 // ----------------------------------------------------------------------------
00558 // wxPictureControl
00559 // ----------------------------------------------------------------------------
00560 
00561 IMPLEMENT_DYNAMIC_CLASS(wxPictureControl,wxResizeableControl)
00562 
00563 void wxPictureControl::OnEditCut(wxCommandEvent &event)
00564 {
00565     OnEditCopy(event);
00566     event.Skip();
00567 }
00568 
00569 void wxPictureControl::OnRightDown(wxMouseEvent &event)
00570 {
00571     wxMenu *context_menu = new wxMenu;
00572 
00573     context_menu->Append(wxID_COPY, _("Copy"));
00574     context_menu->Append(wxID_CUT, _("Cut"));
00575     context_menu->Append(wxID_REVERT, _("Set to original size"));
00576 
00577     wxPoint hp;
00578     hp = event.GetPosition();
00579     PopupMenu(context_menu,hp);
00580     delete context_menu;
00581 }
00582 
00583 void wxPictureControl::OnPaletteChanged(wxSysColourChangedEvent &)
00584 {
00585     Refresh();
00586 }
00587 
00588 void wxPictureControl::OnSize(wxSizeEvent &event)
00589 {
00590     Refresh();
00591     event.Skip();
00592 }
00593 
00594 void wxPictureControl::OnPaint(wxPaintEvent &)
00595 {
00596     wxPaintDC dc(this);
00597     wxSize size = GetClientSize();
00598     Paint(dc,false,size);
00599 
00600     if (m_hasfocus)
00601         DrawSizeRect(dc);
00602 }
00603 
00604 void wxPictureControl::OnRevert(wxCommandEvent &)
00605 {
00606     wxSize orgs = GetOriginalSize();
00607     SetClientSize(orgs.x != -1 ? orgs.x : GetClientSize().x,
00608                   orgs.y != -1 ? orgs.y : GetClientSize().y);
00609 }
00610 
00611 BEGIN_EVENT_TABLE(wxPictureControl,wxResizeableControl)
00612     EVT_MENU(wxID_REVERT,wxPictureControl::OnRevert)
00613     EVT_PAINT(wxPictureControl::OnPaint)
00614     EVT_RIGHT_DOWN(wxPictureControl::OnRightDown)
00615     EVT_SIZE(wxPictureControl::OnSize)
00616     EVT_UPDATE_UI(wxID_COPY,wxPictureControl::CeEditCopy)
00617     EVT_UPDATE_UI(wxID_CUT,wxPictureControl::CeEditCut)
00618     EVT_SYS_COLOUR_CHANGED(wxPictureControl::OnPaletteChanged)
00619 END_EVENT_TABLE()
00620 
00621 #if defined(__WXMSW__) && wxUSE_METAFILE && wxUSE_ENH_METAFILE
00622 
00623 // ----------------------------------------------------------------------------
00624 // wxMetafileControl
00625 // ----------------------------------------------------------------------------
00626 
00627 IMPLEMENT_DYNAMIC_CLASS(wxMetafileControl, wxPictureControl)
00628 
00629 wxMetafileControl::wxMetafileControl(wxWindow *AParent, int AnId,WXHANDLE Meta,
00630                                      const wxPoint &pos,const wxSize &size,
00631                                      long style,const wxString &name)
00632  : wxPictureControl(AParent,AnId,pos,size,style,name)
00633 {
00634     m_metafile.SetHENHMETAFILE(Meta);
00635     wxSize msize = m_metafile.GetSize();
00636     SetSize(msize.x,msize.y);
00637 }
00638 
00639 wxMetafileControl::wxMetafileControl(wxWindow *AParent, int AnId,char *Data,
00640                                      int Size,
00641                                      const wxPoint &pos,const wxSize &size,
00642                                      long style,const wxString &name)
00643  : wxPictureControl(AParent,AnId,pos,size,style,name)
00644 {
00645     m_metafile.SetHENHMETAFILE((WXHANDLE)
00646                                ::SetEnhMetaFileBits(Size,(unsigned char *)Data));
00647 }
00648 
00649 wxMetafileControl::~wxMetafileControl()
00650 {
00651 }
00652 
00653 void wxMetafileControl::OnEditCopy(wxCommandEvent &)
00654 {
00655     if (wxTheClipboard->Open())
00656     {
00657         wxTheClipboard->Clear();
00658         m_metafile.SetClipboard(1,1);
00659         wxTheClipboard->Close();
00660     }
00661 }
00662 
00663 void wxMetafileControl::Paint(wxDC &dc,bool,wxSize &size)
00664 {
00665     wxRect rct(wxPoint(0,0),size);
00666     if (m_metafile.Ok())
00667         m_metafile.Play(&dc,&rct);
00668 }
00669 
00670 wxSize wxMetafileControl::GetOriginalSize()
00671 {
00672     return wxSize(m_metafile.GetWidth(),m_metafile.GetHeight());
00673 }
00674 
00675 float wxMetafileControl::GetRatio()
00676 {
00677     if (m_metafile.GetHeight())
00678         return float(m_metafile.GetWidth())/m_metafile.GetHeight();
00679     else
00680         return 0;
00681 }
00682 
00683 long wxGetEnhMetaFileBits(HENHMETAFILE metafile,UINT size,LPBYTE data)
00684 {
00685 #ifdef __BORLANDC__
00686     return ::GetEnhMetaFileBits(metafile,size,(unsigned char *)data);
00687 #else // some MinGW versions do not have GetEnhMetaFileBits in the headers
00688     HINSTANCE gdi = ::LoadLibrary(wxT("GDI32.DLL"));
00689     UINT (WINAPI *metab)(HENHMETAFILE,UINT,LPBYTE) = 0;
00690     long ret = 0;
00691     if (gdi)
00692         metab = (UINT (WINAPI *)(HENHMETAFILE,UINT,LPBYTE))
00693                 ::GetProcAddress(gdi,"GetEnhMetaFileBits");
00694     if (metab)
00695         ret = metab(metafile,size,(unsigned char *)data);
00696     if (gdi)
00697         ::FreeLibrary(gdi);
00698     return ret;
00699 #endif
00700 }
00701 
00702 long wxMetafileControl::GetPictureSize()
00703 {
00704     return wxGetEnhMetaFileBits((HENHMETAFILE)m_metafile.GetHENHMETAFILE(),0,0);
00705 }
00706 
00707 long wxMetafileControl::GetPictureData(char *data,long n)
00708 {
00709     return wxGetEnhMetaFileBits((HENHMETAFILE)m_metafile.GetHENHMETAFILE(),
00710                                 n,(unsigned char *)data);
00711 }
00712 
00713 BEGIN_EVENT_TABLE(wxMetafileControl,wxPictureControl)
00714     EVT_MENU(wxID_CUT, wxMetafileControl::OnEditCut)
00715     EVT_MENU(wxID_COPY, wxMetafileControl::OnEditCopy)
00716 END_EVENT_TABLE()
00717 
00718 #endif // __WXMSW__
00719 
00720 // ----------------------------------------------------------------------------
00721 // wxBitmapControl
00722 // ----------------------------------------------------------------------------
00723 
00724 IMPLEMENT_DYNAMIC_CLASS(wxBitmapControl, wxPictureControl)
00725 
00726 wxBitmapControl::wxBitmapControl(wxWindow *AParent, int AnId,
00727                                  const wxBitmap &bitmap,
00728                                  const wxPoint &pos,const wxSize &size,
00729                                  long style,const wxString &name)
00730  : wxPictureControl(AParent,AnId,pos,size,style,name)
00731 {
00732     m_bitmap = new wxBitmap(bitmap);
00733 }
00734 
00735 #ifdef __WXMSW__
00736 
00737 static size_t wxGetNumOfBitmapColors(size_t bitsPerPixel)
00738 {
00739     switch ( bitsPerPixel )
00740     {
00741         case 1:
00742             // monochrome bitmap, 2 entries
00743             return 2;
00744 
00745         case 4:
00746             return 16;
00747 
00748         case 8:
00749             return 256;
00750 
00751         case 24:
00752             // may be used with 24bit bitmaps, but we don't use it here - fall
00753             // through
00754 
00755         case 16:
00756         case 32:
00757             // bmiColors not used at all with these bitmaps
00758             return 0;
00759 
00760         default:
00761             wxFAIL_MSG( wxT("unknown bitmap format") );
00762             return 0;
00763     }
00764 }
00765 
00766 wxBitmapControl::wxBitmapControl(wxWindow *AParent, int AnId,char *Data,
00767                                  int /*Size*/,const wxPoint &pos,
00768                                  const wxSize &size,
00769                                  long style,const wxString &name)
00770  : wxPictureControl(AParent,AnId,pos,size,style,name)
00771 {
00772     const LPBITMAPINFO pbmi = (const LPBITMAPINFO)Data;
00773     const BITMAPINFOHEADER *pbmih = &pbmi->bmiHeader;
00774 
00775     // biClrUsed has the number of colors, unless it's 0
00776     int numColors = pbmih->biClrUsed;
00777     if (numColors==0)
00778     {
00779         numColors = wxGetNumOfBitmapColors(pbmih->biBitCount);
00780     }
00781 
00782     // offset of image from the beginning of the header
00783     DWORD ofs = numColors * sizeof(RGBQUAD);
00784     void *image = (char *)pbmih + sizeof(BITMAPINFOHEADER) + ofs;
00785 
00786     ScreenHDC hdc;
00787     HBITMAP hbmp = CreateDIBitmap(hdc, pbmih, CBM_INIT,
00788                                   image, pbmi, DIB_RGB_COLORS);
00789     if ( !hbmp )
00790     {
00791         wxLogLastError(wxT("CreateDIBitmap"));
00792     }
00793 
00794     wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount);
00795     bitmap.SetHBITMAP((WXHBITMAP)hbmp);
00796 
00797     m_bitmap = new wxBitmap(bitmap);
00798 }
00799 
00800 #endif
00801 
00802 wxBitmapControl::~wxBitmapControl()
00803 {
00804     delete m_bitmap;
00805 }
00806 
00807 void wxBitmapControl::Paint(wxDC &dc,bool,wxSize &size)
00808 {
00809     if (m_bitmap)
00810     {
00811         wxImage img = m_bitmap->ConvertToImage();
00812         img.Rescale(size.x,size.y);
00813         wxBitmap bmp(img);
00814         dc.DrawBitmap(bmp,0,0);
00815     }
00816 }
00817 
00818 void wxBitmapControl::OnEditCopy(wxCommandEvent &)
00819 {
00820     if (wxTheClipboard->Open())
00821     {
00822         wxTheClipboard->Clear();
00823         wxBitmapDataObject *bdo = new wxBitmapDataObject;
00824         wxBitmap *ClBitmap = new wxBitmap(*m_bitmap);
00825         bdo->SetBitmap(*ClBitmap);
00826         wxTheClipboard->SetData(bdo);
00827         wxTheClipboard->Close();
00828     }
00829 }
00830 
00831 #ifdef __WXMSW__
00832 
00833 size_t ConvertBitmapToDIB(LPBITMAPINFO pbi, const wxBitmap& bitmap)
00834 {
00835     wxASSERT_MSG( bitmap.Ok(), wxT("invalid bmp can't be converted to DIB") );
00836 
00837     // shouldn't be selected into a DC or GetDIBits() would fail
00838     wxASSERT_MSG( !bitmap.GetSelectedInto(),
00839                   wxT("can't copy bitmap selected into wxMemoryDC") );
00840 
00841     // prepare all the info we need
00842     BITMAP bm;
00843     HBITMAP hbmp = (HBITMAP)bitmap.GetHBITMAP();
00844     if ( !GetObject(hbmp, sizeof(bm), &bm) )
00845     {
00846         wxLogLastError(wxT("GetObject(bitmap)"));
00847 
00848         return 0;
00849     }
00850 
00851     // calculate the number of bits per pixel and the number of items in
00852     // bmiColors array (whose meaning depends on the bitmap format)
00853     WORD biBits = bm.bmPlanes * bm.bmBitsPixel;
00854     WORD biColors = (WORD)wxGetNumOfBitmapColors(biBits);
00855 
00856     BITMAPINFO bi2;
00857 
00858     bool wantSizeOnly = pbi == NULL;
00859     if ( wantSizeOnly )
00860         pbi = &bi2;
00861 
00862     // just for convenience
00863     BITMAPINFOHEADER& bi = pbi->bmiHeader;
00864 
00865     bi.biSize = sizeof(BITMAPINFOHEADER);
00866     bi.biWidth = bm.bmWidth;
00867     bi.biHeight = bm.bmHeight;
00868     bi.biPlanes = 1;
00869     bi.biBitCount = biBits;
00870     bi.biCompression = BI_RGB;
00871     bi.biSizeImage = 0;
00872     bi.biXPelsPerMeter = 0;
00873     bi.biYPelsPerMeter = 0;
00874     bi.biClrUsed = 0;
00875     bi.biClrImportant = 0;
00876 
00877     // memory we need for BITMAPINFO only
00878     DWORD dwLen = bi.biSize + biColors * sizeof(RGBQUAD);
00879 
00880     // first get the image size
00881     ScreenHDC hdc;
00882     if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, NULL, pbi, DIB_RGB_COLORS) )
00883     {
00884         wxLogLastError(wxT("GetDIBits(NULL)"));
00885 
00886         return 0;
00887     }
00888 
00889     if ( wantSizeOnly )
00890     {
00891         // size of the header + size of the image
00892         return dwLen + bi.biSizeImage;
00893     }
00894 
00895     // and now copy the bits
00896     void *image = (char *)pbi + dwLen;
00897     if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, image, pbi, DIB_RGB_COLORS) )
00898     {
00899         wxLogLastError(wxT("GetDIBits"));
00900 
00901         return 0;
00902     }
00903 
00904     return dwLen + bi.biSizeImage;
00905 }
00906 
00907 long wxBitmapControl::GetPictureData(char *data,long /*n*/)
00908 {
00909     ConvertBitmapToDIB((LPBITMAPINFO)data,*m_bitmap);
00910     return GetPictureSize();
00911 }
00912 
00913 long wxBitmapControl::GetPictureSize()
00914 {
00915     return ConvertBitmapToDIB(0,*m_bitmap);
00916 }
00917 
00918 #endif
00919 
00920 wxSize wxBitmapControl::GetOriginalSize()
00921 {
00922     return wxSize(m_bitmap->GetWidth(),m_bitmap->GetHeight());
00923 }
00924 
00925 float wxBitmapControl::GetRatio()
00926 {
00927     if (m_bitmap->GetHeight())
00928         return float(m_bitmap->GetWidth())/m_bitmap->GetHeight();
00929     else
00930         return 0;
00931 }
00932 
00933 BEGIN_EVENT_TABLE(wxBitmapControl,wxPictureControl)
00934     EVT_MENU(wxID_CUT, wxBitmapControl::OnEditCut)
00935     EVT_MENU(wxID_COPY, wxBitmapControl::OnEditCopy)
00936 END_EVENT_TABLE()
00937 
00938 // ----------------------------------------------------------------------------
00939 // wxResizeableControlCanvas
00940 // ----------------------------------------------------------------------------
00941 
00942 void wxResizeableControlCanvas::OnChildWindowChange(wxCommandEvent &)
00943 {
00944     m_scrollflag = true;
00945 }
00946 
00947 void wxResizeableControlCanvas::UpdateScrollRange()
00948 {
00949     wxNode *Child = GetChildren().First();
00950     wxSize GesSize;
00951     int x,y;
00952     GetViewStart(&x,&y);
00953     while (Child)
00954     {
00955         wxWindow *chw = wxDynamicCast(Child->GetData(),wxResizeableControl);
00956         if (chw)
00957         {
00958             wxRect rect = chw->GetRect();
00959             rect.x += x;
00960             rect.y += y;
00961             if (rect.GetBottom() > GesSize.y)
00962                 GesSize.y = rect.GetBottom();
00963             if (rect.GetRight() > GesSize.x)
00964                 GesSize.x = rect.GetRight();
00965         }
00966         Child = Child->Next();
00967     }
00968     SetScrollbars(1,1,GesSize.x,GesSize.y,x,y,true);
00969 }
00970 
00971 void wxResizeableControlCanvas::OnIdle(wxIdleEvent &event)
00972 {
00973     if (m_scrollflag)
00974         UpdateScrollRange();
00975     m_scrollflag = false;
00976     event.Skip();
00977 }
00978 
00979 BEGIN_EVENT_TABLE(wxResizeableControlCanvas,wxScrolledWindow)
00980    /* EVT_IDLE(wxResizeableControlCanvas::OnIdle)
00981     EVT_CHILD_CREATED(-1, wxResizeableControlCanvas::OnChildWindowChange)
00982     EVT_CHILD_MOVED(-1, wxResizeableControlCanvas::OnChildWindowChange)
00983     EVT_CHILD_RESIZED(-1, wxResizeableControlCanvas::OnChildWindowChange)
00984     EVT_CHILD_CLOSED(-1, wxResizeableControlCanvas::OnChildWindowChange)
00985 */END_EVENT_TABLE()
00986 
00987 

 

SourceForge Logo