]> git.lyx.org Git - features.git/commitdiff
Another selection painting patch, PainterInfo::backgroundColor introduced.
authorPavel Sanda <sanda@lyx.org>
Sat, 25 Oct 2008 10:47:38 +0000 (10:47 +0000)
committerPavel Sanda <sanda@lyx.org>
Sat, 25 Oct 2008 10:47:38 +0000 (10:47 +0000)
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

13 files changed:
src/BufferView.cpp
src/MetricsInfo.cpp
src/MetricsInfo.h
src/insets/Inset.cpp
src/insets/Inset.h
src/insets/InsetCollapsable.cpp
src/insets/InsetLayout.cpp
src/insets/InsetTabular.cpp
src/insets/InsetTabular.h
src/insets/InsetText.cpp
src/mathed/InsetMathHull.cpp
src/mathed/InsetMathHull.h
src/rowpainter.cpp

index 02d8fcdc98339f68903a4c0c9fe1451506f3b759..314631cadd0ec344868a6bee54ab2156f19879e8 100644 (file)
@@ -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);
index a90a62bc176d7fa3c5662f8412bb646ed35286b9..9b0a0d5aa10b854ad6cc57121a2edc30c89d2ee5 100644 (file)
@@ -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) {
index e091dc78308ff55760e03d2867223997332dbe59..c82914d8f20512a85b97fd030ffebb34b1d2afba 100644 (file)
@@ -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;
 };
 
index 095cdaa4823e1a5a7da021ffb0d730667118ae22..40f33d9fd11d540d405ec1dc525abbd4610f0a3f 100644 (file)
@@ -430,7 +430,7 @@ void Inset::dump() const
 
 ColorCode Inset::backgroundColor() const
 {
-       return Color_background;
+       return Color_none;
 }
 
 
index 350a0bb356297f9ae432d7659c0419ec541dfe2b..48341f119c3d4d93e32d6acd07dd33b8815b3e8a 100644 (file)
@@ -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;
        ///
index 4898558cce2fd538469137f34aefb400623713ab..b72816c7193a08f55fa0d6b2be8d7256af457e33 100644 (file)
@@ -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;
 }
index f71fd582a2c0711f219a9f7df11bb1dfb122186d..4d3fce51f42bab5bcbcdb9d80d8a86cf7de97c7d 100644 (file)
@@ -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
index fd765d7274cb6e9f64824688f15b2079fbff210a..19c1ec2c1013179f56bcb266d49b1750923b014e 100644 (file)
@@ -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;
index 6134262e5e7d9b5f01036f35f5ee5c612d6ae074..fc4116c7e1477ffa4fc1df0ffdc315b7995f6a0f 100644 (file)
@@ -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
        ///
index ab480f8c135396070a193627852c5cc3d01baa92..b346726201f1137297e4d6c5a79138752d38f7ca 100644 (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 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;
 }
 
 
index 001cdd01ae1c54e552a97cbc6dfc7da57acade6b..cc4672587d2d903dd3b337c32fc02c955eb144fa 100644 (file)
@@ -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
index e020e96ae7e3b8e9350ac7f97b7056184a0be741..ce1e9e51dcf5163a4369881b1e41707bf657987c 100644 (file)
@@ -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;
index 0a097ed9f257edd0308bae09e473db4025b64e4d..3b7bbe09db2c5b427cbd87ae7b2a4f62873fb71a 100644 (file)
@@ -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 {