From: Pavel Sanda Date: Sat, 25 Oct 2008 10:47:38 +0000 (+0000) Subject: Another selection painting patch, PainterInfo::backgroundColor introduced. X-Git-Tag: 1.6.10~2863 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=e4808961c94b22cfa90ffb1e038a59e77dbb087e;p=features.git 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 --- diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 02d8fcdc98..314631cadd 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -2224,7 +2224,7 @@ void BufferView::draw(frontend::Painter & pain) // Clear background. pain.fillRectangle(0, 0, width_, height_, - buffer_.inset().backgroundColor()); + pi.backgroundColor(&buffer_.inset())); // Draw everything. tm.draw(pi, 0, y); diff --git a/src/MetricsInfo.cpp b/src/MetricsInfo.cpp index a90a62bc17..9b0a0d5aa1 100644 --- a/src/MetricsInfo.cpp +++ b/src/MetricsInfo.cpp @@ -14,6 +14,8 @@ #include "Color.h" #include "MetricsInfo.h" +#include "insets/Inset.h" + #include "mathed/MathSupport.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) { switch (st) { diff --git a/src/MetricsInfo.h b/src/MetricsInfo.h index e091dc7830..c82914d8f2 100644 --- a/src/MetricsInfo.h +++ b/src/MetricsInfo.h @@ -26,6 +26,7 @@ class BufferView; namespace lyx { namespace frontend { class Painter; } +class Inset; class MacroContext; @@ -95,6 +96,11 @@ public: void draw(int x, int y, char_type c); /// 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; @@ -104,9 +110,11 @@ public: bool ltr_pos; /// Whether the parent is deleted (change tracking) bool erased_; + /// Whether the parent is selected as a whole + bool selected; /// bool full_repaint; - /// + /// Current background color ColorCode background_color; }; diff --git a/src/insets/Inset.cpp b/src/insets/Inset.cpp index 095cdaa482..40f33d9fd1 100644 --- a/src/insets/Inset.cpp +++ b/src/insets/Inset.cpp @@ -430,7 +430,7 @@ void Inset::dump() const ColorCode Inset::backgroundColor() const { - return Color_background; + return Color_none; } diff --git a/src/insets/Inset.h b/src/insets/Inset.h index 350a0bb356..48341f119c 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -173,6 +173,9 @@ public: virtual void draw(PainterInfo & pi, int x, int y) const = 0; /// draw inset selection if necessary 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; /// diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index 4898558cce..b72816c719 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -266,8 +266,6 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const LASSERT(layout_, /**/); autoOpen_ = pi.base.bv->cursor().isInside(this); - ColorCode const old_color = pi.background_color; - pi.background_color = backgroundColor(); FontInfo tmpfont = pi.base.font; pi.base.font = layout_->font(); @@ -377,7 +375,6 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const } break; } - pi.background_color = old_color; pi.base.font = tmpfont; } diff --git a/src/insets/InsetLayout.cpp b/src/insets/InsetLayout.cpp index f71fd582a2..4d3fce51f4 100644 --- a/src/insets/InsetLayout.cpp +++ b/src/insets/InsetLayout.cpp @@ -119,7 +119,7 @@ bool InsetLayout::read(Lexer & lex, TextClass & tclass) FontInfo font = inherit_font; labelfont_ = inherit_font; - bgcolor_ = Color_background; + bgcolor_ = Color_none; bool getout = false; // whether we've read the CustomPars or ForcePlain tag // for issuing a warning in case MultiPars comes later diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index fd765d7274..19c1ec2c10 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -2996,11 +2996,37 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const 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 { //lyxerr << "InsetTabular::draw: " << x << " " << y << endl; BufferView * bv = pi.base.bv; + Cursor & cur = pi.base.bv->cursor(); // FIXME: As the full backrgound is painted in drawSelection(), // 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; bool const original_drawing_state = pi.pain.isDrawingEnabled(); + bool const original_selection_state = pi.selected; idx_type idx = 0; 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) first_visible_cell = idx; + pi.selected |= isCellSelected(cur, i, j); int const cx = nx + tabular.getBeginningOfTextInCell(idx); // Cache the Inset position. 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); ++idx; + pi.selected = original_selection_state; } 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 h = tabular.height(); 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()) return; @@ -3076,9 +3105,6 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const if (cur.selIsMultiCell()) { - row_type rs, re; - col_type cs, ce; - getSelection(cur, rs, re, cs, ce); y -= tabular.rowAscent(0); for (row_type j = 0; j < tabular.row_info.size(); ++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 = tabular.cellIndex(j, i); 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, Color_selection); xx += w; diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index 6134262e5e..fc4116c7e1 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -834,6 +834,8 @@ public: /// descending into the insets 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 /// diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index ab480f8c13..b346726201 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -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 xframe = x + TEXT_TO_INSET_OFFSET / 2; if (pi.full_repaint) - pi.pain.fillRectangle(xframe, yframe, w, h, backgroundColor()); + pi.pain.fillRectangle(xframe, yframe, w, h, + pi.backgroundColor(this)); + if (drawFrame_) 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); + + pi.background_color = old_color; } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 001cdd01ae..cc4672587d 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -380,16 +380,17 @@ void InsetMathHull::metrics(MetricsInfo & mi, Dimension & dim) const } -void InsetMathHull::draw(PainterInfo & pi, int x, int y) const +void InsetMathHull::drawBackground(PainterInfo & pi, int x, int y) const { - use_preview_ = previewState(pi.base.bv); 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)); +} + - // 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); +void InsetMathHull::draw(PainterInfo & pi, int x, int y) const +{ + use_preview_ = previewState(pi.base.bv); if (use_preview_) { // one pixel gap in front diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h index e020e96ae7..ce1e9e51dc 100644 --- a/src/mathed/InsetMathHull.h +++ b/src/mathed/InsetMathHull.h @@ -45,6 +45,8 @@ public: mode_type currentMode() 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; /// @@ -56,6 +58,8 @@ public: /// void label(row_type row, docstring const & label); /// + ColorCode backgroundColor() const { return Color_mathbg; } + /// void numbered(row_type row, bool num); /// bool numbered(row_type row) const; diff --git a/src/rowpainter.cpp b/src/rowpainter.cpp index 0a097ed9f2..3b7bbe09db 100644 --- a/src/rowpainter.cpp +++ b/src/rowpainter.cpp @@ -109,6 +109,7 @@ void RowPainter::paintInset(Inset const * inset, pos_type const pos) pi_.erased_ = erased_ || par_.isDeleted(pos); pi_.base.bv->coordCache().insets().add(inset, int(x_), yo_); // insets are painted completely. Recursive + inset->drawBackground(pi_, int(x_), yo_); inset->drawSelection(pi_, int(x_), yo_); inset->draw(pi_, int(x_), yo_); @@ -683,7 +684,14 @@ void RowPainter::paintOnlyInsets() if (x_ > pi_.base.bv->workWidth()) continue; 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); + pi_.selected = pi_selected; } } @@ -818,7 +826,14 @@ void RowPainter::paintText() } else if (inset) { // If outer row has changed, nested insets are repaint completely. 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); + pi_.selected = pi_selected; ++vpos; } else {