DockCont *DockWindow::FindDockTarget(DockCont &dc, int &dock) { Point p = GetMousePos(); Rect r = GetScreenView(); DockCont *target = NULL; int align = DOCK_NONE; dock = DOCK_NONE; if (r.Contains(p)) { dock = GetPointAlign(p, r, true, true, true); if (dock != DOCK_NONE && dockpane[dock].IsVisible()) dock = DOCK_NONE; } else { target = GetMouseDockTarget(); if (target) { r = target->GetScreenRect(); dock = GetDockAlign(*target); align = GetPointAlign(p, r, IsTabbing(), IsTB(dock), !IsTB(dock)); } else return NULL; } if (dock != DOCK_NONE && (!dc.IsDockAllowed(dock) || IsPaneAnimating(dock) || IsFrameAnimating(dock)) || (dock == DOCK_NONE && !target)) { dock = DOCK_NONE; return NULL; } // Prepare for highlight if (target) { GetHighlightCtrl().bounds = GetAlignBounds(align, r, IsTabbing(), IsTB(dock), !IsTB(dock)); if (align == DOCK_NONE) dock = DOCK_NONE; // Tabbing // The following code handles the case of an insertion between two docked controls. In this case we must set // the highlight bounds to be a union of the bounds from each control. Very ugly. if (dock != DOCK_NONE) { Ctrl *c = IsTL(align) ? target->GetPrev() : target->GetNext(); if (c) { int opal = align > 1 ? align-2 : align+2; GetHighlightCtrl().bounds.Union(GetAlignBounds(opal, c->GetScreenRect(), IsTabbing())); } target = IsTL(align) ? target : dynamic_cast<DockCont*>(target->GetNext()); } } else if (dock != DOCK_NONE) GetHighlightCtrl().bounds = GetAlignBounds(dock, r, true); return target; }
void PopUpDockWindow::ContainerDragMove(DockCont &dc) { int align = DOCK_NONE; // Is the highlight the same as last time? (Quick escape) if (last_popup && last_popup->IsPopUp() && last_popup->GetRect().Contains(GetMousePos())) return; DockCont *target = GetMouseDockTarget(); int dock = DOCK_NONE; if (target) { dock = GetDockAlign(*target); if (!dc.IsDockAllowed(dock)) target = NULL; } bool target_changed = (target != last_target) && !GetHighlightCtrl().GetParent() && (!target || !IsPaneAnimating(dock)); // Hide show inner popups as necessary if (!target && last_target != NULL) HidePopUps(true, false); else if (target_changed) ShowInnerPopUps(dc, target); ShowOuterPopUps(dc); last_target = target; // Get potential alignment align = PopUpHighlight(inner, 5); if (align == DOCK_NONE) { target = NULL; last_target = NULL; align = PopUpHighlight(outer, 4); } else if (align == 4) align = DOCK_NONE; else if (target) { target = IsTL(align) ? target : dynamic_cast<DockCont*>(target->GetNext()); align = dock; } // Do highlight if (align != DOCK_NONE || target) { if (align == DOCK_NONE) StopHighlight(false); dc.SyncUserSize(true, true); Highlight(align, dc, target); } else { StopHighlight(IsAnimatedHighlight()); last_popup = NULL; } }
void DockWindow::SerializeLayout(Stream &s, bool withsavedlayouts) { StopHighlight(false); int cnt = 0; s.Magic(); // Groups ArrayMap<String, Vector<int> > groups; if (s.IsStoring()) for (int i = 0; i < dockers.GetCount(); i++) { String g = dockers[i]->GetGroup(); if (!g.IsEmpty()) { int ix = groups.Find(g); if (ix < 0) { groups.Add(dockers[i]->GetGroup(), Vector<int>()); ix = groups.GetCount() - 1; } groups[ix].Add(i); } } s % groups; if (s.IsLoading()) { ClearLayout(); for (int i = 0; i < dockers.GetCount(); i++) dockers[i]->SetGroup(Null); for (int i = 0; i < groups.GetCount(); i++) { Vector<int> &v = groups[i]; const String &g = groups.GetKey(i); for (int j = 0; j < v.GetCount(); j++) { int ix = v[j]; if (ix >= 0 && ix < dockers.GetCount()) dockers[ix]->SetGroup(g); } } } if (s.IsStoring()) { // Write docked for (int i = 0; i < 4; i++) { DockPane &pane = dockpane[i]; int fsz = dockframe[i].IsShown() ? dockframe[i].GetSize() : 0; s / fsz % pane; DockCont *dc = dynamic_cast<DockCont *>(pane.GetFirstChild()); for (int j = 0; dc && j < pane.GetCount(); j++) { s % *dc; dc = dynamic_cast<DockCont *>(dc->GetNext()); } } cnt = 0; // Count Floating for (int i = 0; i < conts.GetCount(); i++) if (conts[i].IsFloating()) cnt++; // Write Floating s / cnt; for (int i = 0; i < conts.GetCount(); i++) { if (conts[i].IsFloating()) { conts[i].Serialize(s); conts[i].SerializePlacement(s, false); } } // Write Autohidden for (int i = 0; i < 4; i++) { cnt = hideframe[i].GetCount(); s / cnt; for (int j = 0; j < hideframe[i].GetCount(); j++) { int ix = FindDocker(&hideframe[i].GetCtrl(j)->Get(0)); if (ix >= 0) s / ix; } } } else { // Read docked for (int i = 0; i < 4; i++) { DockPane &pane = dockpane[i]; dockframe[i].Hide(); int fsz; s / fsz % pane; for (int j = 0; j < pane.GetCount(); j++) { DockCont *dc = CreateContainer(); s % *dc; dc->StateDocked(*this); pane << *dc; } if (fsz && pane.GetCount()) { dockframe[i].SetSize(fsz); dockframe[i].Show(); } else dockframe[i].SetSize(0); } // Read floating s / cnt; for (int i = 0; i < cnt; i++) { DockCont *dc = CreateContainer(); dc->Serialize(s); FloatContainer(*dc); dc->SerializePlacement(s, false); } // Read Autohidden for (int i = 0; i < 4; i++) { s / cnt; for (int j = 0; j < cnt; j++) { int ix; s / ix; if (ix >= 0 && ix < dockers.GetCount()) AutoHide(i, *dockers[ix]); } } // Clear empty containers for (int i = conts.GetCount()-1; i >= 0; i--) { if (!conts.GetCount()) CloseContainer(conts[i]); } RefreshLayout(); } bool haslay = withsavedlayouts; s % haslay; if (withsavedlayouts && (s.IsStoring() || haslay)) s % layouts; s.Magic(); }