MatOCAD Logo

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

defplugin.cpp

Go to the documentation of this file.
00001 
00012 #include "../../include/wxIFM/defplugin.h"
00013 
00014 #include <wx/dcbuffer.h>
00015 #include <wx/dcclient.h>
00016 #include <wx/settings.h>
00017 
00018 #if IFM_USE_WX_RTTI
00019 IMPLEMENT_DYNAMIC_CLASS(wxIFMDefaultPlugin, wxEvtHandler);
00020 #endif
00021 
00022 BEGIN_EVENT_TABLE(wxIFMDefaultPlugin, wxEvtHandler)
00023     EVT_IFM_SETRECT         (wxIFMDefaultPlugin::OnSetRect)
00024     EVT_IFM_SETCLIENTRECT   (wxIFMDefaultPlugin::OnSetRect)
00025     EVT_IFM_SETBACKGROUNDRECT (wxIFMDefaultPlugin::OnSetRect)
00026     EVT_IFM_GETRECT         (wxIFMDefaultPlugin::OnGetRect)
00027     EVT_IFM_GETCLIENTRECT   (wxIFMDefaultPlugin::OnGetRect)
00028     EVT_IFM_GETBACKGROUNDRECT (wxIFMDefaultPlugin::OnGetRect)
00029     EVT_IFM_CONVERTRECT     (wxIFMDefaultPlugin::OnConvertRect)
00030     EVT_IFM_HITTEST         (wxIFMDefaultPlugin::OnHitTest)
00031     EVT_IFM_UPDATECOMPONENT (wxIFMDefaultPlugin::OnUpdate)
00032     EVT_IFM_CALCRECTS       (wxIFMDefaultPlugin::OnCalcRects)
00033 
00034     EVT_IFM_SETDESIREDSIZE  (wxIFMDefaultPlugin::OnSetDesiredSize)
00035     EVT_IFM_GETDESIREDSIZE  (wxIFMDefaultPlugin::OnGetDesiredSize)
00036     EVT_IFM_SETMINSIZE      (wxIFMDefaultPlugin::OnSetMinSize)
00037     EVT_IFM_SETMAXSIZE      (wxIFMDefaultPlugin::OnSetMaxSize)
00038     EVT_IFM_GETMINSIZE      (wxIFMDefaultPlugin::OnGetMinSize)
00039     EVT_IFM_GETMAXSIZE      (wxIFMDefaultPlugin::OnGetMaxSize)
00040 
00041     EVT_IFM_BEGINPAINT      (wxIFMDefaultPlugin::OnBeginPaint)
00042     EVT_IFM_ENDPAINT        (wxIFMDefaultPlugin::OnEndPaint)
00043     EVT_IFM_PAINTBG         (wxIFMDefaultPlugin::OnPaintBg)
00044     EVT_IFM_PAINTBORDER     (wxIFMDefaultPlugin::OnPaintBorder)
00045 
00046     EVT_IFM_DOCK            (wxIFMDefaultPlugin::OnDock)
00047     EVT_IFM_UNDOCK          (wxIFMDefaultPlugin::OnUndock)
00048 
00049     EVT_IFM_SETCHILDSIZE    (wxIFMDefaultPlugin::OnSetChildSize)
00050 
00051     EVT_IFM_SHOWCHILD       (wxIFMDefaultPlugin::OnShowChild)
00052     EVT_IFM_HIDECHILD       (wxIFMDefaultPlugin::OnShowChild)
00053     EVT_IFM_SHOWCOMPONENT   (wxIFMDefaultPlugin::OnShowComponent)
00054     EVT_IFM_VISIBILITYCHANGED (wxIFMDefaultPlugin::OnVisibilityChanged)
00055 
00056 #if IFM_CANFLOAT
00057     EVT_IFM_FLOAT           (wxIFMDefaultPlugin::OnFloat)
00058     EVT_IFM_FLOATING_SIZE   (wxIFMDefaultPlugin::OnFloatingSize)
00059     EVT_IFM_FLOATING_MOVE   (wxIFMDefaultPlugin::OnFloatingMove)
00060     EVT_IFM_FLOATING_NOTIFY (wxIFMDefaultPlugin::OnFloatNotify)
00061 #endif
00062 END_EVENT_TABLE()
00063 
00064 wxIFMDefaultPlugin::wxIFMDefaultPlugin(wxIFMInterfacePluginBase *ip)
00065     : wxEvtHandler(),
00066     m_ip(ip)
00067 { }
00068 
00069 void wxIFMDefaultPlugin::OnSetRect(wxIFMRectEvent &event)
00070 {
00071     wxIFMComponent *component = event.GetComponent();
00072     wxEventType type = event.GetEventType();
00073 
00074     if( type == wxEVT_IFM_SETRECT )
00075     {
00076         // store the rect
00077         wxRect rect = event.GetRect();
00078 
00079         // see if we need to use existing values
00080         if( rect.x == IFM_USE_CURRENT_VALUE || rect.y == IFM_USE_CURRENT_VALUE ||
00081             rect.width == IFM_USE_CURRENT_VALUE || rect.height == IFM_USE_CURRENT_VALUE )
00082         {
00083             // we need to use some existing values, find out what they are first
00084             // do this with an event to allow GETRECT to be processed in all circumstances
00085             wxIFMRectEvent rectevt(wxEVT_IFM_GETRECT, component);
00086             GetIP()->ProcessPluginEvent(rectevt);
00087             wxRect m_rect = rectevt.GetRect();
00088 
00089             if( rect.x == IFM_USE_CURRENT_VALUE )
00090                 rect.x = m_rect.x;
00091             if( rect.y == IFM_USE_CURRENT_VALUE )
00092                 rect.y = m_rect.y;
00093             if( rect.width == IFM_USE_CURRENT_VALUE )
00094                 rect.width = m_rect.width;
00095             if( rect.height == IFM_USE_CURRENT_VALUE )
00096                 rect.height = m_rect.height;
00097         }
00098 
00099         // make sure we don't size the component smaller than its minimum size
00100         wxIFMRectEvent minevt(wxEVT_IFM_GETMINSIZE, component);
00101         GetIP()->ProcessPluginEvent(minevt);
00102         const wxSize &min_size = minevt.GetSize();
00103 
00104         if( min_size.GetWidth() != IFM_NO_MINIMUM && min_size.GetWidth() > rect.width )
00105             rect.width = min_size.GetWidth();
00106         if( min_size.GetHeight() != IFM_NO_MINIMUM && min_size.GetHeight() > rect.height )
00107             rect.height = min_size.GetHeight();
00108 
00109         // dont size bigger than the maximum either
00110         wxIFMRectEvent maxevt(wxEVT_IFM_GETMAXSIZE, component);
00111         GetIP()->ProcessPluginEvent(maxevt);
00112         const wxSize &max_size = maxevt.GetSize();
00113 
00114         if( max_size.GetWidth() != IFM_NO_MAXIMUM && max_size.GetWidth() < rect.width )
00115             rect.width = max_size.GetWidth();
00116         if( max_size.GetHeight() != IFM_NO_MAXIMUM && max_size.GetHeight() < rect.height )
00117             rect.height = max_size.GetHeight();
00118 
00119         component->m_rect = rect;
00120     }
00121     else if( type == wxEVT_IFM_SETBACKGROUNDRECT )
00122     {
00123         // calculate new rect
00124         wxRect rect = event.GetRect();
00125 
00126         // see if we need to use existing values
00127         if( rect.x == IFM_USE_CURRENT_VALUE || rect.y == IFM_USE_CURRENT_VALUE ||
00128             rect.width == IFM_USE_CURRENT_VALUE || rect.height == IFM_USE_CURRENT_VALUE )
00129         {
00130             // we need to use some existing values, find out what they are first
00131             // do this with an event to allow GETBACKGROUNDRECT to be processed in all circumstances
00132             wxIFMRectEvent rectevt(wxEVT_IFM_GETBACKGROUNDRECT, component);
00133             GetIP()->ProcessPluginEvent(rectevt);
00134             wxRect m_rect = rectevt.GetRect();
00135 
00136             if( rect.x == IFM_USE_CURRENT_VALUE )
00137                 rect.x = m_rect.x;
00138 
00139             if( rect.y == IFM_USE_CURRENT_VALUE )
00140                 rect.y = m_rect.y;
00141 
00142             if( rect.width == IFM_USE_CURRENT_VALUE )
00143                 rect.width = m_rect.width;
00144 
00145             if( rect.height == IFM_USE_CURRENT_VALUE )
00146                 rect.height = m_rect.height;
00147         }
00148 
00149         // Calculate the new absolute size using CONVERTRECT event
00150         wxIFMConvertRectEvent evt(component, IFM_COORDS_BACKGROUND, IFM_COORDS_ABSOLUTE, rect);
00151         GetIP()->ProcessPluginEvent(evt);
00152         rect = evt.GetRect();
00153 
00154         // set the rect
00155         component->m_rect = rect;
00156     }
00157     else if( type == wxEVT_IFM_SETCLIENTRECT )
00158     {
00159         // calculate new rect
00160         wxRect rect = event.GetRect();
00161 
00162         // see if we need to use existing values
00163         if( rect.x == IFM_USE_CURRENT_VALUE || rect.y == IFM_USE_CURRENT_VALUE ||
00164             rect.width == IFM_USE_CURRENT_VALUE || rect.height == IFM_USE_CURRENT_VALUE )
00165         {
00166             // we need to use some existing values, find out what they are first
00167             // do this with an event to allow GETCLIENTRECT to be processed in all circumstances
00168             wxIFMRectEvent rectevt(wxEVT_IFM_GETCLIENTRECT, component);
00169             GetIP()->ProcessPluginEvent(rectevt);
00170             wxRect m_rect = rectevt.GetRect();
00171 
00172             if( rect.x == IFM_USE_CURRENT_VALUE )
00173                 rect.x = m_rect.x;
00174 
00175             if( rect.y == IFM_USE_CURRENT_VALUE )
00176                 rect.y = m_rect.y;
00177 
00178             if( rect.width == IFM_USE_CURRENT_VALUE )
00179                 rect.width = m_rect.width;
00180 
00181             if( rect.height == IFM_USE_CURRENT_VALUE )
00182                 rect.height = m_rect.height;
00183         }
00184 
00185         // Calculate the new absolute size using CONVERTRECT event
00186         wxIFMConvertRectEvent evt(component, IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, rect);
00187         GetIP()->ProcessPluginEvent(evt);
00188         rect = evt.GetRect();
00189 
00190         // set the new rect
00191         component->m_rect = rect;
00192     }
00193 #ifdef __WXDEBUG__
00194     else
00195         wxFAIL_MSG(wxT("Unknown event type encountered"));
00196 #endif
00197 }
00198 
00199 void wxIFMDefaultPlugin::OnGetRect(wxIFMRectEvent &event)
00200 {
00201     wxIFMComponent *component = event.GetComponent();
00202     wxEventType type = event.GetEventType();
00203 
00204     // return wxRect(0,0,0,0) if we are hidden
00205     /*
00206     if( component->m_hidden )
00207     {
00208         event.SetRect(wxRect(0,0,0,0));
00209         return;
00210     }
00211     */
00212 
00213     if( type == wxEVT_IFM_GETRECT )
00214     {
00215         // return the rect
00216         event.SetRect(component->m_rect);
00217     }
00218     else if( type == wxEVT_IFM_GETBACKGROUNDRECT )
00219     {
00220         // get the absolute rect first
00221         wxIFMRectEvent rectevt(wxEVT_IFM_GETRECT, component);
00222         GetIP()->ProcessEvent(rectevt);
00223 
00224         // use CONVERTRECT to go from absolute to background coords
00225         wxIFMConvertRectEvent evt(component,
00226             IFM_COORDS_ABSOLUTE, IFM_COORDS_BACKGROUND, rectevt.GetRect());
00227         GetIP()->ProcessPluginEvent(evt);
00228 
00229         // return new rect
00230         event.SetRect(evt.GetRect());
00231     }
00232     else if( type == wxEVT_IFM_GETCLIENTRECT )
00233     {
00234         // get the absolute rect first
00235         wxIFMRectEvent rectevt(wxEVT_IFM_GETRECT, component);
00236         GetIP()->ProcessEvent(rectevt);
00237 
00238         // use CONVERTRECT to go from absolute to client coords
00239         wxIFMConvertRectEvent evt(component,
00240             IFM_COORDS_ABSOLUTE, IFM_COORDS_CLIENT, rectevt.GetRect());
00241         GetIP()->ProcessPluginEvent(evt);
00242 
00243         // return new rect
00244         event.SetRect(evt.GetRect());
00245     }
00246 #ifdef __WXDEBUG__
00247     else
00248         wxFAIL_MSG(wxT("Unknown event type encountered"));
00249 #endif
00250 }
00251 
00252 void wxIFMDefaultPlugin::OnConvertRect(wxIFMConvertRectEvent &event)
00253 {
00254     wxIFMComponent *component = event.GetComponent();
00255 
00256     int source = event.GetSourceCoords(), dest = event.GetDestinationCoords();
00257 
00258     // make sure we don't try to convert to the same type
00259     if( source == dest )
00260         return;
00261 
00262     if( source == IFM_COORDS_CLIENT && dest == IFM_COORDS_FLOATINGWINDOW )
00263     {
00264         // use events to go from client -> background -> absolute -> floatingwindow
00265 
00266         // to absolute
00267         wxIFMConvertRectEvent toabsevt(component,
00268             IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, event.GetRect());
00269         GetIP()->ProcessPluginEvent(toabsevt);
00270 
00271         // to floatingwindow
00272         wxIFMConvertRectEvent tofwevt(component,
00273             IFM_COORDS_ABSOLUTE, IFM_COORDS_FLOATINGWINDOW, toabsevt.GetRect());
00274         GetIP()->ProcessPluginEvent(tofwevt);
00275 
00276         // return new rect
00277         event.SetRect(tofwevt.GetRect());
00278     }
00279     if( source == IFM_COORDS_BACKGROUND && dest == IFM_COORDS_FLOATINGWINDOW )
00280     {
00281         // use events to go from background -> absolute -> floatingwindow
00282 
00283         // to absolute
00284         wxIFMConvertRectEvent toabsevt(component,
00285             IFM_COORDS_BACKGROUND, IFM_COORDS_ABSOLUTE, event.GetRect());
00286         GetIP()->ProcessPluginEvent(toabsevt);
00287 
00288         // to floatingwindow
00289         wxIFMConvertRectEvent tofwevt(component,
00290             IFM_COORDS_ABSOLUTE, IFM_COORDS_FLOATINGWINDOW, toabsevt.GetRect());
00291         GetIP()->ProcessPluginEvent(tofwevt);
00292 
00293         // return new rect
00294         event.SetRect(tofwevt.GetRect());
00295     }
00296     else if( source == IFM_COORDS_CLIENT && dest == IFM_COORDS_ABSOLUTE )
00297     {
00298         // use events to go from client -> background -> absolute
00299 
00300         // to background
00301         wxIFMConvertRectEvent tobgevt(component,
00302             IFM_COORDS_CLIENT, IFM_COORDS_BACKGROUND, event.GetRect());
00303         GetIP()->ProcessPluginEvent(tobgevt);
00304 
00305         // to absolute
00306         wxIFMConvertRectEvent toabsevt(component,
00307             IFM_COORDS_BACKGROUND, IFM_COORDS_ABSOLUTE, tobgevt.GetRect());
00308         GetIP()->ProcessPluginEvent(toabsevt);
00309 
00310         // return new rect
00311         event.SetRect(toabsevt.GetRect());
00312     }
00313     else if( source == IFM_COORDS_CLIENT && dest == IFM_COORDS_BACKGROUND )
00314     {
00315         // calculate new rect
00316         wxRect rect = event.GetRect();
00317 
00318         // account for padding
00319         rect.height += component->m_margins.top + component->m_margins.bottom;
00320         rect.width += component->m_margins.left + component->m_margins.right;
00321         rect.y -= component->m_margins.top;
00322         rect.x -= component->m_margins.left;
00323 
00324         // return new rect
00325         event.SetRect(rect);
00326     }
00327     else if( source == IFM_COORDS_BACKGROUND && dest == IFM_COORDS_ABSOLUTE )
00328     {
00329         // calculate new rect
00330         wxRect rect = event.GetRect();
00331 
00332         // account for borders
00333         rect.height += component->m_borders.top + component->m_borders.bottom;
00334         rect.width += component->m_borders.left + component->m_borders.right;
00335         rect.y -= component->m_borders.top;
00336         rect.x -= component->m_borders.left;
00337 
00338         // return new rect
00339         event.SetRect(rect);
00340     }
00341     else if( source == IFM_COORDS_ABSOLUTE && dest == IFM_COORDS_FLOATINGWINDOW )
00342     {
00343         // calculate new rect
00344         wxRect rect = event.GetRect();
00345 
00346         wxWindow *wnd = component->GetParentWindow();
00347 
00348         int caption_height = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, wnd);
00349         if( caption_height == -1 )
00350             caption_height = IFM_DEF_CAPTION_HEIGHT;
00351 
00352         int border_width = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_X, wnd);
00353         if( border_width == -1 )
00354             border_width = IFM_DEF_FRAME_X;
00355 
00356         rect.y -= caption_height;
00357 #ifdef __WXMSW__
00358         rect.y -= wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_Y , wnd);
00359 #endif
00360         rect.x -= border_width;
00361 
00362         // assume borders are the same width
00363         rect.width += border_width;
00364         rect.height += border_width;
00365 
00366         // return new rect
00367         event.SetRect(rect);
00368     }
00369 
00370     else if( source == IFM_COORDS_FLOATINGWINDOW && dest == IFM_COORDS_CLIENT )
00371     {
00372         // use events to go from floatingwindow -> absolute -> background -> client
00373 
00374         // to absolute
00375         wxIFMConvertRectEvent toabsevt(component,
00376             IFM_COORDS_FLOATINGWINDOW, IFM_COORDS_ABSOLUTE, event.GetRect());
00377         GetIP()->ProcessPluginEvent(toabsevt);
00378 
00379         // to client
00380         wxIFMConvertRectEvent tocltevt(component,
00381             IFM_COORDS_ABSOLUTE, IFM_COORDS_CLIENT, toabsevt.GetRect());
00382         GetIP()->ProcessPluginEvent(tocltevt);
00383 
00384         // return new rect
00385         event.SetRect(tocltevt.GetRect());
00386     }
00387     else if( source == IFM_COORDS_FLOATINGWINDOW && dest == IFM_COORDS_BACKGROUND )
00388     {
00389         // use events to go from floatingwindow -> absolute -> background
00390 
00391         // to absolute
00392         wxIFMConvertRectEvent toabsevt(component,
00393             IFM_COORDS_FLOATINGWINDOW, IFM_COORDS_ABSOLUTE, event.GetRect());
00394         GetIP()->ProcessPluginEvent(toabsevt);
00395 
00396         // to background
00397         wxIFMConvertRectEvent tobgevt(component,
00398             IFM_COORDS_ABSOLUTE, IFM_COORDS_BACKGROUND, toabsevt.GetRect());
00399         GetIP()->ProcessPluginEvent(tobgevt);
00400 
00401         // return new rect
00402         event.SetRect(tobgevt.GetRect());
00403     }
00404     else if( source == IFM_COORDS_ABSOLUTE && dest == IFM_COORDS_CLIENT )
00405     {
00406         // use events to go from absolute -> background -> client
00407 
00408         // to background
00409         wxIFMConvertRectEvent tobgevt(component,
00410             IFM_COORDS_ABSOLUTE, IFM_COORDS_BACKGROUND, event.GetRect());
00411         GetIP()->ProcessPluginEvent(tobgevt);
00412 
00413         // to client
00414         wxIFMConvertRectEvent tocltevt(component,
00415             IFM_COORDS_BACKGROUND, IFM_COORDS_CLIENT, tobgevt.GetRect());
00416         GetIP()->ProcessPluginEvent(tocltevt);
00417 
00418         // return new rect
00419         event.SetRect(tocltevt.GetRect());
00420     }
00421     else if( source == IFM_COORDS_ABSOLUTE && dest == IFM_COORDS_BACKGROUND )
00422     {
00423         // calculate new rect
00424         wxRect rect = event.GetRect();
00425 
00426         // account for borders
00427         rect.height -= component->m_borders.top + component->m_borders.bottom;
00428         rect.width -= component->m_borders.left + component->m_borders.right;
00429         rect.y += component->m_borders.top;
00430         rect.x += component->m_borders.left;
00431 
00432         // return new rect
00433         event.SetRect(rect);
00434     }
00435     else if( source == IFM_COORDS_BACKGROUND && dest == IFM_COORDS_CLIENT )
00436     {
00437         // calculate new rect
00438         wxRect rect = event.GetRect();
00439 
00440         // account for padding
00441         rect.height -= component->m_margins.top + component->m_margins.bottom;
00442         rect.width -= component->m_margins.left + component->m_margins.right;
00443         rect.y += component->m_margins.top;
00444         rect.x += component->m_margins.left;
00445 
00446         // return new rect
00447         event.SetRect(rect);
00448     }
00449     else if( source == IFM_COORDS_FLOATINGWINDOW && dest == IFM_COORDS_ABSOLUTE )
00450     {
00451         // calculate new rect
00452         wxRect rect = event.GetRect();
00453 
00454         wxWindow *wnd = component->GetParentWindow();
00455 
00456         int caption_height = wxSystemSettings::GetMetric(wxSYS_CAPTION_Y, wnd);
00457         if( caption_height == -1 )
00458             caption_height = IFM_DEF_CAPTION_HEIGHT;
00459 
00460         int border_width = wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_X , wnd);
00461         if( border_width == -1 )
00462             border_width = IFM_DEF_FRAME_X;
00463 
00464         rect.y += caption_height;
00465 #ifdef __WXMSW__
00466         rect.y += wxSystemSettings::GetMetric(wxSYS_FRAMESIZE_Y , wnd);
00467 #endif
00468         rect.x += border_width;
00469 
00470         // assume borders are the same width
00471         rect.width -= border_width;
00472         rect.height -= border_width;
00473 
00474         // return new rect
00475         event.SetRect(rect);
00476     }
00477 }
00478 
00479 void wxIFMDefaultPlugin::OnHitTest(wxIFMHitTestEvent &event)
00480 {
00481     int coords = event.GetCoords();
00482     wxIFMComponent *component = event.GetComponent();
00483 
00484     if( component->m_hidden )
00485         return;
00486 
00487     wxRect rect;
00488     const wxPoint &pos = event.GetPos();
00489 
00490     switch(coords)
00491     {
00492         case IFM_COORDS_ABSOLUTE:
00493             rect = component->m_rect;
00494             break;
00495         case IFM_COORDS_BACKGROUND:
00496         {
00497             wxIFMRectEvent rectevt(wxEVT_IFM_GETBACKGROUNDRECT, component);
00498             GetIP()->ProcessPluginEvent(rectevt);
00499             rect = rectevt.GetRect();
00500             break;
00501         }
00502         case IFM_COORDS_CLIENT:
00503         {
00504             wxIFMRectEvent rectevt(wxEVT_IFM_GETCLIENTRECT, component);
00505             GetIP()->ProcessPluginEvent(rectevt);
00506             rect = rectevt.GetRect();
00507             break;
00508         }
00509     }
00510 
00511     if( rect.Inside(pos) )
00512         event.SetPassed();
00513 }
00514 
00515 void wxIFMDefaultPlugin::OnGetDesiredSize(wxIFMRectEvent &event)
00516 {
00517     wxIFMComponent *component = event.GetComponent();
00518 
00519     // return the desired size
00520     wxSize size = component->m_desiredSize;
00521 
00522     // never size less than our minimum
00523     // FIXME: This case should never occur, so I assert when it does
00524     if( component->m_minSize.GetHeight() > size.GetHeight() )
00525     {
00526         //wxFAIL_MSG(wxT("Desired size was smaller than minimum!"));
00527         size.SetHeight(component->m_minSize.GetHeight());
00528     }
00529     if( component->m_minSize.GetWidth() > size.GetWidth() )
00530     {
00531         //wxFAIL_MSG(wxT("Desired size was smaller than minimum!"));
00532         size.SetWidth(component->m_minSize.GetWidth());
00533     }
00534 
00535     // desired sizes are stored in client coords, but absolute coords must be returned
00536     wxIFMConvertRectEvent evt(component, IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, wxPoint(0,0), size);
00537     GetIP()->ProcessPluginEvent(evt);
00538 
00539     event.SetSize(evt.GetSize());
00540 }
00541 
00542 void wxIFMDefaultPlugin::OnSetDesiredSize(wxIFMRectEvent &event)
00543 {
00544     wxIFMComponent *component = event.GetComponent();
00545 
00546     wxASSERT_MSG(component, wxT("NULL component?"));
00547     if( !component )
00548         return;
00549 
00550     wxSize size = event.GetSize();
00551 
00552     // handle existing values
00553     if( size.GetWidth() == IFM_USE_CURRENT_VALUE )
00554         size.SetWidth(component->m_desiredSize.GetWidth());
00555     if( size.GetHeight() == IFM_USE_CURRENT_VALUE )
00556         size.SetHeight(component->m_desiredSize.GetHeight());
00557 
00558     // dont size below minimum or bigger than maximum sizes
00559     wxIFMRectEvent minevt(wxEVT_IFM_GETMINSIZE, component);
00560     GetIP()->ProcessPluginEvent(minevt);
00561     const wxSize &minsize = minevt.GetSize();
00562 
00563     if( size.x < minsize.x )
00564         size.x = minsize.x;
00565     if( size.y < minsize.y )
00566         size.y = minsize.y;
00567 
00568     wxIFMRectEvent maxevt(wxEVT_IFM_GETMAXSIZE, component);
00569     GetIP()->ProcessPluginEvent(maxevt);
00570     const wxSize &maxsize = maxevt.GetSize();
00571 
00572     if( size.x > maxsize.x && maxsize.x != IFM_NO_MAXIMUM )
00573         size.x = maxsize.x;
00574     if( size.y > maxsize.y && maxsize.y != IFM_NO_MAXIMUM )
00575         size.y = maxsize.y;
00576 
00577     // desired sizes are set in absolute coords but stored in client coords
00578     wxIFMConvertRectEvent cvtevt(component, IFM_COORDS_ABSOLUTE, IFM_COORDS_CLIENT, wxPoint(0,0), size);
00579     GetIP()->ProcessPluginEvent(cvtevt);
00580     size = cvtevt.GetSize();
00581 
00582     component->m_desiredSize = size;
00583 
00584     // set desired floating size if possible
00585 #if IFM_CANFLOAT
00586     wxIFMFloatingData *data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00587     data->m_rect.SetSize(size);
00588 #endif
00589 }
00590 
00591 void wxIFMDefaultPlugin::OnDock(wxIFMDockEvent &event)
00592 {
00593     wxIFMComponent *component = event.GetComponent();
00594     wxASSERT_MSG(!component->m_docked, wxT("Component already docked!"));
00595 
00596     wxIFMComponent *destination = event.GetDestination();
00597 
00598     wxASSERT_MSG(component != destination, wxT("Docking a component into itself?"));
00599     if( component == destination )
00600         return;
00601 
00602     component->m_docked = true;
00603     component->m_parent = destination;
00604 
00605 #if IFM_CANFLOAT
00606     wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(destination, wxIFMFloatingData);
00607 
00608     // let the component know if it is floating now
00609     wxIFMFloatNotifyEvent notifyevt(component, floating_data->m_floating, floating_data->m_window);
00610     GetIP()->ProcessPluginEvent(notifyevt);
00611 #endif
00612 
00613     int index = event.GetIndex(), count = destination->m_children.size() - 1;
00614 
00615     wxASSERT_MSG(component, wxT("Docking a null component?"));
00616     wxASSERT_MSG(destination, wxT("Null destination component?"));
00617 
00618     if( index == IFM_DEFAULT_INDEX || index > count )
00619     {
00620         // add it after existing components
00621         destination->m_children.push_back(component);
00622     }
00623     else //if( index >= 0 )
00624     {
00625         // add it where it wants to be
00626         destination->m_children.insert(destination->m_children.begin() + index, component);
00627     }
00628 }
00629 
00630 void wxIFMDefaultPlugin::OnUpdate(wxIFMUpdateComponentEvent &event)
00631 {
00632     wxIFMComponent *component = event.GetComponent();
00633 
00634     wxASSERT_MSG(component, wxT("NULL component?"));
00635     if( !component )
00636         return;
00637 
00638     // invalidate the current (old)position
00639     component->GetParentWindow()->RefreshRect(component->m_rect);
00640 
00641     // size and position the component
00642     wxIFMRectEvent rectevt(wxEVT_IFM_SETRECT, component, event.GetRect());
00643     GetIP()->ProcessPluginEvent(rectevt);
00644 
00645     // invalidate the current (new) position
00646     component->GetParentWindow()->RefreshRect(component->m_rect);
00647 
00648     // if this component is the root component of a floating window, set the floating windows size hints here
00649 #if IFM_CANFLOAT
00650     wxIFMFloatingData *data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00651     if( data && data->m_floating && !component->m_docked )
00652     {
00653         wxSize min = component->GetMinSize();
00654 
00655         // absolute to floating window coords
00656         wxIFMConvertRectEvent cvtevt(component, IFM_COORDS_ABSOLUTE, IFM_COORDS_FLOATINGWINDOW, wxPoint(0,0), min);
00657         GetIP()->ProcessEvent(cvtevt);
00658         const wxRect &rect = cvtevt.GetRect();
00659         const wxSize min2(rect.width - rect.x, rect.height - rect.y);
00660 
00661         data->m_window->GetWindow()->SetSizeHints(min2.x, min2.y);
00662 
00663         // if the window is currently too small for the minimum size, make it bigger
00664         wxSize size = data->m_window->GetWindow()->GetClientSize();
00665         if( size.x < min.x || size.y < min.y )
00666         {
00667             if( size.x < min.x )
00668                 size.x = min.x;
00669             if( size.y < min.y )
00670                 size.y = min.y;
00671 
00672             data->m_window->GetWindow()->SetClientSize(size);
00673         }
00674     }
00675 #endif
00676 }
00677 
00678 
00679 void wxIFMDefaultPlugin::OnBeginPaint(wxIFMBeginPaintEvent &event)
00680 {
00681     wxDC *dc;
00682 
00683     // create a dc
00684     if( event.GetOnPaint() )
00685         dc = new wxBufferedPaintDC(event.GetWindow());
00686     else
00687         dc = new wxClientDC(event.GetWindow());
00688 
00689     event.SetDC(dc);
00690 }
00691 
00692 void wxIFMDefaultPlugin::OnEndPaint(wxIFMEndPaintEvent &event)
00693 {
00694     // delete the dc
00695     delete event.GetDC();
00696 }
00697 
00698 void wxIFMDefaultPlugin::OnPaintBg(wxIFMPaintEvent &event)
00699 {
00700     wxIFMComponent *component = event.GetComponent();
00701 
00702     // don't need to paint if we arent visible
00703     if( !component->IsVisible() )
00704         return;
00705 
00706     // get background rect first, as the rect provided in the wxIFMPaintEvent
00707     // is the rect that needs painting, not the background rect
00708     wxIFMRectEvent rectevt(wxEVT_IFM_GETBACKGROUNDRECT, component);
00709     GetIP()->ProcessPluginEvent(rectevt);
00710     wxRect bgrect = rectevt.GetRect();
00711 
00712     // paint normal bg
00714     wxBrush brush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
00715     wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
00716     wxDC &dc = event.GetDC();
00717 
00718     dc.SetBrush(brush);
00719     dc.SetPen(pen);
00720 
00721     dc.BeginDrawing();
00722     dc.DrawRectangle(bgrect);
00723     dc.EndDrawing();
00724 
00725     dc.SetPen(wxNullPen);
00726     dc.SetBrush(wxNullBrush);
00727 }
00728 
00729 void wxIFMDefaultPlugin::OnPaintBorder(wxIFMPaintEvent &event)
00730 {
00731     wxIFMComponent *component = event.GetComponent();
00732 
00733     // don't need to paint if we arent visible
00734     if( !component->IsVisible() )
00735         return;
00736 
00737     // get background rect to draw borders around
00738     wxIFMRectEvent rectevt(wxEVT_IFM_GETBACKGROUNDRECT, component);
00739     GetIP()->ProcessPluginEvent(rectevt);
00740 
00741     // get border rect
00742     wxRect rect = rectevt.GetRect();
00743 
00744     rect.y--;
00745     rect.x--;
00746     rect.width++;
00747     rect.height++;
00748 
00750     //wxPen pen_light(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT));
00751     //wxPen pen_dark(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
00752     wxPen border_pen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW));
00753     wxDC &dc = event.GetDC();
00754 
00755     // paint borders
00756     // top
00757     if( component->m_borders.top )
00758     {
00759         border_pen.SetWidth(component->m_borders.top);
00760         dc.SetPen(border_pen);
00761         dc.DrawLine(rect.x, rect.y, rect.x + rect.width, rect.y);
00762     }
00763 
00764     // left
00765     if( component->m_borders.left )
00766     {
00767         border_pen.SetWidth(component->m_borders.left);
00768         dc.SetPen(border_pen);
00769         dc.DrawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
00770     }
00771 
00772     // right
00773     if( component->m_borders.right )
00774     {
00775         border_pen.SetWidth(component->m_borders.right);
00776         dc.SetPen(border_pen);
00777         dc.DrawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height + 1);
00778     }
00779 
00780     // bottom
00781     if( component->m_borders.bottom )
00782     {
00783         border_pen.SetWidth(component->m_borders.bottom);
00784         dc.SetPen(border_pen);
00785         dc.DrawLine(rect.x, rect.y + rect.height, rect.x + rect.width + 1, rect.y + rect.height);
00786     }
00787 }
00788 
00789 void wxIFMDefaultPlugin::OnUndock(wxIFMUndockEvent &event)
00790 {
00791     wxIFMComponent *component = event.GetComponent();
00792     wxIFMComponent *parent = component->m_parent;
00793     wxASSERT_MSG(parent, wxT("Undocking a component with a null parent?"));
00794 
00795     // find the child within its parent's children list and remove it
00796     wxIFMComponentArray &children = parent->m_children;
00797     //for( int i = 0, count = parent->m_children.GetCount(); i < count; ++i )
00798     for( wxIFMComponentArray::iterator i = children.begin(), end = children.end(); i != end; ++i )
00799     {
00800         //if( children[i] == component )
00801         if( *i == component )
00802         {
00803             //children.RemoveAt(i);
00804             children.erase(i);
00805             break;
00806         }
00807     }
00808 
00809     // delete the parent if necessary
00810     if( event.GetDelete() && parent->m_children.GetCount() == 0 )
00811     {
00812 #if IFM_CANFLOAT
00813         wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(parent, wxIFMFloatingData);
00814 #endif
00815         // undock the parent from its parent first
00816         if( parent->m_docked )
00817         {
00818             wxIFMUndockEvent evt(parent);
00819             GetIP()->ProcessPluginEvent(evt);
00820         }
00821 #if IFM_CANFLOAT
00822         else if( floating_data->m_floating )
00823         {
00824             // if a component is not docked but is floating, that means its the root level component
00825             // of a floating window. It has no children left, so destroy the floating window.
00826             wxIFMDestroyFloatingWindowEvent evt(floating_data->m_window, true);
00827             GetIP()->AddPendingEvent(evt);
00828         }
00829 
00830         if( !floating_data->m_floating )
00831 #endif
00832         {
00833             wxIFMDeleteComponentEvent delevt(parent);
00834             GetIP()->ProcessPluginEvent(delevt);
00835         }
00836     }
00837 
00838     component->m_docked = false;
00839     component->m_parent = NULL;
00840 }
00841 
00842 void wxIFMDefaultPlugin::OnDeleteComponent(wxIFMDeleteComponentEvent &event)
00843 {
00844     wxIFMComponent *component = event.GetComponent();
00845 
00846     // undock ourselves if we are still docked
00847     if( component->m_docked )
00848     {
00849         wxIFMUndockEvent evt(component);
00850         GetIP()->ProcessPluginEvent(evt);
00851     }
00852 
00853     // delete any children first
00854     wxIFMComponentArray &children = component->m_children;
00855     for( size_t i = 0; i < children.GetCount(); i++ )
00856     //for( wxIFMComponentArray::iterator i = children.begin(), end = children.end(); i != end; ++i )
00857     {
00858         wxIFMDeleteComponentEvent evt(children[i]);
00859         GetIP()->ProcessPluginEvent(evt);
00860     }
00861 }
00862 
00863 void wxIFMDefaultPlugin::OnSetChildSize(wxIFMSetChildSizeEvent &event)
00864 {
00865     wxIFMComponent *component = event.GetComponent();
00866 
00867     wxCHECK_RET(component, wxT("Setting the size of a child not managed by this interface"));
00868 
00869     wxSize size;
00870 
00871     // min size
00872     size = event.GetMinSize();
00873     if( size.GetWidth() == IFM_USE_CURRENT_VALUE )
00874         size.SetWidth(component->m_minSize.GetWidth());
00875     if( size.GetHeight() == IFM_USE_CURRENT_VALUE )
00876         size.SetHeight(component->m_minSize.GetHeight());
00877     component->m_minSize = size;
00878 
00879     // max size
00880     size = event.GetMinSize();
00881     if( size.GetWidth() == IFM_USE_CURRENT_VALUE )
00882         size.SetWidth(component->m_maxSize.GetWidth());
00883     if( size.GetHeight() == IFM_USE_CURRENT_VALUE )
00884         size.SetHeight(component->m_maxSize.GetHeight());
00885     component->m_maxSize = size;
00886 
00887     // desired size
00888     size = event.GetMinSize();
00889     if( size.GetWidth() == IFM_USE_CURRENT_VALUE )
00890         size.SetWidth(component->m_desiredSize.GetWidth());
00891     if( size.GetHeight() == IFM_USE_CURRENT_VALUE )
00892         size.SetHeight(component->m_desiredSize.GetHeight());
00893     component->m_desiredSize = size;
00894 
00895     if( event.GetUpdate() )
00896     {
00897 #if IFM_CANFLOAT
00898         wxIFMFloatingData *data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00899         if( data->m_floating )
00900             data->m_window->Update();
00901         else
00902 #endif
00903             GetManager()->Update();
00904     }
00905 }
00906 
00907 void wxIFMDefaultPlugin::OnSetMinSize(wxIFMRectEvent &event)
00908 {
00909 
00910 }
00911 
00912 void wxIFMDefaultPlugin::OnSetMaxSize(wxIFMRectEvent &event)
00913 {
00914 
00915 }
00916 
00917 void wxIFMDefaultPlugin::OnGetMinSize(wxIFMRectEvent &event)
00918 {
00919     wxIFMComponent *component = event.GetComponent();
00920 
00921     wxASSERT_MSG(component, wxT("NULL component?"));
00922     if( !component )
00923         return;
00924 
00925     wxSize size;
00926 
00927     // query the child for our min size if applicable
00928     if( component->m_minSize == IFM_USE_CHILD_MINSIZE )
00929     {
00930         if( component->m_child )
00931         {
00932             size = component->m_child->GetBestSize();
00933         }
00934     }
00935     else
00936     {
00937         // return cummulative minimum size of this window and all children
00938         // in absolute coordinates
00939         wxSize min_size, child_size;
00940         wxIFMComponent *child;
00941         const wxIFMComponentArray &children = component->m_children;
00942         for( size_t i = 0; i < children.GetCount(); i++ )
00943         //for( wxIFMComponentArray::const_iterator i = children.begin(), end = children.end(); i != end; ++i )
00944         {
00945             child = children[i];
00946 
00947             wxIFMRectEvent minevt(wxEVT_IFM_GETMINSIZE, child);
00948             GetIP()->ProcessPluginEvent(minevt);
00949             child_size = minevt.GetSize();
00950 
00951             if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
00952             {
00953                 min_size.x += child_size.x;
00954                 if( child_size.y > min_size.y )
00955                     min_size.y = child_size.y;
00956             }
00957             else if( component->m_alignment == IFM_ALIGN_VERTICAL )
00958             {
00959                 min_size.y += child_size.y;
00960                 if( child_size.x > min_size.x )
00961                     min_size.x = child_size.x;
00962             }
00963         }
00964 
00965         // account for our min sizes too
00966         child_size = component->m_minSize;
00967         if( child_size.x >= min_size.x )
00968             min_size.x = child_size.x;
00969         if( child_size.y >= min_size.y )
00970             min_size.y = child_size.y;
00971 
00972         size = min_size;
00973     }
00974 
00975     // client to absolute
00976     wxSize converted_min = component->GetConvertedRect(wxRect(wxPoint(), size), IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE).GetSize();
00977     if( size.x != IFM_NO_MINIMUM )
00978         size.x = converted_min.x;
00979     if( size.y != IFM_NO_MINIMUM )
00980         size.y = converted_min.y;
00981 
00982     event.SetSize(size);
00983 }
00984 
00985 void wxIFMDefaultPlugin::OnGetMaxSize(wxIFMRectEvent &event)
00986 {
00987     wxIFMComponent *component = event.GetComponent();
00988 
00989     wxASSERT_MSG(component, wxT("NULL component?"));
00990     if( !component )
00991         return;
00992 
00993     // dont use this for now, it doesn't really work anyway
00994 #if 0
00995     // if any child has a max size of IFM_NO_MAXIMUM_SIZE, there is no max size for the children
00996     // and we immediatley return with this components max size
00997     // if all children have a specified max size, return the cummulative total
00998     wxSize max_size, size;
00999     wxIFMComponent *child;
01000     const wxIFMComponentArray &children = component->m_children;
01001     for( wxIFMComponentArray::const_iterator i = children.begin(), end = children.end(); i != end; ++i )
01002     {
01003         child = *i;
01004 
01005         wxIFMRectEvent maxevt(wxEVT_IFM_GETMAXSIZE, child);
01006         GetIP()->ProcessPluginEvent(maxevt);
01007         size = maxevt.GetSize();
01008 
01009         if( size == IFM_NO_MAXIMUM_SIZE )
01010         {
01011             event.SetSize(component->m_maxSize);
01012             return;
01013         }
01014         else
01015         {
01016             if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01017             {
01018                 max_size.x += size.x;
01019                 if( size.y < max_size.y )
01020                     max_size.y = size.y;
01021             }
01022             else if( component->m_alignment == IFM_ALIGN_VERTICAL )
01023             {
01024                 max_size.y += size.y;
01025                 if( size.x < max_size.x )
01026                     max_size.x = size.x;
01027             }
01028         }
01029     }
01030 #endif
01031 
01032     // client to absolute
01033     wxSize size = component->m_maxSize;
01034     if( size != IFM_NO_MAXIMUM_SIZE )
01035     {
01036         wxIFMConvertRectEvent cvtevt(component, IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, wxPoint(), size);
01037         GetIP()->ProcessPluginEvent(cvtevt);
01038         size = cvtevt.GetSize();
01039     }
01040     event.SetSize(size);
01041 }
01042 
01043 void wxIFMDefaultPlugin::OnCalcRects(wxIFMCalcRectsEvent &event)
01044 {
01045     wxIFMComponent *component = event.GetComponent();
01046     wxASSERT_MSG(component, wxT("NULL component?"));
01047     if( !component )
01048         return;
01049 
01050     // retrieve and store all calculated sizes for visible components
01051     const wxIFMComponentArray &children = event.GetComponents();
01052     int numchildren = children.size(), current = wxIFMComponent::GetNextVisibleComponent(children, 0);
01053     wxRectArray children_rects = event.GetComponentRects();
01054     const wxSizeArray &children_minSize = event.GetMinSizes();
01055     const wxSizeArray &children_maxSize = event.GetMaxSizes();
01056 
01057     bool *children_done_sizing = new bool[numchildren];
01058     memset(children_done_sizing, false, sizeof(bool) * numchildren);
01059 
01060     bool again = false;
01061 
01062     const wxRect &clientrect = event.GetRect();
01063 
01064     int available = 0;
01065     if( component->m_alignment == IFM_ALIGN_VERTICAL )
01066         available = clientrect.height;
01067     else if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01068         available = clientrect.width;
01069 
01070     do
01071     {
01072         again = false;
01073         wxRect children_combined_rect;
01074 
01075         for( current = 0; current < numchildren; current++ )
01076         {
01077             if( children[current]->m_hidden )
01078                 continue;
01079 
01080             // keep track of sizes
01081             if( !children_done_sizing[current] )
01082             {
01083                 children_combined_rect.width += children_rects[current].width;
01084                 children_combined_rect.height += children_rects[current].height;
01085             }
01086         }
01087 
01088         // expand or shrink children to fit the client area
01089         float scale_factor = 0;
01090         if( component->m_alignment == IFM_ALIGN_VERTICAL )
01091             scale_factor = available / (float)children_combined_rect.height;
01092         else if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01093             scale_factor = available / (float)children_combined_rect.width;
01094 
01095         // calculate component sizes
01096         for( int i = 0; i < numchildren; ++i )
01097         {
01098             if( children[i]->m_hidden )
01099                 continue;
01100 
01101             int *scaled = 0;
01102             int min = 0, max = 0;
01103             int actual = 0;
01104 
01105             if( component->m_alignment == IFM_ALIGN_VERTICAL )
01106             {
01107                 scaled = &children_rects[i].height;
01108                 children_rects[i].width = clientrect.width;
01109 
01110                 min = children_minSize[i].GetHeight();
01111                 max = children_maxSize[i].GetHeight();
01112             }
01113             else if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01114             {
01115                 scaled = &children_rects[i].width;
01116                 children_rects[i].height = clientrect.height;
01117 
01118                 min = children_minSize[i].GetWidth();
01119                 max = children_maxSize[i].GetWidth();
01120             }
01121 
01122             if( !children_done_sizing[i] )
01123             {
01124                 actual = (int)(*scaled * scale_factor);
01125 
01126                 if( actual < min )
01127                 {
01128                     children_done_sizing[i] = true;
01129                     *scaled = min;
01130                     available -= min;
01131                     again = true;
01132                 }
01133                 else if( actual > max && max != IFM_NO_MAXIMUM )
01134                 {
01135                     children_done_sizing[i] = true;
01136                     *scaled = max;
01137                     available -= max;
01138                     again = true;
01139                 }
01140                 else
01141                     *scaled = actual;
01142             }
01143         }
01144 
01145     } while(again);
01146 
01147 
01148     wxPoint pos = clientrect.GetPosition();
01149 
01150     // position visible children
01151     for( int i = 0; i < numchildren; ++i )
01152     {
01153         if( children[i]->m_hidden )
01154                 continue;
01155 
01156         children_rects[i].y = pos.y;
01157         children_rects[i].x = pos.x;
01158 
01160         if( i + 1 == numchildren )
01161         {
01162             int *scaled = 0, actual = 0, max = 0;
01163             if( component->m_alignment == IFM_ALIGN_VERTICAL )
01164             {
01165                 actual = clientrect.height - pos.y + clientrect.y;
01166                 max = children_maxSize[i].GetHeight();
01167                 scaled = &children_rects[i].height;
01168 
01169             }
01170             else if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01171             {
01172                 scaled = &children_rects[i].width;
01173                 actual = clientrect.width - pos.x + clientrect.x;
01174                 max = children_maxSize[i].GetWidth();
01175             }
01176 
01177             if( actual > max && max != IFM_NO_MAXIMUM )
01178                 actual = max;
01179             *scaled = actual;
01180         }
01181         else
01182         {
01183             if( component->m_alignment == IFM_ALIGN_VERTICAL )
01184                 pos.y += children_rects[i].height;
01185             else if( component->m_alignment == IFM_ALIGN_HORIZONTAL )
01186                 pos.x += children_rects[i].width;
01187         }
01188 
01189         // return the calculated rect with the event
01190         event.SetComponentRect(i, children_rects[i]);
01191     }
01192 
01193     delete[] children_done_sizing;
01194 }
01195 
01196 void wxIFMDefaultPlugin::OnShowChild(wxIFMShowChildEvent &event)
01197 {
01198     wxIFMComponent *component = event.GetComponent();
01199 
01200     wxASSERT_MSG(component, wxT("NULL component?"));
01201     if( !component )
01202         return;
01203 
01204     component->Show(event.GetShow(), event.GetUpdate());
01205 }
01206 
01207 void wxIFMDefaultPlugin::OnShowComponent(wxIFMShowComponentEvent &event)
01208 {
01209     wxIFMComponent *component = event.GetComponent();
01210 
01211     wxASSERT_MSG(component, wxT("NULL component?"));
01212     if( !component )
01213         return;
01214 
01215     bool show = event.GetShow();
01216 
01217     // ensure all parents are visible
01218     // !\todo This is kind of inneficient, each parent will check its parents who check their parents...
01219     if( show )
01220     {
01221         for( wxIFMComponent *parent = component->m_parent; parent; parent = parent->m_parent )
01222         {
01223             if( !parent->IsShown() )
01224                 parent->Show(true, event.GetUpdate());
01225         }
01226     }
01227 
01228     component->VisibilityChanged(event.GetShow());
01229 
01230     if( event.GetUpdate() )
01231         GetIP()->GetManager()->AddPendingUpdate(IFM_DEFAULT_RECT, true);
01232 }
01233 
01234 void wxIFMDefaultPlugin::OnVisibilityChanged(wxIFMComponentVisibilityChangedEvent &event)
01235 {
01236     wxIFMComponent *component = event.GetComponent();
01237 
01238     wxASSERT_MSG(component, wxT("NULL component?"));
01239     if( !component )
01240         return;
01241 
01242     bool show = event.GetShow();
01243 
01244     // send visibility change notifications to our children who need them
01245     const wxIFMComponentArray &components = component->m_children;
01246     for( size_t i = 0; i < components.GetCount(); i++ )
01247     //for( wxIFMComponentArray::const_iterator i = components.begin(), end = components.end(); i != end; ++i )
01248     {
01249         wxIFMComponent *child = components[i];
01250         if( child->IsShown() && (child->IsVisible() != show) )
01251             child->VisibilityChanged(show);
01252     }
01253 }
01254 
01255 #if IFM_CANFLOAT
01256 
01257 void wxIFMDefaultPlugin::OnFloat(wxIFMFloatEvent &event)
01258 {
01259     wxIFMComponent *component = event.GetComponent();
01260 
01261     // undock if we are docked already
01262     if( component->m_docked )
01263     {
01264         wxIFMUndockEvent evt(component, true);
01265         GetIP()->ProcessPluginEvent(evt);
01266     }
01267 
01268     // create a window with which to float
01269     wxIFMCreateFloatingWindowEvent wndevt(GetManager()->GetParent(), component);
01270     GetIP()->ProcessPluginEvent(wndevt);
01271 
01272     wxIFMFloatingWindowBase *base = wndevt.GetWindow();
01273     wxASSERT_MSG(base, wxT("NULL window returned by CreateFloatingWindow event!"));
01274 
01275     // size and position the window
01276     wxPoint pos = event.GetPosition();
01277     wxSize size = event.GetSize();
01278 
01279     // if default rect is specified, use desired size and mouse position
01280     if( size == IFM_DEFAULT_RECT.GetSize() )
01281     {
01282         wxIFMRectEvent evt(wxEVT_IFM_GETDESIREDSIZE, component);
01283         GetIP()->ProcessPluginEvent(evt);
01284         size = evt.GetSize();
01285     }
01286 
01287     // the size requested is in component client coordinants, convert to absolute first
01288     wxIFMConvertRectEvent cvtevt(component, IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, wxPoint(), size);
01289     GetIP()->ProcessPluginEvent(cvtevt);
01290     size = cvtevt.GetSize();
01291 
01292     // make sure there is enough room in the root component to compensate for the size of the component
01293     // being floated. Don't do this if the component ended up being the root component, though
01294     if( base->m_component != component )
01295     {
01296         wxIFMConvertRectEvent cvtevt2(base->m_component, IFM_COORDS_CLIENT, IFM_COORDS_ABSOLUTE, wxPoint(), size);
01297         GetIP()->ProcessPluginEvent(cvtevt2);
01298         size = cvtevt2.GetSize();
01299     }
01300 
01301     wxSize display_size = wxGetDisplaySize();
01302 
01303     // hide the root component to make sure it doesnt display the frame before we are ready
01305     base->m_component->m_hidden = true;
01306 
01307     base->GetWindow()->SetClientSize(size);
01308     size = base->GetWindow()->GetSize();
01309 
01310     // use mouse position now if needed as at this point we have an accurate size
01311     if( pos == IFM_DEFAULT_RECT.GetPosition() )
01312     {
01313         pos = ::wxGetMousePosition();
01314         pos.x -= size.GetWidth() / 2;
01315 
01316         wxIFMConvertRectEvent cvtevt(base->m_component, IFM_COORDS_FLOATINGWINDOW, IFM_COORDS_ABSOLUTE, pos, size);
01317         GetIP()->ProcessPluginEvent(cvtevt);
01318         const wxPoint &pos2 = cvtevt.GetPosition();
01319 
01320         pos.x = pos2.x;
01321         pos.y -= (pos.y - pos2.y) / 2;
01322     }
01323 
01324     // convert from absolute coords of the root component into floating coords to position and size the
01325     // floating window
01326     wxIFMConvertRectEvent cvtevt3(base->m_component, IFM_COORDS_ABSOLUTE, IFM_COORDS_FLOATINGWINDOW, pos, size);
01327     GetIP()->ProcessPluginEvent(cvtevt3);
01328 
01330     pos = cvtevt3.GetPosition();
01331     size = cvtevt3.GetSize();
01332 
01333     {
01334         // dont position the window off screen
01335         if( pos.x < 0 )
01336             pos.x = 0;
01337         if( pos.y < 0 )
01338             pos.y = 0;
01339 
01340         if( pos.x + size.GetWidth() > display_size.GetWidth() )
01341             pos.x = display_size.GetWidth() - size.GetWidth();
01342         if( pos.y + size.GetHeight() > display_size.GetHeight() )
01343             pos.y = display_size.GetHeight() - size.GetHeight();
01344     }
01345 
01346     base->GetWindow()->Move(pos);
01347 
01348     // unhide the root component
01349     base->m_component->m_hidden = false;
01350 
01351     // show the window
01352     base->GetWindow()->Show();
01353 
01354     // updating after we show the window seems to fix broken 2.5.3 release mode behavior
01355     base->Update();
01356 }
01357 
01358 void wxIFMDefaultPlugin::OnFloatingSize(wxIFMFloatingSizeEvent &event)
01359 {
01360     wxIFMFloatingWindowBase *base = event.GetWindow();
01361 
01362     const wxRect &client_rect = base->GetWindow()->GetClientRect();
01363 
01364     // set out root components desired size
01365     wxIFMRectEvent rectevt(wxEVT_IFM_SETDESIREDSIZE, base->GetComponent(), client_rect);
01366     GetIP()->ProcessPluginEvent(rectevt);
01367 
01368     // update our root component
01369     wxIFMUpdateComponentEvent updevt(base->GetComponent(), client_rect);
01370     GetIP()->ProcessPluginEvent(updevt);
01371 }
01372 
01373 void wxIFMDefaultPlugin::OnFloatingMove(wxIFMFloatingMoveEvent &event)
01374 {
01375     // update the floating position of all child windows
01376     UpdateFloatingPos(event.GetWindow()->GetComponent());
01377 }
01378 
01379 void wxIFMDefaultPlugin::UpdateFloatingPos(wxIFMComponent *component)
01380 {
01381     wxPoint pos = component->m_rect.GetPosition();
01382 
01383     wxIFMFloatingData *data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
01384 
01385     // client to screen
01386     data->m_rect.SetPosition(data->m_window->GetWindow()->ClientToScreen(pos));
01387 
01388     // child windows too
01389     const wxIFMComponentArray &children = component->m_children;
01390     for( size_t i = 0; i < children.GetCount(); i++ )
01391     //for( wxIFMComponentArray ::const_iterator i = children.begin(), end = children.end(); i != end; ++i )
01392         UpdateFloatingPos(children[i]);
01393 }
01394 
01395 void wxIFMDefaultPlugin::OnFloatNotify(wxIFMFloatNotifyEvent &event)
01396 {
01397     wxIFMComponent *component = event.GetComponent();
01398     wxIFMFloatingData *data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
01399 
01400     data->m_floating = event.GetFloating();
01401     data->m_window = event.GetWindow();
01402 
01403     // notify our children they are now floating
01404     wxIFMComponentArray &children = component->m_children;
01405     for( int i = 0, count = children.GetCount(); i < count; ++i )
01406     //for( wxIFMComponentArray::iterator i = children.begin(), end = children.end(); i != end; ++i )
01407     {
01408         wxIFMFloatNotifyEvent evt(children[i], event.GetFloating(), event.GetWindow());
01409         GetIP()->ProcessPluginEvent(evt);
01410     }
01411 }
01412 
01413 #endif // IFM_CANFLOAT

 

SourceForge Logo