]> git.lyx.org Git - features.git/commitdiff
Change tracking cue: InsetText and InsetCollapsible
authorGuillaume Munch <gm@lyx.org>
Mon, 23 May 2016 09:01:29 +0000 (10:01 +0100)
committerGuillaume Munch <gm@lyx.org>
Sun, 3 Jul 2016 21:38:37 +0000 (23:38 +0200)
* Underline or strike through the label as if it was text (it is).

* Strike through deleted InsetText, but let RowPainter handle the case of
  non-MultiPar text insets.

* Change the colour of the frame as a cue, unless its colour is customised (not
  Color_foreground). (Essentially do the border of CharStyles like Tabular does
  it already.)

* The change info needs to be reset when entering InsetText. Otherwise labels
  are painted with the change of their n+1-th parent.

src/insets/InsetCollapsable.cpp
src/insets/InsetText.cpp
src/insets/InsetText.h

index 294c82646645da685dcd8f997ae8a7d865df7eef..520d902dcbbc492530fae22d629610049435887a 100644 (file)
@@ -33,6 +33,7 @@
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/RefChanger.h"
 
 using namespace std;
 
@@ -228,9 +229,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
 
        view_[&bv].auto_open_ = bv.cursor().isInside(this);
 
-       FontInfo tmpfont = pi.base.font;
-       pi.base.font = getFont();
-       pi.base.font.realize(tmpfont);
+       Changer dummy = pi.base.font.change(getFont(), true);
 
        // Draw button first -- top, left or only
        Dimension dimc = dimensionCollapsed(bv);
@@ -246,7 +245,11 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
                FontInfo labelfont = getLabelfont();
                labelfont.setColor(labelColor());
                pi.pain.buttonText(x, y, buttonLabel(bv), labelfont,
-                       view_[&bv].mouse_hover_);
+                                  view_[&bv].mouse_hover_);
+               // Draw the change tracking cue on the label, unless RowPainter already
+               // takes care of it.
+               if (canPaintChange(bv))
+                       pi.change_.paintCue(pi, x, y, x + dimc.width(), labelfont);
        } else {
                view_[&bv].button_dim_.x1 = 0;
                view_[&bv].button_dim_.y1 = 0;
@@ -257,17 +260,24 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
        Dimension const textdim = InsetText::dimension(bv);
        int const baseline = y;
        int textx, texty;
-       switch (geometry(bv)) {
+       Geometry g = geometry(bv);
+       switch (g) {
        case LeftButton:
-               textx = x + dimc.width();
-               texty = baseline;
-               InsetText::draw(pi, textx, texty);
-               break;
-       case TopButton:
-               textx = x;
-               texty = baseline + dimc.des + textdim.asc;
+       case TopButton: {
+               if (g == LeftButton) {
+                       textx = x + dimc.width();
+                       texty = baseline;
+               } else {
+                       textx = x;
+                       texty = baseline + dimc.des + textdim.asc;
+               }
+               // Do not draw the cue for INSERTED -- it is already in the button and
+               // that's enough.
+               Changer dummy = make_change(pi.change_, Change(),
+                                           pi.change_.type == Change::INSERTED);
                InsetText::draw(pi, textx, texty);
                break;
+       }
        case ButtonOnly:
                break;
        case NoButton:
@@ -279,38 +289,43 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
        case Corners:
                textx = x;
                texty = baseline;
-               const_cast<InsetCollapsable *>(this)->setDrawFrame(false);
-               InsetText::draw(pi, textx, texty);
-               const_cast<InsetCollapsable *>(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<InsetCollapsable *>(this)->setDrawFrame(false);
+                       InsetText::draw(pi, textx, texty);
+                       const_cast<InsetCollapsable *>(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);
+                            xx1, y + desc, colour);
                if (status_ == Open)
                        pi.pain.line(xx1, y + desc,
-                               xx2, y + desc,
-                               Color_foreground);
+                                    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);
+                            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();
@@ -323,20 +338,21 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
                                buttonLabel(bv), font, Color_none, Color_none);
                }
 
+               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;
 }
 
 
@@ -618,16 +634,18 @@ string InsetCollapsable::contextMenuName() const
 
 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:
-               // these cases are handled by RowPainter since the inset is inline.
                return false;
        default:
                break;
        }
-       // TODO: implement the drawing in the remaining cases
        return true;
 }
 
index 7d28020669caff829576a2919f71254dea8013bd..99b1381f93d9961914dfd163d4c58ab0bd247bb7 100644 (file)
 #include "frontends/alert.h"
 #include "frontends/Painter.h"
 
+#include "support/bind.h"
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/gettext.h"
-#include "support/lstrings.h"
-
-#include "support/bind.h"
 #include "support/lassert.h"
+#include "support/lstrings.h"
+#include "support/RefChanger.h"
 
 #include <algorithm>
 
@@ -215,24 +215,48 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
 {
        TextMetrics & tm = pi.base.bv->textMetrics(&text_);
 
+       int const w = tm.width() + TEXT_TO_INSET_OFFSET;
+       int const yframe = y - TEXT_TO_INSET_OFFSET - tm.ascent();
+       int const h = tm.height() + 2 * TEXT_TO_INSET_OFFSET;
+       int const xframe = x + TEXT_TO_INSET_OFFSET / 2;
+       bool change_drawn = false;
        if (drawFrame_ || pi.full_repaint) {
-               int const w = tm.width() + TEXT_TO_INSET_OFFSET;
-               int const yframe = y - TEXT_TO_INSET_OFFSET - tm.ascent();
-               int const h = tm.height() + 2 * TEXT_TO_INSET_OFFSET;
-               int const xframe = x + TEXT_TO_INSET_OFFSET / 2;
                if (pi.full_repaint)
                        pi.pain.fillRectangle(xframe, yframe, w, h,
                                pi.backgroundColor(this));
 
+               // Change color of the frame in tracked changes, like for tabulars.
+        // Only do so if the color is not custom. But do so even if RowPainter
+        // handles the strike-through already.
+               Color c;
+               if (pi.change_.changed()
+                   // Originally, these are the colors with role Text, from role() in
+                   // ColorCache.cpp.  The code is duplicated to avoid depending on Qt
+                   // types, and also maybe it need not match in the future.
+                   && (frameColor() == Color_foreground
+                       || frameColor() == Color_cursor
+                       || frameColor() == Color_preview
+                       || frameColor() == Color_tabularline
+                       || frameColor() == Color_previewframe)) {
+                       c = pi.change_.color();
+                       change_drawn = true;
+               } else
+                       c = frameColor();
                if (drawFrame_)
-                       pi.pain.rectangle(xframe, yframe, w, h, frameColor());
+                       pi.pain.rectangle(xframe, yframe, w, h, c);
        }
-       ColorCode const old_color = pi.background_color;
-       pi.background_color = pi.backgroundColor(this, false);
-
-       tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y);
-
-       pi.background_color = old_color;
+       {
+               Changer dummy = make_change(pi.background_color,
+                                           pi.backgroundColor(this, false));
+               // The change tracking cue must not be inherited
+               Changer dummy2 = make_change(pi.change_, Change());
+               tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y);
+       }
+       if (canPaintChange(*pi.base.bv) && (!change_drawn || pi.change_.deleted()))
+               // Do not draw the change tracking cue if already done by RowPainter and
+               // do not draw the cue for INSERTED if the information is already in the
+               // color of the frame
+               pi.change_.paintCue(pi, xframe, yframe, xframe + w, yframe + h);
 }
 
 
index 3718e1d1d3e948815c29dd2b415a8f04ef705686..8df1bdfce2109c96e5ab32b39708e37cc88b9f2b 100644 (file)
@@ -63,8 +63,8 @@ public:
        bool editable() const { return true; }
        ///
        bool canTrackChanges() const { return true; }
-       ///
-       bool canPaintChange(BufferView const &) const { return false; }
+       /// Rely on RowPainter to draw the cue of inline insets.
+       bool canPaintChange(BufferView const &) const { return allowMultiPar(); }
        ///
        InsetText * asInsetText() { return this; }
        ///