X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetCollapsable.cpp;h=668a91896ac1704c97cfb480de74d614cef1f626;hb=3d7ede605978461a6bd67b250925fcc8bf8404c3;hp=d656d7a29e65d0b3aaae6c20d0b4623f1d81baf4;hpb=7a5eff56b0498f478eb2120445bcf892cb809f41;p=lyx.git diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index d656d7a29e..668a91896a 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -33,6 +33,7 @@ #include "support/gettext.h" #include "support/lassert.h" #include "support/lstrings.h" +#include "support/RefChanger.h" using namespace std; @@ -40,7 +41,7 @@ using namespace std; namespace lyx { InsetCollapsable::InsetCollapsable(Buffer * buf, InsetText::UsePlain ltype) - : InsetText(buf, ltype), status_(Open), openinlined_(false) + : InsetText(buf, ltype), status_(Open) { setDrawFrame(true); setFrameColor(Color_collapsableframe); @@ -48,22 +49,20 @@ InsetCollapsable::InsetCollapsable(Buffer * buf, InsetText::UsePlain ltype) // The sole purpose of this copy constructor is to make sure -// that the mouse_hover_ map is not copied and remains empty. +// that the view_ map is not copied and remains empty. InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) : InsetText(rhs), status_(rhs.status_), - labelstring_(rhs.labelstring_), - button_dim(rhs.button_dim), - openinlined_(rhs.openinlined_) + labelstring_(rhs.labelstring_) {} InsetCollapsable::~InsetCollapsable() { - map::iterator it = mouse_hover_.begin(); - map::iterator end = mouse_hover_.end(); + map::iterator it = view_.begin(); + map::iterator end = view_.end(); for (; it != end; ++it) - if (it->second) + if (it->second.mouse_hover_) it->first->clearLastInset(this); } @@ -72,7 +71,7 @@ InsetCollapsable::CollapseStatus InsetCollapsable::status(BufferView const & bv) { if (decoration() == InsetLayout::CONGLOMERATE) return status_; - return auto_open_[&bv] ? Open : status_; + return view_[&bv].auto_open_ ? Open : status_; } @@ -81,7 +80,7 @@ InsetCollapsable::Geometry InsetCollapsable::geometry(BufferView const & bv) con switch (decoration()) { case InsetLayout::CLASSIC: if (status(bv) == Open) - return openinlined_ ? LeftButton : TopButton; + return view_[&bv].openinlined_ ? LeftButton : TopButton; return ButtonOnly; case InsetLayout::MINIMALISTIC: @@ -100,30 +99,6 @@ InsetCollapsable::Geometry InsetCollapsable::geometry(BufferView const & bv) con } -InsetCollapsable::Geometry InsetCollapsable::geometry() const -{ - switch (decoration()) { - case InsetLayout::CLASSIC: - if (status_ == Open) - return openinlined_ ? LeftButton : TopButton; - return ButtonOnly; - - case InsetLayout::MINIMALISTIC: - return status_ == Open ? NoButton : ButtonOnly ; - - case InsetLayout::CONGLOMERATE: - return status_ == Open ? SubLabel : Corners ; - - case InsetLayout::DEFAULT: - break; // this shouldn't happen - } - - // dummy return value to shut down a warning, - // this is dead code. - return NoButton; -} - - docstring InsetCollapsable::toolTip(BufferView const & bv, int x, int y) const { Dimension const dim = dimensionCollapsed(bv); @@ -179,7 +154,7 @@ Dimension InsetCollapsable::dimensionCollapsed(BufferView const & bv) const void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { - auto_open_[mi.base.bv] = mi.base.bv->cursor().isInside(this); + view_[mi.base.bv].auto_open_ = mi.base.bv->cursor().isInside(this); FontInfo tmpfont = mi.base.font; mi.base.font = getFont(); @@ -214,17 +189,16 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const case LeftButton: case ButtonOnly: if (hasFixedWidth()){ - const int mindim=button_dim.x2-button_dim.x1; - if (mi.base.textwidth(this)->setDrawFrame(false); - InsetText::draw(pi, textx, texty); - const_cast(this)->setDrawFrame(true); + { // We will take care of the frame and the change tracking cue + // ourselves, below. + Changer dummy = make_change(pi.change_, Change()); + const_cast(this)->setDrawFrame(false); + InsetText::draw(pi, textx, texty); + const_cast(this)->setDrawFrame(true); + } int desc = textdim.descent(); - if (geometry(bv) == Corners) + if (g == Corners) desc -= 3; + // Colour the frame according to the change type. (Like for tables.) + Color colour = pi.change_.changed() ? pi.change_.color() + : Color_foreground; const int xx1 = x + TEXT_TO_INSET_OFFSET - 1; const int xx2 = x + textdim.wid - TEXT_TO_INSET_OFFSET + 1; - pi.pain.line(xx1, y + desc - 4, - xx1, y + desc, - Color_foreground); + pi.pain.line(xx1, y + desc - 4, + xx1, y + desc, colour); if (status_ == Open) - pi.pain.line(xx1, y + desc, - xx2, y + desc, - Color_foreground); + pi.pain.line(xx1, y + desc, + xx2, y + desc, colour); else { // Make status_ value visible: pi.pain.line(xx1, y + desc, - xx1 + 4, y + desc, - Color_foreground); + xx1 + 4, y + desc, colour); pi.pain.line(xx2 - 4, y + desc, - xx2, y + desc, - Color_foreground); + xx2, y + desc, colour); } - pi.pain.line(x + textdim.wid - 3, y + desc, x + textdim.wid - 3, - y + desc - 4, Color_foreground); + pi.pain.line(x + textdim.wid - 3, y + desc, x + textdim.wid - 3, + y + desc - 4, colour); // the label below the text. Can be toggled. - if (geometry(bv) == SubLabel) { + if (g == SubLabel) { FontInfo font(getLabelfont()); + if (pi.change_.changed()) + font.setPaintColor(colour); font.realize(sane_font); font.decSize(); font.decSize(); @@ -348,23 +337,23 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const int const ww = max(textdim.wid, w); pi.pain.rectText(x + (ww - w) / 2, y + desc + a, buttonLabel(bv), font, Color_none, Color_none); - desc += d; } + int const y1 = y - textdim.asc + 3; // a visual cue when the cursor is inside the inset Cursor const & cur = bv.cursor(); if (cur.isInside(this)) { - y -= textdim.asc; - y += 3; - pi.pain.line(xx1, y + 4, xx1, y, Color_foreground); - pi.pain.line(xx1 + 4, y, xx1, y, Color_foreground); - pi.pain.line(xx2, y + 4, xx2, y, Color_foreground); - pi.pain.line(xx2 - 4, y, xx2, y, Color_foreground); + pi.pain.line(xx1, y1 + 4, xx1, y1, colour); + pi.pain.line(xx1 + 4, y1, xx1, y1, colour); + pi.pain.line(xx2, y1 + 4, xx2, y1, colour); + pi.pain.line(xx2 - 4, y1, xx2, y1, colour); } + // Strike through the inset if deleted and not already handled by + // RowPainter. + if (pi.change_.deleted() && canPaintChange(bv)) + pi.change_.paintCue(pi, xx1, y1, xx2, y + desc); break; } - - pi.base.font = tmpfont; } @@ -399,7 +388,13 @@ void InsetCollapsable::cursorPos(BufferView const & bv, bool InsetCollapsable::editable() const { - return geometry() != ButtonOnly; + switch (decoration()) { + case InsetLayout::CLASSIC: + case InsetLayout::MINIMALISTIC: + return status_ == Open; + default: + return true; + } } @@ -409,16 +404,9 @@ bool InsetCollapsable::descendable(BufferView const & bv) const } -bool InsetCollapsable::hitButton(FuncRequest const & cmd) const +bool InsetCollapsable::clickable(BufferView const & bv, int x, int y) const { - return button_dim.contains(cmd.x(), cmd.y()); -} - - -bool InsetCollapsable::clickable(int x, int y) const -{ - FuncRequest cmd(LFUN_NOACTION, x, y, mouse_button::none); - return hitButton(cmd); + return view_[&bv].button_dim_.contains(x, y); } @@ -455,8 +443,8 @@ Inset * InsetCollapsable::editXY(Cursor & cur, int x, int y) { //lyxerr << "InsetCollapsable: edit xy" << endl; if (geometry(cur.bv()) == ButtonOnly - || (button_dim.contains(x, y) - && geometry(cur.bv()) != NoButton)) + || (view_[&cur.bv()].button_dim_.contains(x, y) + && geometry(cur.bv()) != NoButton)) return this; cur.push(*this); return InsetText::editXY(cur, x, y); @@ -468,9 +456,11 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) //lyxerr << "InsetCollapsable::doDispatch (begin): cmd: " << cmd // << " cur: " << cur << " bvcur: " << cur.bv().cursor() << endl; + bool const hitButton = clickable(cur.bv(), cmd.x(), cmd.y()); + switch (cmd.action()) { case LFUN_MOUSE_PRESS: - if (hitButton(cmd)) { + if (hitButton) { switch (cmd.button()) { case mouse_button::button1: case mouse_button::button3: @@ -495,7 +485,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_MOTION: case LFUN_MOUSE_DOUBLE: case LFUN_MOUSE_TRIPLE: - if (hitButton(cmd)) + if (hitButton) cur.noScreenUpdate(); else if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); @@ -504,12 +494,12 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) break; case LFUN_MOUSE_RELEASE: - if (!hitButton(cmd)) { + if (!hitButton) { // The mouse click has to be within the inset! if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); else - cur.undispatched(); + cur.undispatched(); break; } if (cmd.button() != mouse_button::button1) { @@ -587,7 +577,7 @@ void InsetCollapsable::setLabel(docstring const & l) docstring const InsetCollapsable::buttonLabel(BufferView const & bv) const { InsetLayout const & il = getLayout(); - docstring const label = labelstring_.empty() ? + docstring const label = labelstring_.empty() ? translateIfPossible(il.labelstring()) : labelstring_; if (!il.contentaslabel() || geometry(bv) != ButtonOnly) return label; @@ -642,4 +632,23 @@ string InsetCollapsable::contextMenuName() const return "context-collapsable"; } + +bool InsetCollapsable::canPaintChange(BufferView const & bv) const +{ + // return false to let RowPainter draw the change tracking cue consistently + // with the surrounding text, when the inset is inline: for buttons, for + // non-allowMultiPar insets. + switch (geometry(bv)) { + case Corners: + case SubLabel: + return allowMultiPar(); + case ButtonOnly: + return false; + default: + break; + } + return true; +} + + } // namespace lyx