mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Change tracking cue: InsetText and InsetCollapsible
* 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.
This commit is contained in:
parent
16ec606ab4
commit
f151b932c2
@ -33,6 +33,7 @@
|
|||||||
#include "support/gettext.h"
|
#include "support/gettext.h"
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
#include "support/lstrings.h"
|
#include "support/lstrings.h"
|
||||||
|
#include "support/RefChanger.h"
|
||||||
|
|
||||||
using namespace std;
|
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);
|
view_[&bv].auto_open_ = bv.cursor().isInside(this);
|
||||||
|
|
||||||
FontInfo tmpfont = pi.base.font;
|
Changer dummy = pi.base.font.change(getFont(), true);
|
||||||
pi.base.font = getFont();
|
|
||||||
pi.base.font.realize(tmpfont);
|
|
||||||
|
|
||||||
// Draw button first -- top, left or only
|
// Draw button first -- top, left or only
|
||||||
Dimension dimc = dimensionCollapsed(bv);
|
Dimension dimc = dimensionCollapsed(bv);
|
||||||
@ -246,7 +245,11 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
|
|||||||
FontInfo labelfont = getLabelfont();
|
FontInfo labelfont = getLabelfont();
|
||||||
labelfont.setColor(labelColor());
|
labelfont.setColor(labelColor());
|
||||||
pi.pain.buttonText(x, y, buttonLabel(bv), labelfont,
|
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 {
|
} else {
|
||||||
view_[&bv].button_dim_.x1 = 0;
|
view_[&bv].button_dim_.x1 = 0;
|
||||||
view_[&bv].button_dim_.y1 = 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);
|
Dimension const textdim = InsetText::dimension(bv);
|
||||||
int const baseline = y;
|
int const baseline = y;
|
||||||
int textx, texty;
|
int textx, texty;
|
||||||
switch (geometry(bv)) {
|
Geometry g = geometry(bv);
|
||||||
|
switch (g) {
|
||||||
case LeftButton:
|
case LeftButton:
|
||||||
textx = x + dimc.width();
|
case TopButton: {
|
||||||
texty = baseline;
|
if (g == LeftButton) {
|
||||||
InsetText::draw(pi, textx, texty);
|
textx = x + dimc.width();
|
||||||
break;
|
texty = baseline;
|
||||||
case TopButton:
|
} else {
|
||||||
textx = x;
|
textx = x;
|
||||||
texty = baseline + dimc.des + textdim.asc;
|
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);
|
InsetText::draw(pi, textx, texty);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ButtonOnly:
|
case ButtonOnly:
|
||||||
break;
|
break;
|
||||||
case NoButton:
|
case NoButton:
|
||||||
@ -279,38 +289,43 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
|
|||||||
case Corners:
|
case Corners:
|
||||||
textx = x;
|
textx = x;
|
||||||
texty = baseline;
|
texty = baseline;
|
||||||
const_cast<InsetCollapsable *>(this)->setDrawFrame(false);
|
{ // We will take care of the frame and the change tracking cue
|
||||||
InsetText::draw(pi, textx, texty);
|
// ourselves, below.
|
||||||
const_cast<InsetCollapsable *>(this)->setDrawFrame(true);
|
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();
|
int desc = textdim.descent();
|
||||||
if (geometry(bv) == Corners)
|
if (g == Corners)
|
||||||
desc -= 3;
|
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 xx1 = x + TEXT_TO_INSET_OFFSET - 1;
|
||||||
const int xx2 = x + textdim.wid - TEXT_TO_INSET_OFFSET + 1;
|
const int xx2 = x + textdim.wid - TEXT_TO_INSET_OFFSET + 1;
|
||||||
pi.pain.line(xx1, y + desc - 4,
|
pi.pain.line(xx1, y + desc - 4,
|
||||||
xx1, y + desc,
|
xx1, y + desc, colour);
|
||||||
Color_foreground);
|
|
||||||
if (status_ == Open)
|
if (status_ == Open)
|
||||||
pi.pain.line(xx1, y + desc,
|
pi.pain.line(xx1, y + desc,
|
||||||
xx2, y + desc,
|
xx2, y + desc, colour);
|
||||||
Color_foreground);
|
|
||||||
else {
|
else {
|
||||||
// Make status_ value visible:
|
// Make status_ value visible:
|
||||||
pi.pain.line(xx1, y + desc,
|
pi.pain.line(xx1, y + desc,
|
||||||
xx1 + 4, y + desc,
|
xx1 + 4, y + desc, colour);
|
||||||
Color_foreground);
|
|
||||||
pi.pain.line(xx2 - 4, y + desc,
|
pi.pain.line(xx2 - 4, y + desc,
|
||||||
xx2, y + desc,
|
xx2, y + desc, colour);
|
||||||
Color_foreground);
|
|
||||||
}
|
}
|
||||||
pi.pain.line(x + textdim.wid - 3, y + desc, x + textdim.wid - 3,
|
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.
|
// the label below the text. Can be toggled.
|
||||||
if (geometry(bv) == SubLabel) {
|
if (g == SubLabel) {
|
||||||
FontInfo font(getLabelfont());
|
FontInfo font(getLabelfont());
|
||||||
|
if (pi.change_.changed())
|
||||||
|
font.setPaintColor(colour);
|
||||||
font.realize(sane_font);
|
font.realize(sane_font);
|
||||||
font.decSize();
|
font.decSize();
|
||||||
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);
|
buttonLabel(bv), font, Color_none, Color_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int const y1 = y - textdim.asc + 3;
|
||||||
// a visual cue when the cursor is inside the inset
|
// a visual cue when the cursor is inside the inset
|
||||||
Cursor const & cur = bv.cursor();
|
Cursor const & cur = bv.cursor();
|
||||||
if (cur.isInside(this)) {
|
if (cur.isInside(this)) {
|
||||||
y -= textdim.asc;
|
pi.pain.line(xx1, y1 + 4, xx1, y1, colour);
|
||||||
y += 3;
|
pi.pain.line(xx1 + 4, y1, xx1, y1, colour);
|
||||||
pi.pain.line(xx1, y + 4, xx1, y, Color_foreground);
|
pi.pain.line(xx2, y1 + 4, xx2, y1, colour);
|
||||||
pi.pain.line(xx1 + 4, y, xx1, y, Color_foreground);
|
pi.pain.line(xx2 - 4, y1, xx2, y1, colour);
|
||||||
pi.pain.line(xx2, y + 4, xx2, y, Color_foreground);
|
|
||||||
pi.pain.line(xx2 - 4, y, xx2, y, Color_foreground);
|
|
||||||
}
|
}
|
||||||
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pi.base.font = tmpfont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -618,16 +634,18 @@ string InsetCollapsable::contextMenuName() const
|
|||||||
|
|
||||||
bool InsetCollapsable::canPaintChange(BufferView const & bv) 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)) {
|
switch (geometry(bv)) {
|
||||||
case Corners:
|
case Corners:
|
||||||
case SubLabel:
|
case SubLabel:
|
||||||
|
return allowMultiPar();
|
||||||
case ButtonOnly:
|
case ButtonOnly:
|
||||||
// these cases are handled by RowPainter since the inset is inline.
|
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: implement the drawing in the remaining cases
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@
|
|||||||
#include "frontends/alert.h"
|
#include "frontends/alert.h"
|
||||||
#include "frontends/Painter.h"
|
#include "frontends/Painter.h"
|
||||||
|
|
||||||
|
#include "support/bind.h"
|
||||||
#include "support/convert.h"
|
#include "support/convert.h"
|
||||||
#include "support/debug.h"
|
#include "support/debug.h"
|
||||||
#include "support/gettext.h"
|
#include "support/gettext.h"
|
||||||
#include "support/lstrings.h"
|
|
||||||
|
|
||||||
#include "support/bind.h"
|
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
|
#include "support/lstrings.h"
|
||||||
|
#include "support/RefChanger.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -215,24 +215,48 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
|
|||||||
{
|
{
|
||||||
TextMetrics & tm = pi.base.bv->textMetrics(&text_);
|
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) {
|
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)
|
if (pi.full_repaint)
|
||||||
pi.pain.fillRectangle(xframe, yframe, w, h,
|
pi.pain.fillRectangle(xframe, yframe, w, h,
|
||||||
pi.backgroundColor(this));
|
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_)
|
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);
|
Changer dummy = make_change(pi.background_color,
|
||||||
|
pi.backgroundColor(this, false));
|
||||||
tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y);
|
// The change tracking cue must not be inherited
|
||||||
|
Changer dummy2 = make_change(pi.change_, Change());
|
||||||
pi.background_color = old_color;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ public:
|
|||||||
bool editable() const { return true; }
|
bool editable() const { return true; }
|
||||||
///
|
///
|
||||||
bool canTrackChanges() const { return true; }
|
bool canTrackChanges() const { return true; }
|
||||||
///
|
/// Rely on RowPainter to draw the cue of inline insets.
|
||||||
bool canPaintChange(BufferView const &) const { return false; }
|
bool canPaintChange(BufferView const &) const { return allowMultiPar(); }
|
||||||
///
|
///
|
||||||
InsetText * asInsetText() { return this; }
|
InsetText * asInsetText() { return this; }
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user