Another selection painting patch, PainterInfo::backgroundColor introduced.

Patch by Vincent.

http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg145438.html



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27097 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Pavel Sanda 2008-10-25 10:47:38 +00:00
parent fcac9f833a
commit e4808961c9
13 changed files with 108 additions and 20 deletions

View File

@ -2224,7 +2224,7 @@ void BufferView::draw(frontend::Painter & pain)
// Clear background. // Clear background.
pain.fillRectangle(0, 0, width_, height_, pain.fillRectangle(0, 0, width_, height_,
buffer_.inset().backgroundColor()); pi.backgroundColor(&buffer_.inset()));
// Draw everything. // Draw everything.
tm.draw(pi, 0, y); tm.draw(pi, 0, y);

View File

@ -14,6 +14,8 @@
#include "Color.h" #include "Color.h"
#include "MetricsInfo.h" #include "MetricsInfo.h"
#include "insets/Inset.h"
#include "mathed/MathSupport.h" #include "mathed/MathSupport.h"
#include "frontends/Painter.h" #include "frontends/Painter.h"
@ -65,6 +67,29 @@ void PainterInfo::draw(int x, int y, docstring const & str)
} }
ColorCode PainterInfo::backgroundColor(Inset const * inset, bool sel) const
{
ColorCode const color_bg = inset->backgroundColor();
if (selected && sel)
// This inset is in a selection
return Color_selection;
else {
if (color_bg != Color_none)
// This inset has its own color
return color_bg;
else {
if (background_color == Color_none)
// This inset has no own color and does not inherit a color
return Color_background;
else
// This inset has no own color, but inherits a color
return background_color;
}
}
}
Styles smallerScriptStyle(Styles st) Styles smallerScriptStyle(Styles st)
{ {
switch (st) { switch (st) {

View File

@ -26,6 +26,7 @@ class BufferView;
namespace lyx { namespace lyx {
namespace frontend { class Painter; } namespace frontend { class Painter; }
class Inset;
class MacroContext; class MacroContext;
@ -95,6 +96,11 @@ public:
void draw(int x, int y, char_type c); void draw(int x, int y, char_type c);
/// ///
void draw(int x, int y, docstring const & str); void draw(int x, int y, docstring const & str);
/// Determines the background color for the specified inset based on the
/// selection state, the background color inherited from the parent inset
/// and the inset's own background color.
/// \param sel whether to take the selection state into account
ColorCode backgroundColor(Inset const * inset, bool sel = true) const;
/// ///
MetricsBase base; MetricsBase base;
@ -104,9 +110,11 @@ public:
bool ltr_pos; bool ltr_pos;
/// Whether the parent is deleted (change tracking) /// Whether the parent is deleted (change tracking)
bool erased_; bool erased_;
/// Whether the parent is selected as a whole
bool selected;
/// ///
bool full_repaint; bool full_repaint;
/// /// Current background color
ColorCode background_color; ColorCode background_color;
}; };

View File

@ -430,7 +430,7 @@ void Inset::dump() const
ColorCode Inset::backgroundColor() const ColorCode Inset::backgroundColor() const
{ {
return Color_background; return Color_none;
} }

View File

@ -173,6 +173,9 @@ public:
virtual void draw(PainterInfo & pi, int x, int y) const = 0; virtual void draw(PainterInfo & pi, int x, int y) const = 0;
/// draw inset selection if necessary /// draw inset selection if necessary
virtual void drawSelection(PainterInfo &, int, int) const {} virtual void drawSelection(PainterInfo &, int, int) const {}
/// draw inset background if the inset has an own background and a
/// selection is drawn by drawSelection.
virtual void drawBackground(PainterInfo &, int, int) const {}
/// ///
virtual bool editing(BufferView const * bv) const; virtual bool editing(BufferView const * bv) const;
/// ///

View File

@ -266,8 +266,6 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
LASSERT(layout_, /**/); LASSERT(layout_, /**/);
autoOpen_ = pi.base.bv->cursor().isInside(this); autoOpen_ = pi.base.bv->cursor().isInside(this);
ColorCode const old_color = pi.background_color;
pi.background_color = backgroundColor();
FontInfo tmpfont = pi.base.font; FontInfo tmpfont = pi.base.font;
pi.base.font = layout_->font(); pi.base.font = layout_->font();
@ -377,7 +375,6 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
} }
break; break;
} }
pi.background_color = old_color;
pi.base.font = tmpfont; pi.base.font = tmpfont;
} }

View File

@ -119,7 +119,7 @@ bool InsetLayout::read(Lexer & lex, TextClass & tclass)
FontInfo font = inherit_font; FontInfo font = inherit_font;
labelfont_ = inherit_font; labelfont_ = inherit_font;
bgcolor_ = Color_background; bgcolor_ = Color_none;
bool getout = false; bool getout = false;
// whether we've read the CustomPars or ForcePlain tag // whether we've read the CustomPars or ForcePlain tag
// for issuing a warning in case MultiPars comes later // for issuing a warning in case MultiPars comes later

View File

@ -2996,11 +2996,37 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH; dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH;
} }
bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col)
const
{
if (&cur.inset() == this && cur.selection()) {
if (cur.selIsMultiCell()) {
row_type rs, re;
col_type cs, ce;
getSelection(cur, rs, re, cs, ce);
if (col >= cs && col <= ce && row >= rs && row <= re)
return true;
} else
if (col == tabular.cellColumn(cur.idx())
&& row == tabular.cellRow(cur.idx())) {
CursorSlice const & beg = cur.selBegin();
CursorSlice const & end = cur.selEnd();
if (end.lastpos() > 0 && end.pos() == end.lastpos()
&& beg.pos() == 0)
return true;
}
}
return false;
}
void InsetTabular::draw(PainterInfo & pi, int x, int y) const void InsetTabular::draw(PainterInfo & pi, int x, int y) const
{ {
//lyxerr << "InsetTabular::draw: " << x << " " << y << endl; //lyxerr << "InsetTabular::draw: " << x << " " << y << endl;
BufferView * bv = pi.base.bv; BufferView * bv = pi.base.bv;
Cursor & cur = pi.base.bv->cursor();
// FIXME: As the full backrgound is painted in drawSelection(), // FIXME: As the full backrgound is painted in drawSelection(),
// we have no choice but to do a full repaint for the Text cells. // we have no choice but to do a full repaint for the Text cells.
@ -3012,6 +3038,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
x += ADD_TO_TABULAR_WIDTH; x += ADD_TO_TABULAR_WIDTH;
bool const original_drawing_state = pi.pain.isDrawingEnabled(); bool const original_drawing_state = pi.pain.isDrawingEnabled();
bool const original_selection_state = pi.selected;
idx_type idx = 0; idx_type idx = 0;
first_visible_cell = Tabular::npos; first_visible_cell = Tabular::npos;
@ -3026,6 +3053,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
if (first_visible_cell == Tabular::npos) if (first_visible_cell == Tabular::npos)
first_visible_cell = idx; first_visible_cell = idx;
pi.selected |= isCellSelected(cur, i, j);
int const cx = nx + tabular.getBeginningOfTextInCell(idx); int const cx = nx + tabular.getBeginningOfTextInCell(idx);
// Cache the Inset position. // Cache the Inset position.
bv->coordCache().insets().add(cell(idx).get(), cx, y); bv->coordCache().insets().add(cell(idx).get(), cx, y);
@ -3043,6 +3071,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
} }
nx += tabular.columnWidth(idx); nx += tabular.columnWidth(idx);
++idx; ++idx;
pi.selected = original_selection_state;
} }
if (i + 1 < tabular.row_info.size()) if (i + 1 < tabular.row_info.size())
@ -3065,7 +3094,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
int const w = tabular.width(); int const w = tabular.width();
int const h = tabular.height(); int const h = tabular.height();
int yy = y - tabular.rowAscent(0); int yy = y - tabular.rowAscent(0);
pi.pain.fillRectangle(x, yy, w, h, backgroundColor()); pi.pain.fillRectangle(x, yy, w, h, pi.backgroundColor(this));
if (!cur.selection()) if (!cur.selection())
return; return;
@ -3076,9 +3105,6 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
if (cur.selIsMultiCell()) { if (cur.selIsMultiCell()) {
row_type rs, re;
col_type cs, ce;
getSelection(cur, rs, re, cs, ce);
y -= tabular.rowAscent(0); y -= tabular.rowAscent(0);
for (row_type j = 0; j < tabular.row_info.size(); ++j) { for (row_type j = 0; j < tabular.row_info.size(); ++j) {
int const a = tabular.rowAscent(j); int const a = tabular.rowAscent(j);
@ -3091,7 +3117,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
idx_type const cell = idx_type const cell =
tabular.cellIndex(j, i); tabular.cellIndex(j, i);
int const w = tabular.columnWidth(cell); int const w = tabular.columnWidth(cell);
if (i >= cs && i <= ce && j >= rs && j <= re) if (isCellSelected(cur, j, i))
pi.pain.fillRectangle(xx, y, w, h, pi.pain.fillRectangle(xx, y, w, h,
Color_selection); Color_selection);
xx += w; xx += w;

View File

@ -834,6 +834,8 @@ public:
/// descending into the insets /// descending into the insets
docstring asString(idx_type stidx, idx_type enidx, bool intoInsets = true); docstring asString(idx_type stidx, idx_type enidx, bool intoInsets = true);
/// Returns whether the cell in the specified row and column is selected.
bool isCellSelected(Cursor & cur, row_type row, col_type col) const;
// //
// Public structures and variables // Public structures and variables
/// ///

View File

@ -200,11 +200,18 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
int const h = tm.height() + 2 * TEXT_TO_INSET_OFFSET; int const h = tm.height() + 2 * TEXT_TO_INSET_OFFSET;
int const xframe = x + TEXT_TO_INSET_OFFSET / 2; int const xframe = x + TEXT_TO_INSET_OFFSET / 2;
if (pi.full_repaint) if (pi.full_repaint)
pi.pain.fillRectangle(xframe, yframe, w, h, backgroundColor()); pi.pain.fillRectangle(xframe, yframe, w, h,
pi.backgroundColor(this));
if (drawFrame_) if (drawFrame_)
pi.pain.rectangle(xframe, yframe, w, h, frameColor()); pi.pain.rectangle(xframe, yframe, w, h, frameColor());
} }
ColorCode const old_color = pi.background_color;
pi.background_color = pi.backgroundColor(this, false);
tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y); tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y);
pi.background_color = old_color;
} }

View File

@ -380,16 +380,17 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const
} }
void InsetMathHull::drawBackground(PainterInfo & pi, int x, int y) const
{
Dimension const dim = dimension(*pi.base.bv);
pi.pain.fillRectangle(x + 1, y - dim.asc + 1, dim.wid - 2,
dim.asc + dim.des - 1, pi.backgroundColor(this));
}
void InsetMathHull::draw(PainterInfo & pi, int x, int y) const void InsetMathHull::draw(PainterInfo & pi, int x, int y) const
{ {
use_preview_ = previewState(pi.base.bv); use_preview_ = previewState(pi.base.bv);
Dimension const dim = dimension(*pi.base.bv);
// background of mathed under focus is not painted because
// selection at the top level of nested inset is difficult to handle.
if (!editing(pi.base.bv))
pi.pain.fillRectangle(x + 1, y - dim.asc + 1, dim.wid - 2,
dim.asc + dim.des - 1, Color_mathbg);
if (use_preview_) { if (use_preview_) {
// one pixel gap in front // one pixel gap in front

View File

@ -45,6 +45,8 @@ public:
mode_type currentMode() const; mode_type currentMode() const;
/// ///
void metrics(MetricsInfo & mi, Dimension & dim) const; void metrics(MetricsInfo & mi, Dimension & dim) const;
///
void drawBackground(PainterInfo & pi, int x, int y) const;
/// ///
void draw(PainterInfo &, int x, int y) const; void draw(PainterInfo &, int x, int y) const;
/// ///
@ -56,6 +58,8 @@ public:
/// ///
void label(row_type row, docstring const & label); void label(row_type row, docstring const & label);
/// ///
ColorCode backgroundColor() const { return Color_mathbg; }
///
void numbered(row_type row, bool num); void numbered(row_type row, bool num);
/// ///
bool numbered(row_type row) const; bool numbered(row_type row) const;

View File

@ -109,6 +109,7 @@ void RowPainter::paintInset(Inset const * inset, pos_type const pos)
pi_.erased_ = erased_ || par_.isDeleted(pos); pi_.erased_ = erased_ || par_.isDeleted(pos);
pi_.base.bv->coordCache().insets().add(inset, int(x_), yo_); pi_.base.bv->coordCache().insets().add(inset, int(x_), yo_);
// insets are painted completely. Recursive // insets are painted completely. Recursive
inset->drawBackground(pi_, int(x_), yo_);
inset->drawSelection(pi_, int(x_), yo_); inset->drawSelection(pi_, int(x_), yo_);
inset->draw(pi_, int(x_), yo_); inset->draw(pi_, int(x_), yo_);
@ -683,7 +684,14 @@ void RowPainter::paintOnlyInsets()
if (x_ > pi_.base.bv->workWidth()) if (x_ > pi_.base.bv->workWidth())
continue; continue;
x_ = pi_.base.bv->coordCache().getInsets().x(inset); x_ = pi_.base.bv->coordCache().getInsets().x(inset);
bool const pi_selected = pi_.selected;
Cursor const & cur = pi_.base.bv->cursor();
if (cur.selection() && cur.text() == &text_
&& cur.anchor().text() == &text_)
pi_.selected = row_.sel_beg <= pos && row_.sel_end > pos;
paintInset(inset, pos); paintInset(inset, pos);
pi_.selected = pi_selected;
} }
} }
@ -818,7 +826,14 @@ void RowPainter::paintText()
} else if (inset) { } else if (inset) {
// If outer row has changed, nested insets are repaint completely. // If outer row has changed, nested insets are repaint completely.
pi_.base.bv->coordCache().insets().add(inset, int(x_), yo_); pi_.base.bv->coordCache().insets().add(inset, int(x_), yo_);
bool const pi_selected = pi_.selected;
Cursor const & cur = pi_.base.bv->cursor();
if (cur.selection() && cur.text() == &text_
&& cur.anchor().text() == &text_)
pi_.selected = row_.sel_beg <= pos && row_.sel_end > pos;
paintInset(inset, pos); paintInset(inset, pos);
pi_.selected = pi_selected;
++vpos; ++vpos;
} else { } else {