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
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
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
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
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
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
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
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
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
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
00339
00340
00341 wxWindow *win = GetManager()->GetCapturedWindow();
00342
00343
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
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
00361 m_window = floating_data->m_window;
00362
00363
00364 GetManager()->Update();
00365 }
00366 else
00367 {
00368 bool reuse_window = false;
00369
00370
00371 if( !component->m_docked )
00372 reuse_window = true;
00373
00374
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
00386 m_offset = wxPoint(12,12);
00387
00388
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
00401
00402 wxIFMDestroyFloatingWindowEvent evt(floating_parent, true);
00403 GetIP()->ProcessPluginEvent(evt);
00404 }
00405 else
00406
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
00434
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
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
00457
00458 wxIFMRemoveTopContainerEvent evt(component);
00459 GetIP()->ProcessPluginEvent(evt);
00460
00461 }
00462 #if IFM_CANFLOAT
00463 else
00464 {
00465
00466
00467 destroy_floating_window = true;
00468 }
00469 #endif
00470
00471
00472 if( component->GetType() == IFM_COMPONENT_CONTAINER )
00473 new_container = false;
00474
00475
00476 int id = m_oldBtn->GetId();
00477
00478 if( !m_oldBtn->GetComponent() )
00479 {
00480 wxIFMComponent *container;
00481
00482 if( new_container )
00483 {
00484
00485 wxIFMNewComponentEvent newevt(IFM_COMPONENT_CONTAINER);
00486 GetIP()->ProcessPluginEvent(newevt);
00487
00488
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
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
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
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
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
00588
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
00599 wxIFMAddTopContainerEvent topevt(container, destination, before);
00600 GetIP()->ProcessPluginEvent(topevt);
00601 }
00602 else
00603 {
00605
00606
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
00622 wxIFMDockEvent dockevt(component, destination, index);
00623 GetIP()->ProcessPluginEvent(dockevt);
00624 }
00625 }
00626
00627 else if( destination->GetType() == IFM_COMPONENT_PANEL && id == IFM_DOCK_ID_TAB )
00628 {
00629
00630 wxIFMDockEvent dockevt(component, destination, IFM_DEFAULT_INDEX);
00631 GetIP()->ProcessPluginEvent(dockevt);
00632 }
00633
00634 else if( destination->m_parent )
00635 {
00636 wxIFMComponent *parent = destination->m_parent;
00637
00638
00639 {
00640 const wxIFMComponentArray &children = parent->m_children;
00641
00642 for( wxIFMComponentArray::const_iterator i = children.begin(), end = children.end(); i != end; ++i, index++ )
00643 {
00644
00645 if( *i == destination )
00646 break;
00647 }
00648 }
00649
00650
00651 wxIFMDockEventEx dockevt(component, parent, index, id);
00652 GetIP()->ProcessPluginEvent(dockevt);
00653 }
00654 }
00655
00656 #if IFM_CANFLOAT
00657
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
00665 wxIFMUpdateComponentEvent updevt(window->GetComponent(), window->GetComponent()->m_rect);
00666 GetIP()->ProcessPluginEvent(updevt);
00667 }
00668
00669 if( m_floatingParent )
00670 {
00671 m_floatingParent->Update();
00672 }
00673 #endif
00674
00675
00676 GetManager()->Update();
00677 }
00678 #if IFM_CANFLOAT
00679 else
00680 {
00681 component->GetParentWindow()->SetFocus();
00682 }
00683
00684 if( destroy_floating_window )
00685 {
00686
00687
00688
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
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
00759
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
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
00806
00807
00808
00809
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
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
00831 wxIFMDockEvent dockevt1(container, dest, index);
00832 GetIP()->ProcessPluginEvent(dockevt1);
00833
00834
00835 wxIFMUndockEvent undockevt(child, false);
00836 GetIP()->ProcessPluginEvent(undockevt);
00837
00838
00839 wxIFMDockEvent dockevt2(child, container, IFM_DEFAULT_INDEX);
00840 GetIP()->ProcessPluginEvent(dockevt2);
00841
00842
00843
00844 wxIFMDockEventEx dockevt3(event.GetComponent(), container, 0, where);
00845 GetIP()->ProcessPluginEvent(dockevt3);
00846 }
00847
00848 return;
00849 }
00850 }
00851
00852
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
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
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
00887 wxRect client_rect = GetManager()->GetInterfaceRect();
00888 client_rect.SetPosition(GetManager()->GetParent()->ClientToScreen(client_rect.GetPosition()));
00889
00890
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
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
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
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
00915 pos.x = pos.y = 3000;
00916
00917
00918 btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_LEFT, IFM_DOCK_ICON_LEFT);
00919 _create_helper(m_dockButtonArray, btn);
00920
00921
00922 btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_TOP, IFM_DOCK_ICON_TOP);
00923 _create_helper(m_dockButtonArray, btn);
00924
00925
00926 btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_RIGHT, IFM_DOCK_ICON_RIGHT);
00927 _create_helper(m_dockButtonArray, btn);
00928
00929
00930 btn = new wxIFMDockTargetButton(parent, pos, IFM_DOCK_ID_BOTTOM, IFM_DOCK_ICON_BOTTOM);
00931 _create_helper(m_dockButtonArray, btn);
00932
00933
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
00942 m_dockButtonArray[i]->Destroy();
00943
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
00958 m_dockButtonArray[i]->Show(show);
00959
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
00975 m_dockButtonArray[i]->Show(show);
00976
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
01004
01005
01006
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
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
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
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
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
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
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
01094
01095
01096
01097
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
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
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
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
01129 {
01130 m_dockButtonArray[i]->SetComponent(component);
01131
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
01141 {
01142 btn = m_dockButtonArray[i];
01143
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
01160 {
01161 window = windows[i];
01162
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
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, 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 }