00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #ifdef __GNUG__
00013 #pragma implementation "resizec.h"
00014 #endif
00015
00016
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
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
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
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
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
00130
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
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
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
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
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
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
00552 EVT_SIZE(wxResizeableControl::OnSize)
00553 EVT_MOVE(wxResizeableControl::OnMove)
00554 EVT_PAINT(wxResizeableControl::OnP)
00555 END_EVENT_TABLE()
00556
00557
00558
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
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
00719
00720
00721
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
00743 return 2;
00744
00745 case 4:
00746 return 16;
00747
00748 case 8:
00749 return 256;
00750
00751 case 24:
00752
00753
00754
00755 case 16:
00756 case 32:
00757
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 ,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
00776 int numColors = pbmih->biClrUsed;
00777 if (numColors==0)
00778 {
00779 numColors = wxGetNumOfBitmapColors(pbmih->biBitCount);
00780 }
00781
00782
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
00838 wxASSERT_MSG( !bitmap.GetSelectedInto(),
00839 wxT("can't copy bitmap selected into wxMemoryDC") );
00840
00841
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
00852
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
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
00878 DWORD dwLen = bi.biSize + biColors * sizeof(RGBQUAD);
00879
00880
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
00892 return dwLen + bi.biSizeImage;
00893 }
00894
00895
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 )
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
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
00981
00982
00983
00984
00985 END_EVENT_TABLE()
00986
00987