MatOCAD Logo

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

dragndrop.cpp

Go to the documentation of this file.
00001 
00012 #include "../../include/wxIFM/dragndrop.h"
00013 
00014 #include "../../icons/dock_left.xpm"
00015 #include "../../icons/dock_left_mo.xpm"
00016 #include "../../icons/dock_up.xpm"
00017 #include "../../icons/dock_up_mo.xpm"
00018 #include "../../icons/dock_down.xpm"
00019 #include "../../icons/dock_down_mo.xpm"
00020 #include "../../icons/dock_right.xpm"
00021 #include "../../icons/dock_right_mo.xpm"
00022 #include "../../icons/dock_center.xpm"
00023 #include "../../icons/dock_center_mo.xpm"
00024 
00025 #include <wx/msgdlg.h>
00026 #include <wx/settings.h>
00027 
00028 // images used for rendering drop targets
00029 wxBitmap img_left, img_right, img_top, img_bottom, img_tab,
00030     img_leftHover, img_rightHover, img_topHover, img_bottomHover, img_tabHover;
00031 
00032 DEFINE_EVENT_TYPE(wxEVT_IFM_INITDRAG);
00033 DEFINE_EVENT_TYPE(wxEVT_IFM_BEGINDRAG);
00034 DEFINE_EVENT_TYPE(wxEVT_IFM_ENDDRAG);
00035 DEFINE_EVENT_TYPE(wxEVT_IFM_DRAGGING);
00036 
00037 DEFINE_EVENT_TYPE(wxEVT_IFM_SHOWDROPTARGETS);
00038 
00039 #if IFM_USE_WX_RTTI
00040 IMPLEMENT_DYNAMIC_CLASS(wxIFMDefaultDockingPlugin, wxIFMExtensionPluginBase);
00041 IMPLEMENT_DYNAMIC_CLASS(wxIFMDockEventEx, wxIFMDockEvent);
00042 #endif
00043 
00044 BEGIN_EVENT_TABLE(wxIFMDefaultDockingPlugin, wxIFMExtensionPluginBase)
00045     //EVT_IFM_LEFTDOWN    (wxIFMDefaultDockingPlugin::OnLeftDown)
00046 #if IFM_CANFLOAT
00047     EVT_IFM_LEFTDCLICK  (wxIFMDefaultDockingPlugin::OnLeftDClick)
00048 #endif
00049     EVT_IFM_LEFTUP      (wxIFMDefaultDockingPlugin::OnLeftUp)
00050     EVT_IFM_MOTION      (wxIFMDefaultDockingPlugin::OnMouseMove)
00051     EVT_IFM_KEYDOWN     (wxIFMDefaultDockingPlugin::OnKeyDown)
00052     EVT_IFM_DRAG_INIT   (wxIFMDefaultDockingPlugin::OnDragInit)
00053     EVT_IFM_DRAG_BEGIN  (wxIFMDefaultDockingPlugin::OnDragBegin)
00054     EVT_IFM_DRAG_END    (wxIFMDefaultDockingPlugin::OnDragEnd)
00055     EVT_IFM_DRAG_DRAGGING (wxIFMDefaultDockingPlugin::OnDrag)
00056     EVT_IFM_SHOWDROPTARGETS (wxIFMDefaultDockingPlugin::OnShowDropTargets)
00057     EVT_IFM_DOCK        (wxIFMDefaultDockingPlugin::OnDock)
00058 END_EVENT_TABLE()
00059 
00060 wxIFMDefaultDockingPlugin::wxIFMDefaultDockingPlugin()
00061     : wxIFMExtensionPluginBase(),
00062     m_realtime(false),
00063     m_dragging(false),
00064     m_captured(false),
00065     m_dragx(0),
00066     m_dragy(0),
00067     m_oldBtn(NULL)
00068 #if IFM_CANFLOAT
00069     ,m_window(NULL)
00070 #endif
00071 { }
00072 
00073 bool wxIFMDefaultDockingPlugin::Initialize(wxIFMInterfacePluginBase *plugin)
00074 {
00075     wxIFMExtensionPluginBase::Initialize(plugin);
00076 
00077 #if IFM_USE_WX_RTTI
00078     m_ip = wxDynamicCast(plugin, wxIFMDefaultInterfacePlugin);
00079 #else
00080     m_ip = dynamic_cast<wxIFMDefaultInterfacePlugin*>(plugin);
00081 #endif
00082 
00083     if( !m_ip )
00084     {
00085         wxMessageBox(wxT("wxIFMDefaultDockingPlugin only extends wxIFMDefaultInterfacePlugin"), wxT("Error"),
00086             wxICON_ERROR | wxOK);
00087         return false;
00088     }
00089 
00090     // initialize drop bitmaps
00091     img_left = wxBitmap(dock_left_xpm);
00092     img_leftHover = wxBitmap(dock_left_mo_xpm);
00093     img_top = wxBitmap(dock_up_xpm);
00094     img_topHover = wxBitmap(dock_up_mo_xpm);
00095     img_bottom = wxBitmap(dock_down_xpm);
00096     img_bottomHover = wxBitmap(dock_down_mo_xpm);
00097     img_right = wxBitmap(dock_right_xpm);
00098     img_rightHover = wxBitmap(dock_right_mo_xpm);
00099     img_tab = wxBitmap(dock_center_xpm);
00100     img_tabHover = wxBitmap(dock_center_mo_xpm);
00101 
00102     return true;
00103 }
00104 
00105 #if IFM_CANFLOAT
00106 void wxIFMDefaultDockingPlugin::OnLeftDClick(wxIFMMouseEvent &event)
00107 {
00108     // float the component if inside of background rect
00109     wxIFMComponent *component = event.GetComponent();
00110     const wxPoint &pos = event.GetMouseEvent().GetPosition();
00111 
00112     if( !component )
00113     {
00114         event.Skip();
00115         return;
00116     }
00117 
00118     // mouse must be within background rect to initiate floating
00119     wxIFMHitTestEvent hitevt(component, IFM_COORDS_BACKGROUND, pos);
00120     GetIP()->ProcessPluginEvent(hitevt);
00121 
00122     if( !hitevt.GetPassed() )
00123     {
00124         event.Skip();
00125         return;
00126     }
00127     else
00128     {
00129         wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00130         wxIFMFloatingWindowBase *parent = NULL;
00131         bool destroy = false;
00132 
00133         if( floating_data->m_floating )
00134         {
00135             parent = floating_data->m_window;
00136             if( !component->m_docked )
00137                 destroy = true;
00138         }
00139 
00140         wxIFMFloatEvent evt(component, floating_data->m_rect);
00141         GetIP()->ProcessPluginEvent(evt);
00142 
00143         // if we floated the root component, destroy the old window instead of updating it
00144         if( destroy )
00145         {
00146             wxIFMDestroyFloatingWindowEvent evt(parent, false);
00147             GetIP()->ProcessPluginEvent(evt);
00148         }
00149         else if( parent )
00150             parent->Update();
00151         else
00152             GetManager()->Update();
00153     }
00154 }
00155 #endif
00156 
00157 void wxIFMDefaultDockingPlugin::OnLeftDown(wxIFMMouseEvent &event)
00158 {
00159     /*
00160     wxIFMComponent *component = event.GetComponent(), *dragged = NULL;
00161     const wxPoint &pos = event.GetMouseEvent().GetPosition();
00162     bool do_drag = false;
00163 
00164     if( !component )
00165     {
00166         event.Skip();
00167         return;
00168     }
00169 
00170     // let other stuff go first
00171     GetNextHandler()->ProcessEvent(event);
00172 
00173     // mouse must be within caption rect to initiate dragging on panels
00174     if( component->GetType() == IFM_COMPONENT_PANEL )
00175     {
00176         wxIFMPanelData *data = IFM_GET_EXTENSION_DATA(component, wxIFMPanelData);
00177 
00178         wxASSERT_MSG(data, wxT("Panel with no panel data?"));
00179         if( !data )
00180             return;
00181 
00182         if( data->m_caption.Inside(pos) )
00183         {
00184             do_drag = true;
00185             dragged = component;
00186         }
00187         else
00188         {
00189             // check for individual tab hits
00190             for(wxIFMTabArray::iterator i = data->m_tabs.begin(), end = data->m_tabs.end(); i != end; ++i )
00191             {
00192                 wxIFMTab *tab = *i;
00193                 if( tab->m_rect.Inside(pos) )
00194                 {
00195                     do_drag = true;
00196                     dragged = tab->m_tab;
00197                     break;
00198                 }
00199             }
00200         }
00201     }
00202     // mouse must be within the gray bar on the left
00203     else if( component->GetType() == IFM_COMPONENT_CONTAINER )
00204     {
00205 
00206     }
00207     else
00208     {
00209         wxIFMHitTestEvent hitevt(component, IFM_COORDS_BACKGROUND, pos);
00210         GetIP()->ProcessPluginEvent(hitevt);
00211 
00212         do_drag = hitevt.GetPassed();
00213         dragged = component;
00214     }
00215 
00216     if( do_drag )
00217     {
00218         // init the drag
00219         wxIFMInitDragEvent evt(component, dragged, pos);
00220         GetIP()->ProcessPluginEvent(evt);
00221     }
00222     */
00223 }
00224 
00225 void wxIFMDefaultDockingPlugin::OnLeftUp(wxIFMMouseEvent &event)
00226 {
00227     if( m_captured )
00228     {
00229         m_captured = false;
00230         GetManager()->ReleaseInput();
00231     }
00232 
00233     if( m_dragging )
00234     {
00235         m_dragging = false;
00236         wxIFMDragEvent evt(wxEVT_IFM_ENDDRAG, event.GetComponent(),
00237             event.GetMouseEvent().GetPosition(),
00238             event.GetMouseEvent().AltDown(), event.GetMouseEvent().ShiftDown(),
00239             event.GetMouseEvent().ControlDown(), m_realtime);
00240         GetIP()->ProcessPluginEvent(evt);
00241     }
00242     else
00243         event.Skip();
00244 }
00245 
00246 void wxIFMDefaultDockingPlugin::OnMouseMove(wxIFMMouseEvent &event)
00247 {
00248     wxIFMComponent *component = event.GetComponent();
00249     const wxPoint &pos = event.GetMouseEvent().GetPosition();
00250 
00251     if( m_dragging )
00252     {
00253         wxIFMDragEvent evt(wxEVT_IFM_DRAGGING, component, pos,
00254             event.GetMouseEvent().AltDown(), event.GetMouseEvent().ShiftDown(),
00255             event.GetMouseEvent().ControlDown(), m_realtime);
00256         GetIP()->ProcessPluginEvent(evt);
00257         return;
00258     }
00259     else
00260     {
00261         if( m_captured )
00262         {
00263             wxPoint distance = m_clickPos - GetManager()->GetCapturedWindow()->ClientToScreen(pos);
00264             if( distance.x < 0 ) distance.x *= -1;
00265             if( distance.y < 0 ) distance.y *= -1;
00266 
00267             if( distance.x > m_dragx || distance.y > m_dragy )
00268             {
00269                 m_dragging = true;
00270 
00271                 wxIFMDragEvent evt(wxEVT_IFM_BEGINDRAG, component, pos,
00272                     event.GetMouseEvent().AltDown(), event.GetMouseEvent().ShiftDown(),
00273                     event.GetMouseEvent().ControlDown(), m_realtime);
00274                 GetIP()->ProcessPluginEvent(evt);
00275                 return;
00276             }
00277         }
00278     }
00279 
00280     event.Skip();
00281 }
00282 
00283 void wxIFMDefaultDockingPlugin::OnKeyDown(wxIFMKeyEvent &event)
00284 {
00285     if( m_dragging )
00286     {
00287         if( event.GetKeyEvent().GetKeyCode() == WXK_ESCAPE )
00288         {
00289             m_dragging = false;
00290             m_captured = false;
00291             GetManager()->ReleaseInput();
00292 
00293             // cancel dragging
00294             wxIFMDragEvent evt(wxEVT_IFM_ENDDRAG, event.GetComponent(),
00295             event.GetKeyEvent().GetPosition(),
00296             event.GetKeyEvent().AltDown(), event.GetKeyEvent().ShiftDown(),
00297             event.GetKeyEvent().ControlDown(), m_realtime, true);
00298             GetIP()->ProcessPluginEvent(evt);
00299             return;
00300         }
00301     }
00302 
00303     event.Skip();
00304 }
00305 
00306 void wxIFMDefaultDockingPlugin::OnDragInit(wxIFMInitDragEvent &event)
00307 {
00308     if( !m_captured )
00309     {
00310         wxIFMComponent *component = event.GetDraggedComponent();
00311 
00312         wxASSERT_MSG(component, wxT("Dragging a NULL component?"));
00313         if( !component )
00314             return;
00315 
00316         m_captured = true;
00317         GetManager()->CaptureInput(component);
00318         m_clickPos = GetManager()->GetCapturedWindow()->ClientToScreen(event.GetPos());
00319 
00320         m_dragx = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
00321         m_dragy = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
00322 
00323         if( m_dragx == -1 )
00324             m_dragx = IFM_DRAG_DISTANCE;
00325         if( m_dragy == -1 )
00326             m_dragy = IFM_DRAG_DISTANCE;
00327 
00328         m_dragx /= 2;
00329         m_dragy /= 2;
00330     }
00331 }
00332 
00333 void wxIFMDefaultDockingPlugin::OnDragBegin(wxIFMDragEvent &event)
00334 {
00335     m_oldPos = event.GetPosition();
00336     wxIFMComponent *component = event.GetComponent();
00337 
00338     // calculate offset
00339 
00340     //when floating, keep the window in the same position relative to the mouse
00341     wxWindow *win = GetManager()->GetCapturedWindow();
00342     //gets the offset in "window coordinates - relative to total size of the window, including
00343     //non-client area
00344     m_offset = win->ClientToScreen(m_oldPos) - win->GetPosition();
00345 
00346     wxPoint pos = m_oldPos;
00347 
00348 #if IFM_CANFLOAT
00349     wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00350 
00351     wxIFMFloatingWindowBase *floating_parent = floating_data->m_window;
00352 
00353     // float the window immediately (if not floating already)
00354     if( !floating_data->m_floating )
00355     {
00356         m_offset = wxPoint(12,12);
00357         wxIFMFloatEvent floatevt(component, pos, floating_data->m_rect.GetSize());
00358         GetIP()->ProcessPluginEvent(floatevt);
00359 
00360         // store floating window for later
00361         m_window = floating_data->m_window;
00362 
00363         // update interface
00364         GetManager()->Update();
00365     }
00366     else
00367     {
00368         bool reuse_window = false;
00369 
00370         // if we are dragging the root component, just drag the floating window instead
00371         if( !component->m_docked )
00372             reuse_window = true;
00373 
00374         // don't make a new window if we are dragging the only child panel either
00375         {
00376             wxIFMComponent *root = floating_data->m_window->m_component;
00377             if( root->m_children.size() == 1 && root->m_children[0] == component )
00378                 reuse_window = true;
00379         }
00380 
00381         if( reuse_window )
00382             m_window = floating_data->m_window;
00383         else
00384         {
00385             // fix the offset being incorrect if you are re-floating an already floating window
00386             m_offset = wxPoint(12,12);
00387 
00388             // don't delete the old floating window to prevent wierd bugs
00390             wxIFMUndockEvent evt(component, false);
00391             GetIP()->ProcessPluginEvent(evt);
00392 
00393             wxIFMFloatEvent floatevt(component, pos, floating_data->m_rect.GetSize());
00394             GetIP()->ProcessPluginEvent(floatevt);
00395 
00396             m_window = floating_data->m_window;
00397 
00398             if( floating_parent->GetComponent()->m_children.GetCount() == 0 )
00399             {
00400                 // FIXME: The huge if statement above prevents this code from ever firing (right now)
00401                 // but when this code does fire, windows is unhappy and messes up mouse capture
00402                 wxIFMDestroyFloatingWindowEvent evt(floating_parent, true);
00403                 GetIP()->ProcessPluginEvent(evt);
00404             }
00405             else
00406                 // update the floating window we docked out of
00407                 floating_parent->Update();
00408         }
00409     }
00410 
00411 #endif
00412 
00413     CreateTargetButtons();
00414     ShowFrameDropButtons(true);
00415 
00416     GetManager()->DisplayStatusMessage(wxT("Press Escape to cancel. Hold down alt to prevent drop target buttons from moving. Hold down shift to hide drop target buttons."));
00417 }
00418 
00419 void wxIFMDefaultDockingPlugin::OnDragEnd(wxIFMDragEvent &event)
00420 {
00421     ShowComponentDropButtons(false);
00422     ShowFrameDropButtons(false);
00423 
00424     if( !event.WasCanceled() )
00425     {
00426         wxPoint pos = event.GetPosition();
00427         wxIFMComponent *component = event.GetComponent();
00428         bool new_container = true, destroy_floating_window = false;
00429 
00430 #if IFM_CANFLOAT
00431         wxIFMFloatingWindowBase *m_floatingParent = NULL;
00432         wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00433         // only set this value if we are undocking from a floating window, and we aren't undocking
00434         // the root container of the floating window
00435         if( floating_data->m_floating )
00436             m_floatingParent = floating_data->m_window;
00437 #endif
00438 
00439         wxIFMComponent *destination = NULL;
00440 
00441         if( m_oldBtn && !(m_oldBtn->GetId() == IFM_DOCK_ID_TAB && !m_oldBtn->GetComponent()) )
00442         {
00443             wxIFMComponent *parent = component->m_parent;
00444             if( parent )
00445             {
00446                 // undock the component first
00447                 wxIFMUndockEvent evt(component);
00448                 GetIP()->ProcessPluginEvent(evt);
00449             }
00450 #if IFM_CANFLOAT
00451             else if( !floating_data->m_floating )
00452 #else
00453             else
00454 #endif
00455             {
00456                 // no parent and not floating means the component is a top level container
00457                 // remove it from the top level container list first
00458                 wxIFMRemoveTopContainerEvent evt(component);
00459                 GetIP()->ProcessPluginEvent(evt);
00460                 //new_container = false;
00461             }
00462 #if IFM_CANFLOAT
00463             else
00464             {
00465                 // no parent and floating means its the root component of a floating window
00466                 //new_container = false;
00467                 destroy_floating_window = true;
00468             }
00469 #endif
00470 
00471             // we don't need a new container if we are already a container...
00472             if( component->GetType() == IFM_COMPONENT_CONTAINER )
00473                 new_container = false;
00474 
00475             // generate the appropriate dock event
00476             int id = m_oldBtn->GetId();
00477 
00478             if( !m_oldBtn->GetComponent() )
00479             {
00480                 wxIFMComponent *container;
00481 
00482                 if( new_container )
00483                 {
00484                     // create a new container
00485                     wxIFMNewComponentEvent newevt(IFM_COMPONENT_CONTAINER);
00486                     GetIP()->ProcessPluginEvent(newevt);
00487 
00488                     // WARNING: This may return null
00489                     container = newevt.GetComponent();
00490                 }
00491                 else
00492                     container = component;
00493 
00494                 wxIFMContainerData *data = IFM_GET_EXTENSION_DATA(container, wxIFMContainerData);
00495                 bool front = false;
00496 
00497                 switch(id)
00498                 {
00499                     case IFM_DOCK_ID_FRAME_TOP:
00500                         front = true;
00501                     case IFM_DOCK_ID_TOP:
00502                         data->m_orientation = IFM_ORIENTATION_TOP;
00503                         container->m_alignment = IFM_ALIGN_HORIZONTAL;
00504                         break;
00505                     case IFM_DOCK_ID_FRAME_BOTTOM:
00506                         front = true;
00507                     case IFM_DOCK_ID_BOTTOM:
00508                         data->m_orientation = IFM_ORIENTATION_BOTTOM;
00509                         container->m_alignment = IFM_ALIGN_HORIZONTAL;
00510                         break;
00511                     case IFM_DOCK_ID_FRAME_LEFT:
00512                         front = true;
00513                     case IFM_DOCK_ID_LEFT:
00514                         data->m_orientation = IFM_ORIENTATION_LEFT;
00515                         container->m_alignment = IFM_ALIGN_VERTICAL;
00516                         break;
00517                     case IFM_DOCK_ID_FRAME_RIGHT:
00518                         front = true;
00519                     case IFM_DOCK_ID_RIGHT:
00520                         data->m_orientation = IFM_ORIENTATION_RIGHT;
00521                         container->m_alignment = IFM_ALIGN_VERTICAL;
00522                         break;
00523                 }
00524 
00525                 // add container to front of the list
00526                 if( front )
00527                 {
00528                     wxIFMAddTopContainerEvent evt(container, 0);
00529                     GetIP()->ProcessPluginEvent(evt);
00530                 }
00531                 else
00532                 {
00533                     wxIFMAddTopContainerEvent evt(container, -1);
00534                     GetIP()->ProcessPluginEvent(evt);
00535                 }
00536 
00537                 if( new_container )
00538                 {
00539                     // dock the panel into the new container
00540                     wxIFMDockEvent dockevt(component, container, 0);
00541                     GetIP()->ProcessPluginEvent(dockevt);
00542                 }
00543             }
00544             else
00545             {
00546                 destination = m_oldBtn->GetComponent();
00547                 wxIFMComponent *container = NULL;
00548                 int index = 0;
00549 
00550                 if( destination->GetType() == IFM_COMPONENT_CONTAINER )
00551                 {
00552                     wxIFMContainerData *data = IFM_GET_EXTENSION_DATA(destination, wxIFMContainerData);
00553 
00554                     if( (destination->m_alignment == IFM_ALIGN_VERTICAL && (id == IFM_DOCK_ID_LEFT || id == IFM_DOCK_ID_RIGHT)) ||
00555                         (destination->m_alignment == IFM_ALIGN_HORIZONTAL && (id == IFM_DOCK_ID_TOP || id == IFM_DOCK_ID_BOTTOM)) )
00556                     {
00557                         if( !destination->m_docked )
00558                         {
00559                             // create a new container
00560                             if( new_container )
00561                             {
00562                                 wxIFMNewComponentEvent newevt(IFM_COMPONENT_CONTAINER);
00563                                 GetIP()->ProcessPluginEvent(newevt);
00564                                 container = newevt.GetComponent();
00565                             }
00566                             else
00567                                 container = component;
00568 
00569                             wxIFMContainerData *contdata = IFM_GET_EXTENSION_DATA(container, wxIFMContainerData);
00570 
00571                             container->m_alignment = destination->m_alignment;
00572                             contdata->m_orientation = data->m_orientation;
00573 
00574                             if( new_container )
00575                             {
00576                                 // dock into it
00577                                 wxIFMDockEvent dockevt(component, container, 0);
00578                                 GetIP()->ProcessPluginEvent(dockevt);
00579                             }
00580 
00581                             bool before;
00582                             if( destination->m_alignment == IFM_ALIGN_VERTICAL )
00583                                 before = id == IFM_DOCK_ID_LEFT ? true : false;
00584                             else
00585                                 before = id == IFM_DOCK_ID_TOP ? true : false;
00586 
00587                             // if the destination is a container, we need to invert before depending
00588                             // on what side of the application the container is on
00589                             if( destination->GetType() == IFM_COMPONENT_CONTAINER )
00590                             {
00591                                 wxIFMContainerData *contdata = IFM_GET_EXTENSION_DATA(destination, wxIFMContainerData);
00592 
00593                                 wxASSERT_MSG(contdata, wxT("container with no container data?"));
00594                                 if( contdata && (contdata->m_orientation == IFM_ORIENTATION_BOTTOM || contdata->m_orientation == IFM_ORIENTATION_RIGHT) )
00595                                     before = !before;
00596                             }
00597 
00598                             // add the container as a top container
00599                             wxIFMAddTopContainerEvent topevt(container, destination, before);
00600                             GetIP()->ProcessPluginEvent(topevt);
00601                         }
00602                         else
00603                         {
00605 
00606                             // send custom dock event
00607                             wxIFMDockEventEx dockevt(component, destination, index, id);
00608                             GetIP()->ProcessPluginEvent(dockevt);
00609                         }
00610                     }
00611                     else if( (destination->m_alignment == IFM_ALIGN_VERTICAL && (id == IFM_DOCK_ID_TOP || id == IFM_DOCK_ID_BOTTOM)) ||
00612                         (destination->m_alignment == IFM_ALIGN_HORIZONTAL && (id == IFM_DOCK_ID_LEFT || id == IFM_DOCK_ID_RIGHT)) )
00613                     {
00614                         int index;
00615 
00616                         if( destination->m_alignment == IFM_ALIGN_VERTICAL )
00617                             index = id == IFM_DOCK_ID_TOP ? 0 : -1;
00618                         else
00619                             index = id == IFM_DOCK_ID_LEFT ? 0 : -1;
00620 
00621                         // send a normal dock event
00622                         wxIFMDockEvent dockevt(component, destination, index);
00623                         GetIP()->ProcessPluginEvent(dockevt);
00624                     }
00625                 }
00626                 // docking into panels as a tab
00627                 else if( destination->GetType() == IFM_COMPONENT_PANEL && id == IFM_DOCK_ID_TAB )
00628                 {
00629                     // send a normal dock event
00630                     wxIFMDockEvent dockevt(component, destination, IFM_DEFAULT_INDEX);
00631                     GetIP()->ProcessPluginEvent(dockevt);
00632                 }
00633                 // generic docking fallback
00634                 else if( destination->m_parent )
00635                 {
00636                     wxIFMComponent *parent = destination->m_parent;
00637 
00638                     // find the index of the component within its parent
00639                     {
00640                         const wxIFMComponentArray &children = parent->m_children;
00641                         //for( int count = children.GetCount(); index < count; index++ )
00642                         for( wxIFMComponentArray::const_iterator i = children.begin(), end = children.end(); i != end; ++i, index++ )
00643                         {
00644                             //if( children[index] == destination )
00645                             if( *i == destination )
00646                                 break;
00647                         }
00648                     }
00649 
00650                     // send custom dock event
00651                     wxIFMDockEventEx dockevt(component, parent, index, id);
00652                     GetIP()->ProcessPluginEvent(dockevt);
00653                 }
00654             }
00655 
00656 #if IFM_CANFLOAT
00657             // update the destination floating window too
00658             wxIFMFloatingData *dest_floating_data = NULL;
00659             if( destination )
00660                 dest_floating_data = IFM_GET_EXTENSION_DATA(destination, wxIFMFloatingData);
00661             if( destination && dest_floating_data->m_floating )
00662             {
00663                 wxIFMFloatingWindowBase *window = dest_floating_data->m_window;
00664                 // FIXME: accessing m_rect directly here, is this ok?
00665                 wxIFMUpdateComponentEvent updevt(window->GetComponent(), window->GetComponent()->m_rect);
00666                 GetIP()->ProcessPluginEvent(updevt);
00667             }
00668             // update the floating parent if we undocked from it
00669             if( m_floatingParent )
00670             {
00671                 m_floatingParent->Update();
00672             }
00673 #endif
00674 
00675             // update interface
00676             GetManager()->Update();
00677         }
00678 #if IFM_CANFLOAT
00679         else
00680         {
00681             component->GetParentWindow()->SetFocus();
00682         }
00683 
00684         if( destroy_floating_window )
00685         {
00686             // destroy the floating window, but not its root component
00687             // FIXME: If I drag the only panel out of a floating window, the root component
00688             // of this floating window wont be destroyed
00689             wxIFMDestroyFloatingWindowEvent evt(m_floatingParent, false);
00690             GetIP()->AddPendingEvent(evt);
00691         }
00692 #endif
00693     }
00694 
00695     DestroyTargetButtons();
00696 
00697     m_oldBtn = NULL;
00698 
00699     GetManager()->ResetStatusMessage();
00700 }
00701 
00702 void wxIFMDefaultDockingPlugin::OnDrag(wxIFMDragEvent &event)
00703 {
00704     wxPoint client_pos = event.GetPosition();
00705     wxIFMComponent *component = event.GetComponent();
00706 
00707     wxPoint pos;
00708     pos = GetManager()->GetCapturedWindow()->ClientToScreen(client_pos);
00709 
00710     wxIFMDockTargetButton *btn = GetDockTargetButtonByPos(pos);
00711 
00712 #if IFM_CANFLOAT
00713     wxIFMFloatingData *floating_data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00714 
00715     if( floating_data->m_floating )
00716         component = GetFloatingComponentByPosExclusion(pos, floating_data->m_window);
00717 
00718     if( !component )
00719 #endif
00720         component = m_ip->GetComponentByPos(GetManager()->GetParent()->ScreenToClient(pos), NULL);
00721 
00722     // if the component the mouse is over
00723     if( btn )
00724     {
00725         wxSetCursor(wxCursor(wxCURSOR_ARROW));
00726         btn->SetHover(true);
00727     }
00728     else
00729     {
00730 #if !IFM_CANFLOAT
00731         wxSetCursor(wxCursor(wxCURSOR_NO_ENTRY));
00732 #endif
00733 
00734         if( event.ShiftDown() )
00735         {
00736             ShowFrameDropButtons(false);
00737             ShowComponentDropButtons(false);
00738         }
00739         else
00740         {
00741             static wxIFMComponent *last_component = NULL;
00742             static bool last_component_set = false;
00743             if( event.AltDown() )
00744             {
00745                 if( !last_component_set )
00746                 {
00747                     last_component = component;
00748                     last_component_set = true;
00749                 }
00750                 component = last_component;
00751             }
00752             else
00753             {
00754                 last_component_set = false;
00755                 last_component = NULL;
00756             }
00757 
00758             // special processing for tabbed panels is required. If the mouse is over the active tab
00759             // of a tabbed panel, display buttons for that tabbed panel instead of the tab
00760             if( component && component->GetType() == IFM_COMPONENT_PANEL_TAB )
00761                 component = component->m_parent;
00762 
00763             wxIFMShowDropTargetsEvent evt(component, GetManager()->GetParent()->ScreenToClient(pos), event.GetComponent());
00764             GetIP()->ProcessPluginEvent(evt);
00765         }
00766 
00767 #if IFM_CANFLOAT
00768         // move the floating window
00769         if( m_window )
00770             m_window->GetWindow()->Move(pos - m_offset);
00771 #endif
00772 
00773         m_oldPos = pos;
00774     }
00775 
00776     if( m_oldBtn && m_oldBtn != btn )
00777             m_oldBtn->SetHover(false);
00778 
00779     m_oldBtn = btn;
00780 }
00781 
00782 void wxIFMDefaultDockingPlugin::OnDock(wxIFMDockEvent &event)
00783 {
00784 #if IFM_USE_WX_RTTI
00785     wxIFMDockEventEx *evt = wxDynamicCast(&event,wxIFMDockEventEx);
00786 #else
00787     wxIFMDockEventEx *evt = dynamic_cast<wxIFMDockEventEx*>(&event);
00788 #endif
00789 
00790     if( evt )
00791     {
00792         int where = evt->GetWhere();
00793         int index = evt->GetIndex();
00794 
00795         wxIFMComponent *dest = evt->GetDestination();
00796 
00797         if( dest->m_alignment == IFM_ALIGN_HORIZONTAL && where == IFM_DOCK_ID_RIGHT ||
00798             dest->m_alignment == IFM_ALIGN_VERTICAL &&  where == IFM_DOCK_ID_BOTTOM )
00799         {
00800             evt->SetIndex(index + 1);
00801         }
00802         else if( (dest->m_alignment == IFM_ALIGN_HORIZONTAL && (where == IFM_DOCK_ID_TOP || where == IFM_DOCK_ID_BOTTOM)) ||
00803             (dest->m_alignment == IFM_ALIGN_VERTICAL && (where == IFM_DOCK_ID_LEFT || where == IFM_DOCK_ID_RIGHT)) )
00804         {
00805             // need to create a container, undock the child at the current index,
00806             // dock the container where the child was, dock the child into the container,
00807             // and finally dock the component into the container
00808 
00809             // just change the orientation of the container if it has one child
00810             if( dest->m_children.size() == 1 )
00811             {
00812                 if( dest->m_alignment == IFM_ALIGN_HORIZONTAL )
00813                     dest->m_alignment = IFM_ALIGN_VERTICAL;
00814                 else if( dest->m_alignment == IFM_ALIGN_VERTICAL )
00815                     dest->m_alignment = IFM_ALIGN_HORIZONTAL;
00816 
00817                 event.Skip();
00818             }
00819             else
00820             {
00821                 // make a container
00822                 wxIFMNewComponentEvent newevt(IFM_COMPONENT_CONTAINER);
00823                 GetIP()->ProcessPluginEvent(newevt);
00824                 wxIFMComponent *container = newevt.GetComponent();
00825 
00826                 container->m_alignment = dest->m_alignment == IFM_ALIGN_HORIZONTAL ? IFM_ALIGN_VERTICAL : IFM_ALIGN_HORIZONTAL;
00827 
00828                 wxIFMComponent *child = dest->m_children[index];
00829 
00830                 // dock the container where the child was
00831                 wxIFMDockEvent dockevt1(container, dest, index);
00832                 GetIP()->ProcessPluginEvent(dockevt1);
00833 
00834                 // undock the child
00835                 wxIFMUndockEvent undockevt(child, false);
00836                 GetIP()->ProcessPluginEvent(undockevt);
00837 
00838                 // dock the child into the container
00839                 wxIFMDockEvent dockevt2(child, container, IFM_DEFAULT_INDEX);
00840                 GetIP()->ProcessPluginEvent(dockevt2);
00841 
00842                 // dock the component into the container using the special dock event
00843                 // for proper "where" processing
00844                 wxIFMDockEventEx dockevt3(event.GetComponent(), container, 0, where);
00845                 GetIP()->ProcessPluginEvent(dockevt3);
00846             }
00847 
00848             return;
00849         }
00850     }
00851 
00852     // let the container handle the docking now
00853     event.Skip();
00854 }
00855 
00856 void wxIFMDefaultDockingPlugin::DrawHintRect(wxDC &dc, const wxRect &rect)
00857 {
00858     dc.SetPen(*wxGREY_PEN);
00859     dc.SetLogicalFunction(wxXOR);
00860 
00861     // draw border
00862     int top = rect.y, left = rect.x, right = left + rect.width - 1, bottom = top + rect.height - 1;
00863     dc.BeginDrawing();
00864     dc.DrawLine(left + 1, top, right, top);
00865     dc.DrawLine(left, top, left, bottom);
00866     dc.DrawLine(left, bottom, right + 1, bottom);
00867     dc.DrawLine(right, top, right, bottom);
00868     dc.EndDrawing();
00869 
00870     dc.SetLogicalFunction(wxCOPY);
00871     dc.SetPen(wxNullPen);
00872 }
00873 
00874 inline void _create_helper(DockButtonArray &array, wxIFMDockTargetButton *btn)
00875 {
00876     //btn->Raise();
00877     array.push_back(btn);
00878 }
00879 
00880 void wxIFMDefaultDockingPlugin::CreateTargetButtons()
00881 {
00882     wxWindow *parent = GetManager()->GetParent();
00883     wxPoint pos;
00884     wxIFMDockTargetButton *btn;
00885 
00886     // Frame buttons
00887     wxRect client_rect = GetManager()->GetInterfaceRect();
00888     client_rect.SetPosition(GetManager()->GetParent()->ClientToScreen(client_rect.GetPosition()));
00889 
00890     // left button
00891     pos.x = IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.x;
00892     pos.y = client_rect.height / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.y;
00893     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_FRAME_LEFT, IFM_DOCK_ICON_LEFT);
00894     m_dockButtonArray.push_back(btn);
00895 
00896     // top button
00897     pos.x = client_rect.width / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.x;
00898     pos.y = IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.y;
00899     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_FRAME_TOP, IFM_DOCK_ICON_TOP);
00900     _create_helper(m_dockButtonArray, btn);
00901 
00902     // right button
00903     pos.x = client_rect.width - IFM_DOCK_TARGET_BUTTON_WIDTH - IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.x;
00904     pos.y = client_rect.height / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.y;
00905     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_FRAME_RIGHT, IFM_DOCK_ICON_RIGHT);
00906     _create_helper(m_dockButtonArray, btn);
00907 
00908     // bottom button
00909     pos.x = client_rect.width / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.x;
00910     pos.y = client_rect.height - IFM_DOCK_TARGET_BUTTON_WIDTH - IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.y;
00911     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_FRAME_BOTTOM, IFM_DOCK_ICON_BOTTOM);
00912     _create_helper(m_dockButtonArray, btn);
00913 
00914     // Component buttons
00915     pos.x = pos.y = 3000; // random value off screen
00916 
00917     // left button
00918     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_LEFT, IFM_DOCK_ICON_LEFT);
00919     _create_helper(m_dockButtonArray, btn);
00920 
00921     // top button
00922     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_TOP, IFM_DOCK_ICON_TOP);
00923     _create_helper(m_dockButtonArray, btn);
00924 
00925     // right button
00926     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_RIGHT, IFM_DOCK_ICON_RIGHT);
00927     _create_helper(m_dockButtonArray, btn);
00928 
00929     // bottom button
00930     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_BOTTOM, IFM_DOCK_ICON_BOTTOM);
00931     _create_helper(m_dockButtonArray, btn);
00932 
00933     // tabulate button
00934     btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_TAB, IFM_DOCK_ICON_TAB);
00935     _create_helper(m_dockButtonArray, btn);
00936 }
00937 
00938 void wxIFMDefaultDockingPlugin::DestroyTargetButtons()
00939 {
00940     for( int i = 0, count = m_dockButtonArray.GetCount(); i < count; ++i )
00941     //for( DockButtonArray::iterator i = m_dockButtonArray.begin(), end = m_dockButtonArray.end(); i != end; ++i )
00942         m_dockButtonArray[i]->Destroy();
00943         //(*i)->Destroy();
00944     m_dockButtonArray.clear();
00945 }
00946 
00947 void wxIFMDefaultDockingPlugin::ShowFrameDropButtons(bool show)
00948 {
00949     static bool last = false;
00950 
00951     if( show != last )
00952         last = show;
00953     else
00954         return;
00955 
00956     for( int i = 0, end = 4; i < end; ++i )
00957     //for( DockButtonArray::iterator i = m_dockButtonArray.begin(), end = i + 4; i != end; ++i )
00958         m_dockButtonArray[i]->Show(show);
00959         //(*i)->Show(show);
00960 
00961     GetManager()->GetParent()->SetFocus();
00962 }
00963 
00964 void wxIFMDefaultDockingPlugin::ShowComponentDropButtons(bool show)
00965 {
00966     static bool last = false;
00967 
00968     if( show != last )
00969         last = show;
00970     else
00971         return;
00972 
00973     for( int i = 4, end = m_dockButtonArray.GetCount(); i < end; ++i )
00974     //for( DockButtonArray::iterator i = m_dockButtonArray.begin() + 4, end = m_dockButtonArray.end(); i != end; ++i )
00975         m_dockButtonArray[i]->Show(show);
00976         //(*i)->Show(show);
00977 
00978 
00979     GetManager()->GetParent()->SetFocus();
00980 }
00981 
00982 void wxIFMDefaultDockingPlugin::OnShowDropTargets(wxIFMShowDropTargetsEvent &event)
00983 {
00985     wxPoint pos = event.GetPosition();
00986     wxIFMComponent *component = event.GetComponent();
00987 
00988     ShowFrameDropButtons(true);
00989 
00990 #if IFM_CANFLOAT
00991     wxIFMFloatingData *floating_data = NULL;
00992     if( component )
00993          floating_data = IFM_GET_EXTENSION_DATA(component, wxIFMFloatingData);
00994 #endif
00995 
00996     if( !GetManager()->GetParent()->GetClientRect().Inside(pos) && !component )
00997     {
00998         ShowComponentDropButtons(false);
00999         return;
01000     }
01001     else if( component )
01002     {
01003         // don't display target buttons if you hover over the component you're dragging
01004         // or if you're hovering over the parent of the control you are dragging and the
01005         // parent's only child is the control you are dragging.
01006         // also don't display buttons if hovering over the root component of a floating window
01007         if( (component == event.GetDraggedComponent()) ||
01008             (component == event.GetDraggedComponent()->m_parent &&
01009              component->m_children.GetCount() == 1) ||
01010 #if IFM_CANFLOAT
01011             (floating_data->m_floating && !component->m_docked) ||
01012 #endif
01013             (wxIFMComponent::IsChildOf(event.GetDraggedComponent(), component))
01014             )
01015         {
01016             ShowComponentDropButtons(false);
01017             return;
01018         }
01019         else
01020         {
01021             wxPoint center;
01022             wxIFMRectEvent rectevt(wxEVT_IFM_GETRECT, component);
01023             GetIP()->ProcessPluginEvent(rectevt);
01024             wxRect rect = rectevt.GetRect();
01025             center.x = rect.x + rect.width / 2;
01026             center.y = rect.y + rect.height / 2;
01027             pos = center;
01028             ShowComponentDropButtons(true);
01029         }
01030     }
01031     else
01032     {
01033         wxPoint center;
01034         wxIFMRectEvent rectevt(wxEVT_IFM_GETCONTENTRECT, NULL);
01035         GetIP()->ProcessPluginEvent(rectevt);
01036         wxRect rect = rectevt.GetRect();
01037         center.x = rect.x + rect.width / 2;
01038         center.y = rect.y + rect.height / 2;
01039         pos = center;
01040         ShowComponentDropButtons(true);
01041     }
01042 
01043     // position buttons properly over floating windows
01044     if( component )
01045         pos = component->GetParentWindow()->ClientToScreen(pos);
01046     else
01047         pos = GetManager()->GetParent()->ClientToScreen(pos);
01048 
01049     wxIFMDockTargetButton *btn;
01050     wxPoint new_pos, tab_pos;
01051     int i = m_dockButtonArray.GetCount() - 1;
01052     wxRect rect;
01053 
01054     // tabulate
01055     btn = m_dockButtonArray[i--];
01056     tab_pos.x = pos.x - IFM_DOCK_TARGET_BUTTON_WIDTH / 2;
01057     tab_pos.y = pos.y - IFM_DOCK_TARGET_BUTTON_WIDTH / 2;
01058     btn->Move(tab_pos);
01059 
01060     // bottom
01061     btn = m_dockButtonArray[i--];
01062     new_pos.y = tab_pos.y + IFM_DOCK_TARGET_BUTTON_WIDTH;
01063     new_pos.x = tab_pos.x;
01064     btn->Move(new_pos);
01065 
01066     // right
01067     btn = m_dockButtonArray[i--];
01068     new_pos.x = tab_pos.x + IFM_DOCK_TARGET_BUTTON_WIDTH;
01069     new_pos.y = tab_pos.y;
01070     btn->Move(new_pos);
01071 
01072     // top
01073     btn = m_dockButtonArray[i--];
01074     new_pos.y = tab_pos.y - IFM_DOCK_TARGET_BUTTON_WIDTH;
01075     new_pos.x = tab_pos.x;
01076     btn->Move(new_pos);
01077 
01078     rect.y = new_pos.y;
01079 
01080     // left
01081     btn = m_dockButtonArray[i];
01082     new_pos.x = tab_pos.x - IFM_DOCK_TARGET_BUTTON_WIDTH;
01083     new_pos.y = tab_pos.y;
01084     btn->Move(new_pos);
01085 
01086     rect.x = new_pos.x;
01087     rect.width = IFM_DOCK_TARGET_BUTTON_WIDTH * 3;
01088     rect.height = IFM_DOCK_TARGET_BUTTON_WIDTH * 3;
01089 
01090     wxRect client_rect = GetManager()->GetInterfaceRect();
01091     client_rect.SetPosition(GetManager()->GetParent()->ClientToScreen(client_rect.GetPosition()));
01092 
01093     // position the edge buttons here as well. They normally don't move,
01094     // but if any component drop button overlaps one of the edge buttons,
01095     // we need to "nudge" the edge button out of the way
01096 
01097     // left button
01098     wxRect btn_size(0, 0, IFM_DOCK_TARGET_BUTTON_WIDTH, IFM_DOCK_TARGET_BUTTON_WIDTH);
01099     btn_size.x = IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.x;
01100     btn_size.y = client_rect.height / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.y;
01101     if( btn_size.Intersects(rect) )
01102         btn_size.y = rect.y - IFM_DOCK_TARGET_BUTTON_WIDTH;
01103     m_dockButtonArray[0]->Move(btn_size.GetPosition());
01104 
01105     // top button
01106     btn_size.x = client_rect.width / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.x;
01107     btn_size.y = IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.y;
01108     if( btn_size.Intersects(rect) )
01109         btn_size.x = rect.x - IFM_DOCK_TARGET_BUTTON_WIDTH;
01110     m_dockButtonArray[1]->Move(btn_size.GetPosition());
01111 
01112     // right button
01113     btn_size.x = client_rect.width - IFM_DOCK_TARGET_BUTTON_WIDTH - IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.x;
01114     btn_size.y = client_rect.height / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.y;
01115     if( btn_size.Intersects(rect) )
01116         btn_size.y = rect.y - IFM_DOCK_TARGET_BUTTON_WIDTH;
01117     m_dockButtonArray[2]->Move(btn_size.GetPosition());
01118 
01119     // bottom button
01120     btn_size.x = client_rect.width / 2 - IFM_DOCK_TARGET_BUTTON_WIDTH / 2 + client_rect.x;
01121     btn_size.y = client_rect.height - IFM_DOCK_TARGET_BUTTON_WIDTH - IFM_DOCK_TARGET_BUTTON_WIDTH + client_rect.y;
01122     if( btn_size.Intersects(rect) )
01123         btn_size.x = rect.x - IFM_DOCK_TARGET_BUTTON_WIDTH;
01124     m_dockButtonArray[3]->Move(btn_size.GetPosition());
01125 
01126     {
01127         for( int i = 4, count = m_dockButtonArray.GetCount(); i < count; ++i )
01128         //for( DockButtonArray::iterator i = m_dockButtonArray.begin() + 4, end = m_dockButtonArray.end(); i != end; ++i )
01129         {
01130             m_dockButtonArray[i]->SetComponent(component);
01131             //(*i)->SetComponent(component);
01132         }
01133     }
01134 }
01135 
01136 wxIFMDockTargetButton *wxIFMDefaultDockingPlugin::GetDockTargetButtonByPos(const wxPoint &pos)
01137 {
01138     wxIFMDockTargetButton *btn;
01139     for( int i = 0, count = m_dockButtonArray.GetCount(); i < count; ++i )
01140     //for( DockButtonArray::const_iterator i = m_dockButtonArray.begin(), end = m_dockButtonArray.end(); i != end; ++i )
01141     {
01142         btn = m_dockButtonArray[i];
01143         //btn = *i;
01144         if( btn->IsShown() && btn->GetRect().Inside(pos) )
01145             return btn;
01146     }
01147 
01148     return NULL;
01149 }
01150 
01151 #if IFM_CANFLOAT
01152 wxIFMComponent *wxIFMDefaultDockingPlugin::GetFloatingComponentByPosExclusion(const wxPoint &pos, wxIFMFloatingWindowBase *exclude)
01153 {
01154     wxIFMFloatingWindowArray windows = GetIP()->GetFloatingWindows();
01155     wxIFMComponent *ret = NULL;
01156     wxIFMFloatingWindowBase *window;
01157 
01158     for( int i = 0, count = windows.GetCount(); i < count; ++i )
01159     //for( wxIFMFloatingWindowArray::const_iterator i = windows.begin(), end = windows.end(); i != end; ++i )
01160     {
01161         window = windows[i];
01162         //window = *i;
01163 
01164         if( window != exclude )
01165         {
01166             ret = GetIP()->GetComponentByPos(window->GetWindow()->ScreenToClient(pos), window->GetComponent());
01167             if( ret )
01168                 return ret;
01169         }
01170     }
01171 
01172     return ret;
01173 }
01174 #endif
01175 
01176 BEGIN_EVENT_TABLE(wxIFMDockTargetButton, wxWindow)
01177     EVT_PAINT   (wxIFMDockTargetButton::OnPaint)
01178     EVT_ERASE_BACKGROUND (wxIFMDockTargetButton::OnEraseBackground)
01179 END_EVENT_TABLE()
01180 
01181 wxIFMDockTargetButton::wxIFMDockTargetButton(wxWindow *parent, const wxPoint &pos, int id, int icon, wxIFMComponent *component)
01182 #if 0 //defined(__WXMAC__) || defined (__WXCOCOA)
01183         : wxWindow(parent, wxID_ANY, pos, IFM_DOCK_TARGET_BUTTON_SIZE, wxCLIP_SIBLINGS | wxNO_BORDER ),
01184 #else
01185         : wxFrame(parent, wxID_ANY, wxT(""), pos, IFM_DOCK_TARGET_BUTTON_SIZE, /*wxSTAY_ON_TOP | */wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT | wxNO_BORDER ),
01186 #endif
01187         m_hover(false),
01188         m_id(id),
01189         m_icon(icon),
01190         m_component(component)
01191 {
01192 
01193 }
01194 
01195 void wxIFMDockTargetButton::SetHover(bool hover)
01196 {
01197     if( m_hover != hover )
01198     {
01199         m_hover = hover;
01200         Refresh();
01201     }
01202 }
01203 
01204 void wxIFMDockTargetButton::OnEraseBackground(wxEraseEvent &WXUNUSED(event))
01205 {
01206 
01207 }
01208 
01209 void wxIFMDockTargetButton::OnPaint(wxPaintEvent &WXUNUSED(event))
01210 {
01211     wxPaintDC dc(this);
01212 
01213     switch(m_icon)
01214     {
01215         case IFM_DOCK_ICON_LEFT:
01216             if( m_hover )
01217                 dc.DrawBitmap(img_leftHover, 0, 0, false);
01218             else
01219                 dc.DrawBitmap(img_left, 0, 0, false);
01220             break;
01221         case IFM_DOCK_ICON_RIGHT:
01222             if( m_hover )
01223                 dc.DrawBitmap(img_rightHover, 0, 0, false);
01224             else
01225                 dc.DrawBitmap(img_right, 0, 0, false);
01226             break;
01227         case IFM_DOCK_ICON_TOP:
01228             if( m_hover )
01229                 dc.DrawBitmap(img_topHover, 0, 0, false);
01230             else
01231                 dc.DrawBitmap(img_top, 0, 0, false);
01232             break;
01233         case IFM_DOCK_ICON_BOTTOM:
01234             if( m_hover )
01235                 dc.DrawBitmap(img_bottomHover, 0, 0, false);
01236             else
01237                 dc.DrawBitmap(img_bottom, 0, 0, false);
01238             break;
01239         case IFM_DOCK_ICON_TAB:
01240             if( m_hover )
01241                 dc.DrawBitmap(img_tabHover, 0, 0, false);
01242             else
01243                 dc.DrawBitmap(img_tab, 0, 0, false);
01244             break;
01245     }
01246 }

 

SourceForge Logo