// pre-docking handling -- Point p in SCREEN COORDINATES XMLToolBarFrame &XMLToolBarFrame::PreDock(XMLToolBarCtrl &tb, Point p) { if(preDocking) return *this; // get dock position int dockLine, col; bool insert; if(!GetDockTarget(tb, p, dockLine, insert, col)) return *this; preDocking = true; // if needed, shift all positions to make place for this toolbar line if(insert) { for(int i = 0; i < relativePositions.GetCount(); i++) if(relativePositions[i].cy >= dockLine) relativePositions[i].cy++; } // docks the toolbar there relativePositions.Add(Size(col, dockLine)); toolBars.Add(&tb); Reposition(); Layout(); return *this; }
XMLToolBarFrame &XMLToolBarFrame::DockAt(XMLToolBarCtrl &tb, Point p) { // should not happen, but.... if(FindIndex(tb) >= 0) return *this; // get dock position int dockLine, col; bool insert; if(!GetDockTarget(tb, p, dockLine, insert, col)) return *this; // if needed, shift all positions to make place for this toolbar line if(insert) { for(int i = 0; i < relativePositions.GetCount(); i++) if(relativePositions[i].cy >= dockLine) relativePositions[i].cy++; } // docks the toolbar there relativePositions.Add(Size(col, dockLine)); toolBars.Add(&tb); toolBarContainer.AddChild(&tb); Reposition(); Layout(); tb.toolBarPos = Point(relativePositions.Top().cx, relativePositions.Top().cy); return *this; }
// // if the dockpanel is moving, and it's caused by us, // then we need to decide whether to dock it or keep it floating // LRESULT DockPanel_OnMoving(DOCKPANEL *dppThis) { POINT ptCurrent; RECT rect; POINT pt; RECT r; DOCKPANEL *dppUnder; UINT area; if(!dppThis->fDragging) return 0; GetCursorPos(&pt); area = GetDockTarget(dppThis->pDockServer, dppThis, pt, &r, &dppUnder); if(dppUnderLast != dppUnder || lastArea != area) { if(1)//dppUnderLast != dppUnder) { // kick off timer if(hwndTransPanel != 0) { hwndAnimPanel = hwndTransPanel; SetWindowLongPtr(hwndAnimPanel, GWLP_USERDATA, 255); SetTimer(dppThis->hwndPanel, (UINT_PTR)hwndAnimPanel, 10, 0); hwndTransPanel = 0; } } else { DestroyWindow(hwndTransPanel); hwndTransPanel = 0; } } dppUnderLast = dppUnder; lastArea = area; if(hwndTransPanel == 0) { hwndTransPanel = ShowTransWindow(dppThis, dppThis->hwndPanel, &r, area ? area : DWS_DOCKED_MASK, area ? 3 : 0); } GetWindowRect(dppThis->hwndPanel, &rect); dppThis->xpos = rect.left;//(short)LOWORD(lParam); dppThis->ypos = rect.top;///(short)HIWORD(lParam); g_dppTargetDockPanel = 0; GetCursorPos(&ptCurrent); return 0; }
// // Called when the dockpanel has stopped being dragged around // need to decide whether to dock/undock/leave it as it is // LRESULT DockPanel_ExitSizeMove(DOCKPANEL *dpp) { extern HWND hwndTransPanel; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; DockPanel_RemoveKeyboardHook(dpp); dpp->fUndockNextMsg = FALSE; if(dpp->fDragging) { DOCKSERVER *dsp = dpp->pDockServer; DOCKPANEL *dppUnder; RECT rectDrag; POINT pt; UINT area; HWND hwnd; DestroyWindow(hwndTransPanel); hwndTransPanel = 0; dpp->fDragging = FALSE; GetCursorPos(&pt); area = GetDockTarget(dpp->pDockServer, dpp, pt, &rectDrag, &dppUnder); // did we want to dock onto anything? if(area != 0)//dpp->fDragStatus || g_dppTargetDockPanel) { ShowWindow(dpp->hwndPanel, SW_HIDE); RemoveWindowTrans(dpp->hwndPanel); // docking onto an existing DOCKPANEL (i.e. not the main window, // but becoming a tab in another panel) if(area == TAB) { // move all DOCKWNDs in the current panel to the DOCKPANEL // that we are dragging on to DOCKWND *dwp, *next = 0; for(dwp = dpp->WndListHead->flink; dwp != dpp->WndListTail; dwp = next)//dwp->flink) { next = dwp->flink; SetDockPanel(dppUnder, dwp); DockWnd_Show(dpp->hwndMain, dwp->uWndId, TRUE); } UpdateDockTabView(dppUnder); // oof! RemoveObj(dpp); hwnd = dpp->hwndPanel; dpp->hwndPanel = 0; DestroyWindow(hwnd);//dpp->hwndPanel); } // otherwise dock with the main window else { // if docking on the inside, // move to end of dock-panel list if(dppUnder == (DOCKPANEL *)1) // NASTY HACK!! WHY!??? { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListTail); } // if docking else if(dppUnder) { if( area == TOP && (dppUnder->dwStyle & BOTTOM) || area == BOTTOM && (dppUnder->dwStyle & TOP) || area == LEFT && (dppUnder->dwStyle & RIGHT) || area == RIGHT && (dppUnder->dwStyle & LEFT)) { // inside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder->flink); if(area == TOP) area = BOTTOM; else if(area == BOTTOM) area = TOP; else if(area == LEFT) area = RIGHT; else if(area == RIGHT) area = LEFT; } else if( area == TOP && (dppUnder->dwStyle & TOP) || area == BOTTOM && (dppUnder->dwStyle & BOTTOM) || area == LEFT && (dppUnder->dwStyle & LEFT) || area == RIGHT && (dppUnder->dwStyle & RIGHT)) { // outside of target panel RemoveObj(dpp); InsertBefore(dpp, dppUnder); } } // if docking against the outside edge else { RemoveObj(dpp); InsertBefore(dpp, dsp->PanelListHead->flink); } dpp->dwStyle = (dpp->dwStyle & ~DWS_DOCKED_MASK) | area; DockWindow(dpp); } ShowWindow(dpp->hwndPanel, SW_SHOW); } dpp->fDragging = FALSE; dpp->fDragStatus = 0; } // if the dock-panel is still floating, determine if it's edges // intersect the main window, and turn on the 'sticky' flag if(dpp->fDocked == FALSE) { RECT r1, r2, r3; GetWindowRect(dpp->hwndMain, &r2); GetWindowRect(dpp->hwndPanel, &r3); dpp->fSticky = IntersectRect(&r1, &r2, &r3); } return 0; }