diff options
-rw-r--r-- | basctl/source/basicide/baside3.cxx | 4 | ||||
-rw-r--r-- | basctl/source/basicide/bastypes.cxx | 4 | ||||
-rw-r--r-- | basctl/source/basicide/layout.cxx | 202 | ||||
-rw-r--r-- | basctl/source/basicide/layout.hxx | 25 | ||||
-rw-r--r-- | basctl/source/inc/bastypes.hxx | 6 |
5 files changed, 146 insertions, 95 deletions
diff --git a/basctl/source/basicide/baside3.cxx b/basctl/source/basicide/baside3.cxx index 6b137d2af311..2d22e5083eaa 100644 --- a/basctl/source/basicide/baside3.cxx +++ b/basctl/source/basicide/baside3.cxx @@ -1437,13 +1437,15 @@ void DialogWindowLayout::ShowPropertyBrowser () { // creating pPropertyBrowser = new PropBrw(*this); + pPropertyBrowser->Show(); // after OnFirstSize(): if (HasSize()) AddPropertyBrowser(); // updating if neccessary UpdatePropertyBrowser(); } - pPropertyBrowser->Show(); + else + pPropertyBrowser->Show(); // refreshing the button state if (SfxBindings* pBindings = GetBindingsPtr()) pBindings->Invalidate(SID_SHOW_PROPERTYBROWSER); diff --git a/basctl/source/basicide/bastypes.cxx b/basctl/source/basicide/bastypes.cxx index bc4d32babc81..384566d3ad9e 100644 --- a/basctl/source/basicide/bastypes.cxx +++ b/basctl/source/basicide/bastypes.cxx @@ -308,6 +308,10 @@ void DockingWindow::ResizeIfDocking (Point const& rPos, Size const& rSize) SetPosSizePixel(rPos, rSize); } } +void DockingWindow::ResizeIfDocking (Size const& rSize) +{ + ResizeIfDocking(aDockingRect.TopLeft(), rSize); +} // Sets the parent Layout window. // The physical parent is set only when the window is docking. diff --git a/basctl/source/basicide/layout.cxx b/basctl/source/basicide/layout.cxx index 32edb585fdac..752f830ed89b 100644 --- a/basctl/source/basicide/layout.cxx +++ b/basctl/source/basicide/layout.cxx @@ -73,34 +73,36 @@ void Layout::Resize() // ArrangeWindows() -- arranges the child windows void Layout::ArrangeWindows () { - Size const aSize = GetOutputSizePixel(); - int const nWidth = aSize.Width(), nHeight = aSize.Height(); - if (!nWidth || !nHeight) // empty size - return; - // prevent recursion via OnFirstSize() -> Add() -> ArrangeWindows() - static bool bRecursion = false; - if (bRecursion) + static bool bInArrangeWindows = false; + if (bInArrangeWindows) return; - bRecursion = true; + bInArrangeWindows = true; - // on first call - if (bFirstSize) + Size const aSize = GetOutputSizePixel(); + int const nWidth = aSize.Width(), nHeight = aSize.Height(); + if (nWidth && nHeight) // non-empty size { - bFirstSize = false; - this->OnFirstSize(nWidth, nHeight); // virtual - } + // On first call the derived classes initializes the sizes of the + // docking windows. This cannot be done at construction because + // the Layout has empty size at that point. + if (bFirstSize) + { + bFirstSize = false; + this->OnFirstSize(nWidth, nHeight); // virtual + } - // sides - aBottomSide.ArrangeIn(Rectangle(Point(0, 0), aSize)); - aLeftSide.ArrangeIn(Rectangle(Point(0, 0), Size(nWidth, nHeight - aBottomSide.GetSize()))); - // child in the middle - pChild->SetPosSizePixel( - Point(aLeftSide.GetSize(), 0), - Size(nWidth - aLeftSide.GetSize(), nHeight - aBottomSide.GetSize()) - ); + // sides + aBottomSide.ArrangeIn(Rectangle(Point(0, 0), aSize)); + aLeftSide.ArrangeIn(Rectangle(Point(0, 0), Size(nWidth, nHeight - aBottomSide.GetSize()))); + // child in the middle + pChild->SetPosSizePixel( + Point(aLeftSide.GetSize(), 0), + Size(nWidth - aLeftSide.GetSize(), nHeight - aBottomSide.GetSize()) + ); + } - bRecursion = false; + bInArrangeWindows = false; } void Layout::DockaWindow (DockingWindow*) @@ -159,7 +161,6 @@ void Layout::DataChanged (DataChangedEvent const& rDCEvt) // ctor Layout::SplittedSide::SplittedSide (Layout* pParent, Side eSide) : rLayout(*pParent), - bFirstArrange(true), bVertical(eSide == Left || eSide == Right), bLower(eSide == Left || eSide == Top), nSize(0), @@ -179,19 +180,18 @@ void Layout::SplittedSide::Add (DockingWindow* pWin, Size const& rSize) if (nSize1 > nSize) nSize = nSize1; // window - vWindows.push_back(pWin); - // split line - if (vWindows.size() > 1) + Item aItem; + aItem.pWin = pWin; + aItem.nStartPos = vItems.empty() ? 0 : vItems.back().nEndPos + nSplitThickness; + aItem.nEndPos = aItem.nStartPos + nSize2; + // splitter + if (!vItems.empty()) { - vSplitters.push_back(boost::make_shared<Splitter>( - &rLayout, bVertical ? WB_VSCROLL : WB_HSCROLL - )); - Splitter& rSplitter = *vSplitters.back(); - rSplitter.SetSplitPosPixel(nLastPos - nSplitThickness); - InitSplitter(rSplitter); + aItem.pSplit = boost::make_shared<Splitter>(&rLayout, bVertical ? WB_VSCROLL : WB_HSCROLL); + aItem.pSplit->SetSplitPosPixel(aItem.nStartPos - nSplitThickness); + InitSplitter(*aItem.pSplit); } - // nLastPos - nLastPos += nSize2 + nSplitThickness; + vItems.push_back(aItem); // refresh rLayout.ArrangeWindows(); } @@ -200,22 +200,17 @@ void Layout::SplittedSide::Add (DockingWindow* pWin, Size const& rSize) void Layout::SplittedSide::Remove (DockingWindow* pWin) { // contains? - std::vector<DockingWindow*>::iterator const itWin = - std::find(vWindows.begin(), vWindows.end(), pWin); - if (itWin == vWindows.end()) + unsigned iWin; + for (iWin = 0; iWin != vItems.size(); ++iWin) + if (vItems[iWin].pWin == pWin) + break; + if (iWin == vItems.size()) return; - // index - unsigned const iWin = itWin - vWindows.begin(); - // nLastPos - if (iWin == vWindows.size() - 1) // that is the last one - nLastPos = vSplitters.back()->GetSplitPosPixel() + nSplitThickness; // remove - vWindows.erase(itWin); - // remove a splitter line - if (!vSplitters.empty()) - vSplitters.pop_back(); - // refresh - rLayout.ArrangeWindows(); + vItems.erase(vItems.begin() + iWin); + // if that was the first one, remove the first splitter line + if (iWin == 0 && !vItems.empty()) + vItems.front().pSplit.reset(); } // creating a Point or a Size object @@ -229,11 +224,17 @@ inline Point Layout::SplittedSide::MakePoint (int A, int B) const return bVertical ? Point(B, A) : Point(A, B); } +// IsDocking() -- is this window currently docking in the strip? +bool Layout::SplittedSide::IsDocking (DockingWindow const& rWin) +{ + return rWin.IsVisible() && !rWin.IsFloatingMode(); +} + // IsEmpty() -- are there no windows docked in this strip? bool Layout::SplittedSide::IsEmpty () const { - for (unsigned i = 0; i != vWindows.size(); ++i) - if (vWindows[i]->IsVisible() && !vWindows[i]->IsFloatingMode()) + for (unsigned i = 0; i != vItems.size(); ++i) + if (IsDocking(*vItems[i].pWin)) return false; return true; } @@ -261,57 +262,61 @@ void Layout::SplittedSide::ArrangeIn (Rectangle const& rRect) int const nPos2 = bVertical ? aRect.Top() : aRect.Left(); // main line + bool const bEmpty = IsEmpty(); + // shown if any of the windows is docked + if (!bEmpty) { - // shown if any of the windows is docked - if (!IsEmpty()) - { - aSplitter.Show(); - // split position - aSplitter.SetSplitPosPixel((bLower ? nSize : nPos1) - nSplitThickness); - // the actual position and size - aSplitter.SetPosSizePixel( - MakePoint(nPos2, aSplitter.GetSplitPosPixel()), - MakeSize(nLength, nSplitThickness) - ); - // dragging rectangle - aSplitter.SetDragRectPixel(aRect); - } - else - aSplitter.Hide(); + aSplitter.Show(); + // split position + aSplitter.SetSplitPosPixel((bLower ? nSize : nPos1) - nSplitThickness); + // the actual position and size + aSplitter.SetPosSizePixel( + MakePoint(nPos2, aSplitter.GetSplitPosPixel()), + MakeSize(nLength, nSplitThickness) + ); + // dragging rectangle + aSplitter.SetDragRectPixel(aRect); } + else + aSplitter.Hide(); // positioning separator lines and windows - bool bPrevDocked = false; // is the previous window docked? - int nStartPos = nPos2; // window position in the strip - for (unsigned i = 0; i != vWindows.size(); ++i) + bool bPrevDocking = false; // is the previous window docked? + int nStartPos = 0; // window position in the strip + unsigned iLastWin; // index of last docking window in the strip + // (iLastWin will be initialized if !bEmpty) + for (unsigned i = 0; i != vItems.size(); ++i) { // window - DockingWindow& rWin = *vWindows[i]; - bool const bDocked = rWin.IsVisible() && !rWin.IsFloatingMode(); - // The window is docked between nStartPos and nEndPos along. - int const nEndPos = i == vWindows.size() - 1 ? - nPos2 + nLength : vSplitters[i]->GetSplitPosPixel(); + DockingWindow& rWin = *vItems[i].pWin; + bool const bDocking = IsDocking(rWin); + if (bDocking) + iLastWin = i; + // sizing window rWin.ResizeIfDocking( - MakePoint(nStartPos, nPos1), - MakeSize(nEndPos - nStartPos, nSize - nSplitThickness) + MakePoint(nPos2 + nStartPos, nPos1), + MakeSize(vItems[i].nEndPos - nStartPos, nSize - nSplitThickness) ); // splitting line before the window if (i > 0) { - Splitter& rSplit = *vSplitters[i - 1]; + Splitter& rSplit = *vItems[i].pSplit; // If neither of two adjacent windows are docked, // the splitting line is hidden. - if (bDocked || bPrevDocked) + // If this window is docking but the previous isn't, + // then the splitting line is also hidden, because this window + // will occupy the space of the previous. + if (bPrevDocking) { rSplit.Show(); // the actual pozition and size of the line rSplit.SetPosSizePixel( - MakePoint(nStartPos - nSplitThickness, nPos1), + MakePoint(nPos2 + nStartPos - nSplitThickness, nPos1), MakeSize(nSplitThickness, nSize - nSplitThickness) ); // the dragging rectangle rSplit.SetDragRectPixel(Rectangle( - MakePoint(bVertical ? aRect.Top() : aRect.Left(), nPos1), + MakePoint(nPos2, nPos1), MakeSize(nLength, nSize - nSplitThickness) )); } @@ -319,26 +324,53 @@ void Layout::SplittedSide::ArrangeIn (Rectangle const& rRect) rSplit.Hide(); } // next - bPrevDocked = bDocked; - nStartPos = nEndPos + nSplitThickness; + bPrevDocking = bDocking; + if (bDocking) + nStartPos = vItems[i].nEndPos + nSplitThickness; + // We only set nStartPos if this window is docking, because otherwise + // the next window will occupy also the space of this window. } - // first arrange - bFirstArrange = false; + // filling the remaining space with the last docking window + if (!bEmpty && vItems[iLastWin].nEndPos != nLength) + { + Item& rItem = vItems[iLastWin]; + Size aSize = rItem.pWin->GetDockingSize(); + (bVertical ? aSize.Height() : aSize.Width()) += nLength - rItem.nEndPos; + rItem.pWin->ResizeIfDocking(aSize); + // and hiding the split line after the window + if (iLastWin < vItems.size() - 1) + vItems[iLastWin + 1].pSplit->Hide(); + } } IMPL_LINK(Layout::SplittedSide, SplitHdl, Splitter*, pSplitter) { // checking margins CheckMarginsFor(pSplitter); - // nSize has to be changed? + // changing stored sizes if (pSplitter == &aSplitter) { + // nSize if (bLower) nSize = pSplitter->GetSplitPosPixel(); else nSize = (bVertical ? aRect.Right() : aRect.Bottom()) + 1 - pSplitter->GetSplitPosPixel(); } + else + { + // Item::nStartPos, Item::nLength + for (unsigned i = 1; i < vItems.size(); ++i) + { + if (vItems[i].pSplit.get() == pSplitter) + { + // before the line + vItems[i - 1].nEndPos = pSplitter->GetSplitPosPixel(); + // after the line + vItems[i].nStartPos = pSplitter->GetSplitPosPixel() + nSplitThickness; + } + } + } // arranging windows rLayout.ArrangeWindows(); diff --git a/basctl/source/basicide/layout.hxx b/basctl/source/basicide/layout.hxx index 6a63547f5acf..127f77e80f77 100644 --- a/basctl/source/basicide/layout.hxx +++ b/basctl/source/basicide/layout.hxx @@ -91,8 +91,6 @@ private: private: // the layout window Layout& rLayout; - // ArrangeIn() is called at first time? - bool bFirstArrange; // horizontal or vertical strip? bool bVertical; // lower (top or left) or higher (bottom or right) strip? @@ -105,15 +103,28 @@ private: int nLastPos; // the main splitting line Splitter aSplitter; - // the dockable windows - std::vector<DockingWindow*> vWindows; - // splitting lines between the docking windows (vWindows.size() - 1) - std::vector<boost::shared_ptr<Splitter> > vSplitters; - + // the dockable windows (and some data) + struct Item + { + // pointer to the dockable window + DockingWindow* pWin; + // starting and ending position in the strip + // They may be different from the actual window position, because + // the window may fill the space of the adjacent currently + // non-docking windows, but this change is not stored in these + // variables. These change only when the splitter lines are moved. + int nStartPos, nEndPos; + // splitter line window before the window + // (the first one is always nullptr) + boost::shared_ptr<Splitter> pSplit; + }; + std::vector<Item> vItems; private: Point MakePoint (int, int) const; Size MakeSize (int, int) const; private: + static bool IsDocking (DockingWindow const&); + private: DECL_LINK(SplitHdl, Splitter*); void CheckMarginsFor (Splitter*); void InitSplitter (Splitter&); diff --git a/basctl/source/inc/bastypes.hxx b/basctl/source/inc/bastypes.hxx index 6d24dae1e6b9..d7d2e69d0196 100644 --- a/basctl/source/inc/bastypes.hxx +++ b/basctl/source/inc/bastypes.hxx @@ -82,6 +82,8 @@ public: DockingWindow (Layout* pParent); public: void ResizeIfDocking (Point const&, Size const&); + void ResizeIfDocking (Size const&); + Size GetDockingSize () const { return aDockingRect.GetSize(); } void SetLayoutWindow (Layout*); public: void Show (bool = true); @@ -228,9 +230,9 @@ public: virtual void OnNewDocument (); virtual char const* GetHid () const = 0; - virtual ItemType GetType () const = 0; // TODO + virtual ItemType GetType () const = 0; void InsertLibInfo () const; - bool Is (ScriptDocument const&, rtl::OUString const&, rtl::OUString const&, ItemType, bool bFindSuspended); // TODO + bool Is (ScriptDocument const&, rtl::OUString const&, rtl::OUString const&, ItemType, bool bFindSuspended); virtual bool HasActiveEditor () const; }; |