From 6a1803e18dfac1720920a4fc8c500300658bc7d7 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 3 Feb 2016 10:37:29 +0100 Subject: [PATCH] Fix display of InsetCollapsable with split views When several bufferviews exist for the same inset, the data that depends on the view width have to be BufferView-dependent. While this is the case for several mutable members of InsetCollapsable, some were missing. This commit makes button_dim_ (renamed from button_dim) and openinlined_ bv-dependent. Get rid of the hitButton function. Remove the bv-independent geometry() method and implement editable() explicitely instead. Fixes bug #9756. --- src/insets/InsetCollapsable.cpp | 86 ++++++++++++--------------------- src/insets/InsetCollapsable.h | 19 ++++---- status.22x | 8 +-- 3 files changed, 45 insertions(+), 68 deletions(-) diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index c4ca450c4a..54e813b1ac 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -40,7 +40,7 @@ using namespace std; namespace lyx { InsetCollapsable::InsetCollapsable(Buffer * buf, InsetText::UsePlain ltype) - : InsetText(buf, ltype), status_(Open), openinlined_(false) + : InsetText(buf, ltype), status_(Open) { setDrawFrame(true); setFrameColor(Color_collapsableframe); @@ -53,7 +53,7 @@ InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) : InsetText(rhs), status_(rhs.status_), labelstring_(rhs.labelstring_), - button_dim(rhs.button_dim), + button_dim_(rhs.button_dim_), openinlined_(rhs.openinlined_) {} @@ -81,7 +81,7 @@ InsetCollapsable::Geometry InsetCollapsable::geometry(BufferView const & bv) con switch (decoration()) { case InsetLayout::CLASSIC: if (status(bv) == Open) - return openinlined_ ? LeftButton : TopButton; + return openinlined_[&bv] ? LeftButton : TopButton; return ButtonOnly; case InsetLayout::MINIMALISTIC: @@ -100,30 +100,6 @@ InsetCollapsable::Geometry InsetCollapsable::geometry(BufferView const & bv) con } -InsetCollapsable::Geometry InsetCollapsable::geometry() const -{ - switch (decoration()) { - case InsetLayout::CLASSIC: - if (status_ == Open) - return openinlined_ ? LeftButton : TopButton; - return ButtonOnly; - - case InsetLayout::MINIMALISTIC: - return status_ == Open ? NoButton : ButtonOnly ; - - case InsetLayout::CONGLOMERATE: - return status_ == Open ? SubLabel : Corners ; - - case InsetLayout::DEFAULT: - break; // this shouldn't happen - } - - // dummy return value to shut down a warning, - // this is dead code. - return NoButton; -} - - docstring InsetCollapsable::toolTip(BufferView const & bv, int x, int y) const { Dimension const dim = dimensionCollapsed(bv); @@ -214,17 +190,16 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const case LeftButton: case ButtonOnly: if (hasFixedWidth()){ - int const mindim = button_dim.x2 - button_dim.x1; + int const mindim = button_dim_[&bv].x2 - button_dim_[&bv].x1; if (mi.base.textwidth < mindim) mi.base.textwidth = mindim; } dim = dimensionCollapsed(bv); - if (geometry(bv) == TopButton - || geometry(bv) == LeftButton) { + if (geometry(bv) == TopButton || geometry(bv) == LeftButton) { Dimension textdim; InsetText::metrics(mi, textdim); - openinlined_ = (textdim.wid + dim.wid) < mi.base.textwidth; - if (openinlined_) { + openinlined_[&bv] = (textdim.wid + dim.wid) < mi.base.textwidth; + if (openinlined_[&bv]) { // Correct for button width. dim.wid += textdim.wid; dim.des = max(dim.des - textdim.asc + dim.asc, textdim.des); @@ -265,20 +240,20 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const if (geometry(bv) == TopButton || geometry(bv) == LeftButton || geometry(bv) == ButtonOnly) { - button_dim.x1 = x + 0; - button_dim.x2 = x + dimc.width(); - button_dim.y1 = y - dimc.asc; - button_dim.y2 = y + dimc.des; + button_dim_[&bv].x1 = x + 0; + button_dim_[&bv].x2 = x + dimc.width(); + button_dim_[&bv].y1 = y - dimc.asc; + button_dim_[&bv].y2 = y + dimc.des; FontInfo labelfont = getLabelfont(); labelfont.setColor(labelColor()); pi.pain.buttonText(x, y, buttonLabel(bv), labelfont, mouse_hover_[&bv]); } else { - button_dim.x1 = 0; - button_dim.y1 = 0; - button_dim.x2 = 0; - button_dim.y2 = 0; + button_dim_[&bv].x1 = 0; + button_dim_[&bv].y1 = 0; + button_dim_[&bv].x2 = 0; + button_dim_[&bv].y2 = 0; } Dimension const textdim = InsetText::dimension(bv); @@ -398,7 +373,13 @@ void InsetCollapsable::cursorPos(BufferView const & bv, bool InsetCollapsable::editable() const { - return geometry() != ButtonOnly; + switch (decoration()) { + case InsetLayout::CLASSIC: + case InsetLayout::MINIMALISTIC: + return status_ == Open; + default: + return true; + } } @@ -408,16 +389,9 @@ bool InsetCollapsable::descendable(BufferView const & bv) const } -bool InsetCollapsable::hitButton(FuncRequest const & cmd) const +bool InsetCollapsable::clickable(BufferView const & bv, int x, int y) const { - return button_dim.contains(cmd.x(), cmd.y()); -} - - -bool InsetCollapsable::clickable(BufferView const &, int x, int y) const -{ - FuncRequest cmd(LFUN_NOACTION, x, y, mouse_button::none); - return hitButton(cmd); + return button_dim_[&bv].contains(x, y); } @@ -454,8 +428,8 @@ Inset * InsetCollapsable::editXY(Cursor & cur, int x, int y) { //lyxerr << "InsetCollapsable: edit xy" << endl; if (geometry(cur.bv()) == ButtonOnly - || (button_dim.contains(x, y) - && geometry(cur.bv()) != NoButton)) + || (button_dim_[&cur.bv()].contains(x, y) + && geometry(cur.bv()) != NoButton)) return this; cur.push(*this); return InsetText::editXY(cur, x, y); @@ -467,9 +441,11 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) //lyxerr << "InsetCollapsable::doDispatch (begin): cmd: " << cmd // << " cur: " << cur << " bvcur: " << cur.bv().cursor() << endl; + bool const hitButton = clickable(cur.bv(), cmd.x(), cmd.y()); + switch (cmd.action()) { case LFUN_MOUSE_PRESS: - if (hitButton(cmd)) { + if (hitButton) { switch (cmd.button()) { case mouse_button::button1: case mouse_button::button3: @@ -494,7 +470,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_MOTION: case LFUN_MOUSE_DOUBLE: case LFUN_MOUSE_TRIPLE: - if (hitButton(cmd)) + if (hitButton) cur.noScreenUpdate(); else if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); @@ -503,7 +479,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) break; case LFUN_MOUSE_RELEASE: - if (!hitButton(cmd)) { + if (!hitButton) { // The mouse click has to be within the inset! if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); diff --git a/src/insets/InsetCollapsable.h b/src/insets/InsetCollapsable.h index e231ca0e9f..298c4e14ec 100644 --- a/src/insets/InsetCollapsable.h +++ b/src/insets/InsetCollapsable.h @@ -58,18 +58,16 @@ public: /// return x,y of given position relative to the inset's baseline void cursorPos(BufferView const & bv, CursorSlice const & sl, bool boundary, int & x, int & y) const; - /// Returns true if (mouse) action is over the inset's button. - /// Always returns false when the inset does not have a - /// button. - bool hitButton(FuncRequest const &) const; /// docstring const getNewLabel(docstring const & l) const; /// bool editable() const; /// bool hasSettings() const { return true; } - /// - bool clickable(BufferView const &, int x, int y) const; + /// Returns true if coordinates are over the inset's button. + /// Always returns false when the inset does not have a + /// button. + bool clickable(BufferView const & bv, int x, int y) const; /// can we go further down on mouse click? bool descendable(BufferView const & bv) const; /// @@ -128,8 +126,6 @@ public: /// (status_), auto_open_[BufferView] and openinlined_, /// and of course decoration(). Geometry geometry(BufferView const & bv) const; - /// Returns the geometry disregarding auto_open_ - Geometry geometry() const; /// bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const; /// @@ -163,10 +159,13 @@ private: Dimension dimensionCollapsed(BufferView const & bv) const; /// docstring labelstring_; + + /// FIXME: the variables below should be grouped in a View subclass (as in MVC) + /// - mutable Box button_dim; + mutable std::map button_dim_; /// a substatus of the Open status, determined automatically in metrics - mutable bool openinlined_; + mutable std::map openinlined_; /// the inset will automatically open when the cursor is inside. This is /// dependent on the bufferview, compare with MathMacro::editing_. mutable std::map auto_open_; diff --git a/status.22x b/status.22x index abbd9e7df8..1feec7543b 100644 --- a/status.22x +++ b/status.22x @@ -23,7 +23,7 @@ What's new * USER INTERFACE - Increase the maximum value for the number of last open files that LyX can - remember (#9924). + remember (bug 9924). * DOCUMENTATION AND LOCALIZATION @@ -47,11 +47,13 @@ What's new * USER INTERFACE -- Do not omit the first space of the selection when copying (#9995) +- Do not omit the first space of the selection when copying (bug 9995). - Display the correct column alignment and a better column spacing in AMS - environments (#1861, #9908) + environments (bugs 1861, 9908). +- Fix display of collapsable insets when the same document is shown in + two views with different width (bug 9756). * INTERNALS