This is quick implementation of a long-standing feature request: autoopening/closing collapsables. This is really easy with the new scheme (most of this patch is a replace of status_ -> status())
On a side note, we should keep the following tree bools of insetcollapsable.h inside a "metrics cache" so they can be different in different bufferviews (and so one can open an inset in one of them and close it in another). How will these heterogeneous type caches (among different insets) would be best handled? What comes obviously to mind is a static map<BufferView *, something> in insetcollapsable.C. Or would it be better to have a more general mechanism somehow/where? /// mutable CollapseStatus status_; /// a substatus of the Open status, determined automatically in metrics mutable bool openinlined_; /// the inset will automatically open when the cursor is inside mutable bool autoOpen_; Opinions? Alfredo
Index: insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.264 diff -u -p -r1.264 insetcollapsable.C --- insetcollapsable.C 30 Nov 2004 01:59:47 -0000 1.264 +++ insetcollapsable.C 1 Dec 2004 01:38:52 -0000 @@ -39,6 +39,12 @@ using std::min; using std::ostream; +InsetCollapsable::CollapseStatus InsetCollapsable::status() const +{ + return autoOpen_ ? Open : status_; +} + + void leaveInset(LCursor & cur, InsetBase const & in) { for (unsigned int i = 0; i != cur.size(); ++i) { @@ -52,7 +58,8 @@ void leaveInset(LCursor & cur, InsetBase InsetCollapsable::InsetCollapsable (BufferParams const & bp, CollapseStatus status) - : InsetText(bp), label("Label"), status_(status), openinlined_(false) + : InsetText(bp), label("Label"), status_(status), + openinlined_(false), autoOpen_(false) { setAutoBreakRows(true); setDrawFrame(true); @@ -132,12 +139,14 @@ Dimension InsetCollapsable::dimensionCol void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { + autoOpen_ = mi.base.bv->cursor().isInside(this); mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET; - if (status_ == Inlined) { + + if (status() == Inlined) { InsetText::metrics(mi, dim); } else { dim = dimensionCollapsed(); - if (status_ == Open) { + if (status() == Open) { InsetText::metrics(mi, textdim_); openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth); if (openinlined_) { @@ -161,7 +170,7 @@ void InsetCollapsable::metrics(MetricsIn void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { const int xx = x + TEXT_TO_INSET_OFFSET; - if (status_ == Inlined) { + if (status() == Inlined) { InsetText::draw(pi, xx, y); } else { Dimension dimc = dimensionCollapsed(); @@ -172,7 +181,7 @@ void InsetCollapsable::draw(PainterInfo button_dim.y2 = top + dimc.height(); pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_); - if (status_ == Open) { + if (status() == Open) { int textx, texty; if (openinlined_) { textx = xx + dimc.width(); @@ -191,13 +200,13 @@ void InsetCollapsable::draw(PainterInfo void InsetCollapsable::drawSelection(PainterInfo & pi, int x, int y) const { x += TEXT_TO_INSET_OFFSET; - if (status_ == Open) { + if (status() == Open) { if (openinlined_) x += dimensionCollapsed().wid; else y += dimensionCollapsed().des + textdim_.asc; } - if (status_ != Collapsed) + if (status() != Collapsed) InsetText::drawSelection(pi, x, y); } @@ -205,14 +214,10 @@ void InsetCollapsable::drawSelection(Pai void InsetCollapsable::getCursorPos (CursorSlice const & sl, int & x, int & y) const { - if (status_ == Collapsed) { - x = xo(); - y = yo(); - return; - } + BOOST_ASSERT(status() != Collapsed); InsetText::getCursorPos(sl, x, y); - if (status_ == Open) { + if (status() == Open) { if (openinlined_) x += dimensionCollapsed().wid; else @@ -225,13 +230,13 @@ void InsetCollapsable::getCursorPos InsetBase::EDITABLE InsetCollapsable::editable() const { - return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; + return status() != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; } bool InsetCollapsable::descendable() const { - return status_ != Collapsed; + return status() != Collapsed; } @@ -267,14 +272,14 @@ void InsetCollapsable::edit(LCursor & cu //lyxerr << "InsetCollapsable: edit left/right" << endl; cur.push(*this); InsetText::edit(cur, left); - open(); +// open(); } InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y) const { //lyxerr << "InsetCollapsable: edit xy" << endl; - if (status_ == Collapsed) { + if (status() == Collapsed) { return const_cast<InsetCollapsable*>(this); } cur.push(const_cast<InsetCollapsable&>(*this)); @@ -289,9 +294,9 @@ void InsetCollapsable::doDispatch(LCurso switch (cmd.action) { case LFUN_MOUSE_PRESS: - if (status_ == Inlined) + if (status() == Inlined) InsetText::doDispatch(cur, cmd); - else if (status_ == Open && !hitButton(cmd)) + else if (status() == Open && !hitButton(cmd)) InsetText::doDispatch(cur, cmd); else cur.noUpdate(); @@ -300,7 +305,7 @@ void InsetCollapsable::doDispatch(LCurso case LFUN_MOUSE_MOTION: if (status_ == Inlined) InsetText::doDispatch(cur, cmd); - else if (status_ == Open && !hitButton(cmd)) + else if (status() && !hitButton(cmd)) InsetText::doDispatch(cur, cmd); else cur.undispatched(); @@ -312,11 +317,12 @@ void InsetCollapsable::doDispatch(LCurso break; } - switch (status_) { + switch (status()) { case Collapsed: lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl; edit(cur, true); + open(); cur.bv().cursor() = cur; break; Index: insetcollapsable.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.h,v retrieving revision 1.179 diff -u -p -r1.179 insetcollapsable.h --- insetcollapsable.h 30 Nov 2004 01:59:47 -0000 1.179 +++ insetcollapsable.h 1 Dec 2004 01:38:52 -0000 @@ -81,7 +81,7 @@ public: /// bool inlined() const { return status_ == Inlined; } /// - CollapseStatus status() const { return status_; } + CollapseStatus status() const; /// void open(); /// @@ -121,6 +121,8 @@ private: mutable CollapseStatus status_; /// a substatus of the Open status, determined automatically in metrics mutable bool openinlined_; + /// the inset will automatically open when the cursor is inside + mutable bool autoOpen_; /// mutable Dimension textdim_; };