cur.clearSelection();
break;
case bv_funcs::CUR_INSIDE:
- int const y = bv_funcs::getPos(cur).y_;
+ int const y = bv_funcs::getPos(cur, cur.boundary()).y_;
int const newy = min(last, max(y, first));
if (y != newy) {
cur.reset(buffer_->inset());
LyXFont const font = cursor_.getFont();
int const asc = font_metrics::maxAscent(font);
int const des = font_metrics::maxDescent(font);
- Point const p = bv_funcs::getPos(cursor_);
+ Point const p = bv_funcs::getPos(cursor_, cursor_.boundary());
if (p.y_ - asc >= 0 && p.y_ + des < workarea().workHeight())
return false;
}
bot.text()->redoParagraph(pit);
Paragraph const & par = bot.text()->paragraphs()[pit];
anchor_ref_ = pit;
- offset_ref_ = bv_funcs::coordOffset(cursor_).y_ + par.ascent()
- - workarea().workHeight() / 2;
+ offset_ref_ = bv_funcs::coordOffset(cursor_, cursor_.boundary()).y_
+ + par.ascent() - workarea().workHeight() / 2;
}
// the next two should probably go elsewhere
// this give the position relative to (0, baseline) of outermost
// paragraph
-Point coordOffset(DocIterator const & dit)
+Point coordOffset(DocIterator const & dit, bool boundary)
{
int x = 0;
int y = 0;
CursorSlice const & sl = dit[i];
int xx = 0;
int yy = 0;
- sl.inset().getCursorPos(sl, xx, yy);
+ sl.inset().cursorPos(sl, boundary, xx, yy);
x += xx;
y += yy;
- //lyxerr << "LCursor::getPos, i: " << i << " x: " << xx << " y: " << y << endl;
+ //lyxerr << "LCursor::getPos, i: "
+ // << i << " x: " << xx << " y: " << y << endl;
}
// Add contribution of initial rows of outermost paragraph
CursorSlice const & sl = dit[0];
Paragraph const & par = sl.text()->getPar(sl.pit());
y -= par.rows()[0].ascent();
- for (size_t rit = 0, rend = par.pos2row(sl.pos()); rit != rend; ++rit)
+ //size_t rend = par.pos2row(sl.pos() - boundary ? 1 : 0);
+ size_t rend = par.pos2row(sl.pos());
+ for (size_t rit = 0; rit != rend; ++rit)
y += par.rows()[rit].height();
- y += par.rows()[par.pos2row(sl.pos())].ascent();
- x += dit.bottom().text()->cursorX(dit.bottom());
+ y += par.rows()[rend].ascent();
+ x += dit.bottom().text()->cursorX(dit.bottom(), boundary);
// The following correction should not be there at all.
- // The cusor looks much better with the -1, though.
+ // The cursor looks much better with the -1, though.
--x;
return Point(x, y);
}
-Point getPos(DocIterator const & dit)
+Point getPos(DocIterator const & dit, bool boundary)
{
CursorSlice const & bot = dit.bottom();
- CoordCache::InnerParPosCache const & cache = theCoords.getParPos().find(bot.text())->second;
+ CoordCache::InnerParPosCache const & cache =
+ theCoords.getParPos().find(bot.text())->second;
CoordCache::InnerParPosCache::const_iterator it = cache.find(bot.pit());
if (it == cache.end()) {
//lyxerr << "cursor out of view" << std::endl;
return Point(-1, -1);
}
- Point p = coordOffset(dit); // offset from outer paragraph
+ Point p = coordOffset(dit, boundary); // offset from outer paragraph
p.y_ += it->second.y_;
return p;
}
#include <string>
#include <vector>
-class LyXFont;
-class Point;
-class DocIterator;
class BufferView;
+class DocIterator;
class InsetBase_code;
+class LyXFont;
+class Point;
namespace bv_funcs {
*/
std::string const freefont2string();
-Point getPos(DocIterator const & dit);
+Point getPos(DocIterator const & dit, bool boundary);
enum CurStatus {
CUR_INSIDE,
CurStatus status(BufferView const * bv, DocIterator const & dit);
-Point coordOffset(DocIterator const & dit);
+Point coordOffset(DocIterator const & dit, bool boundary);
/// Moves cursor to the next inset with one of the given codes.
void gotoInset(BufferView * bv, std::vector<InsetBase_code> const & codes,
for (int i = 0; ; ++i) {
int xo;
int yo;
- LCursor cur = c;
- cur.setCursor(it);
- cur.inset().getCursorPos(cur.top(), xo, yo);
+ it.inset().cursorPos(it.top(), c.boundary(), xo, yo);
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
// '<=' in order to take the last possible position
// this is important for clicking behind \sum in e.g. '\sum_i a'
// avoid invalid nesting when selecting
if (bv_funcs::status(&cursor.bv(), it) == bv_funcs::CUR_INSIDE
&& (!cursor.selection() || positionable(it, cursor.anchor_))) {
- Point p = bv_funcs::getPos(it);
+ Point p = bv_funcs::getPos(it, false);
int xo = p.x_;
int yo = p.y_;
if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
// bv functions are not yet available!
LCursor::LCursor(BufferView & bv)
: DocIterator(), bv_(&bv), anchor_(), x_target_(-1),
- selection_(false), mark_(false)
+ selection_(false), mark_(false), logicalpos_(false)
{}
void LCursor::getPos(int & x, int & y) const
{
- Point p = bv_funcs::getPos(*this);
+ Point p = bv_funcs::getPos(*this, boundary());
x = p.x_;
y = p.y_;
}
bool selection_;
/// are we on the way to get one?
bool mark_;
+ /// If true, we are behind the previous char, otherwise we are in front
+ // of the next char. This only make a difference when we are in front
+ // of a big inset spanning a whole row and computing coordinates for
+ // displaying the cursor.
+ bool logicalpos_;
private:
CursorSlice::CursorSlice()
- : inset_(0), idx_(0), pit_(0), pos_(0), boundary_(false)
+ : inset_(0), idx_(0), pit_(0), pos_(0)
{}
CursorSlice::CursorSlice(InsetBase & p)
- : inset_(&p), idx_(0), pit_(0), pos_(0), boundary_(false)
+ : inset_(&p), idx_(0), pit_(0), pos_(0)
{
BOOST_ASSERT(inset_);
}
///
/// texted specific stuff
///
- /// \sa boundary_
- bool boundary() const { return boundary_; }
- /// \sa boundary_
- bool & boundary() { return boundary_; }
/// returns text corresponding to this position
LyXText * text();
/// returns text corresponding to this position
bool pit_valid_;
/// position in this cell
pos_type pos_;
- /**
- * When the cursor position is i, is the cursor after the i-th char
- * or before the i+1-th char ? Normally, these two interpretations are
- * equivalent, except when the fonts of the i-th and i+1-th char
- * differ.
- * We use boundary_ to distinguish between the two options:
- * If boundary_=true, then the cursor is after the i-th char
- * and if boundary_=false, then the cursor is before the i+1-th char.
- *
- * We currently use the boundary only when the language direction of
- * the i-th char is different than the one of the i+1-th char.
- * In this case it is important to distinguish between the two
- * cursor interpretations, in order to give a reasonable behavior to
- * the user.
- */
- bool boundary_;
};
/// test for equality
explicit DocIterator(InsetBase & inset);
/// access slice at position \p i
- CursorSlice const & operator[](size_t i) const {
- return slices_[i];
- }
-
+ CursorSlice const & operator[](size_t i) const { return slices_[i]; }
/// access slice at position \p i
- CursorSlice & operator[](size_t i) {
- return slices_[i];
- }
-
- // What is the point of this function?
+ CursorSlice & operator[](size_t i) { return slices_[i]; }
+ /// chop a few slices from the iterator
void resize(size_t i) { slices_.resize(i); }
/// is the iterator valid?
InsetBase * prevInset();
/// the inset just in front of the cursor
InsetBase const * prevInset() const;
+ ///
+ bool boundary() const { return boundary_; }
+ ///
+ void boundary(bool b) { boundary_ = b; }
/// are we in mathed?
bool inMathed() const;
//
// text-specific part
//
- /// \sa boundary_
- bool boundary() const { return top().boundary(); }
- /// \sa boundary_
- bool & boundary() { return top().boundary(); }
/// the paragraph we're in
Paragraph & paragraph();
/// the paragraph we're in
/// output
friend std::ostream &
operator<<(std::ostream & os, DocIterator const & cur);
+ ///
friend bool operator==(DocIterator const &, DocIterator const &);
+ ///
friend class StableDocIterator;
protected:
+ ///
void clear() { slices_.clear(); }
- void push_back(CursorSlice const & sl) {
- slices_.push_back(sl);
- }
- void pop_back() {
- slices_.pop_back();
- }
+ ///
+ void push_back(CursorSlice const & sl) { slices_.push_back(sl); }
+ ///
+ void pop_back() { slices_.pop_back(); }
private:
+ /**
+ * When the cursor position is i, is the cursor after the i-th char
+ * or before the i+1-th char ? Normally, these two interpretations are
+ * equivalent, except when the fonts of the i-th and i+1-th char
+ * differ.
+ * We use boundary_ to distinguish between the two options:
+ * If boundary_=true, then the cursor is after the i-th char
+ * and if boundary_=false, then the cursor is before the i+1-th char.
+ *
+ * We currently use the boundary only when the language direction of
+ * the i-th char is different than the one of the i+1-th char.
+ * In this case it is important to distinguish between the two
+ * cursor interpretations, in order to give a reasonable behavior to
+ * the user.
+ */
+ bool boundary_;
+ ///
std::vector<CursorSlice> const & internalData() const {
return slices_;
}
+ ///
std::vector<CursorSlice> slices_;
+ ///
InsetBase * inset_;
};
{}
-void InsetBase::getCursorPos(CursorSlice const &, int & x, int & y) const
+void InsetBase::cursorPos(CursorSlice const &, bool, int & x, int & y) const
{
- lyxerr << "InsetBase::getCursorPos called directly" << std::endl;
+ lyxerr << "InsetBase::cursorPos called directly" << std::endl;
x = 100;
y = 100;
}
/// do we cover screen position x/y?
virtual bool covers(int x, int y) const;
/// get the screen positions of the cursor (see note in cursor.C)
- virtual void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ virtual void cursorPos(CursorSlice const & sl, bool boundary,
+ int & x, int & y) const;
/// is this an inset that can be moved into?
virtual bool isActive() const { return nargs() > 0; }
}
-void InsetCollapsable::getCursorPos
- (CursorSlice const & sl, int & x, int & y) const
+void InsetCollapsable::cursorPos
+ (CursorSlice const & sl, bool boundary, int & x, int & y) const
{
if (status_ == Collapsed) {
x = xo();
y = yo();
- return;
- }
-
- InsetText::getCursorPos(sl, x, y);
- if (status_ == Open) {
- if (openinlined_)
- x += dimensionCollapsed().wid;
- else
- y += dimensionCollapsed().height() - ascent() + TEXT_TO_INSET_OFFSET + textdim_.asc;
+ } else {
+ InsetText::cursorPos(sl, boundary, x, y);
+ if (status_ == Open) {
+ if (openinlined_)
+ x += dimensionCollapsed().wid;
+ else
+ y += dimensionCollapsed().height() - ascent()
+ + TEXT_TO_INSET_OFFSET + textdim_.asc;
+ }
+ x += TEXT_TO_INSET_OFFSET;
}
-
- x += TEXT_TO_INSET_OFFSET;
}
pos_type const n = min(max_length, p_siz);
pos_type i = 0;
pos_type j = 0;
- for( ; i < n && j < p_siz; ++j) {
+ for (; i < n && j < p_siz; ++j) {
if (paragraphs().begin()->isInset(j))
continue;
label += paragraphs().begin()->getChar(j);
///
void drawSelection(PainterInfo & pi, int x, int y) const;
/// return x,y of given position relative to the inset's baseline
- void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ void cursorPos(CursorSlice const & sl, bool boundary, int & x, int & y) const;
///
bool hitButton(FuncRequest const &) const;
///
}
-void InsetTabular::getCursorPos(CursorSlice const & sl, int & x, int & y) const
+void InsetTabular::cursorPos
+ (CursorSlice const & sl, bool boundary, int & x, int & y) const
{
- cell(sl.idx())->getCursorPos(sl, x, y);
+ cell(sl.idx())->cursorPos(sl, boundary, x, y);
// y offset correction
int const row = tabular.row_of_cell(sl.idx());
///
Code lyxCode() const { return InsetBase::TABULAR_CODE; }
/// get offset of this cursor slice relative to our upper left corner
- void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ void cursorPos(CursorSlice const & sl, bool boundary, int & x, int & y) const;
///
bool tabularFeatures(LCursor & cur, std::string const & what);
///
}
-void InsetText::getCursorPos(CursorSlice const & sl, int & x, int & y) const
+void InsetText::cursorPos
+ (CursorSlice const & sl, bool boundary, int & x, int & y) const
{
- x = text_.cursorX(sl) + border_;
- y = text_.cursorY(sl);
+ x = text_.cursorX(sl, boundary) + border_;
+ y = text_.cursorY(sl, boundary);
}
void validate(LaTeXFeatures & features) const;
/// return x,y of given position relative to the inset's baseline
- void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ void cursorPos(CursorSlice const & sl, bool boundary, int & x, int & y) const;
///
Code lyxCode() const { return TEXT_CODE; }
///
///
int descent() const;
///
- int cursorX(CursorSlice const & cursor) const;
+ int cursorX(CursorSlice const & cursor, bool boundary) const;
///
- int cursorY(CursorSlice const & cursor) const;
+ int cursorY(CursorSlice const & cursor, bool boundary) const;
///
friend class LyXScreen;
}
-void MathMBoxInset::getCursorPos(CursorSlice const & sl, int & x, int & y) const
+void MathMBoxInset::cursorPos
+ (CursorSlice const & sl, bool boundary, int & x, int & y) const
{
- x = text_.cursorX(sl);
- y = text_.cursorY(sl);
+ x = text_.cursorX(sl, boundary);
+ y = text_.cursorY(sl, boundary);
}
///
LyXText * getText(int) const;
///
- void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ void cursorPos(CursorSlice const & sl, bool boundary, int & x, int & y) const;
protected:
virtual void doDispatch(LCursor & cur, FuncRequest & cmd);
}
-void MathNestInset::getCursorPos(CursorSlice const & sl,
+void MathNestInset::cursorPos(CursorSlice const & sl, bool boundary,
int & x, int & y) const
{
// FIXME: This is a hack. Ideally, the coord cache should not store
/// identifies NestInsets
MathNestInset const * asNestInset() const { return this; }
/// get cursor position
- void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
+ void cursorPos(CursorSlice const & sl, bool boundary, int & x, int & y) const;
///
void edit(LCursor & cur, bool left);
///
if (bv_owner->text() == this) {
if (pit == 0 && row.pos() == 0)
maxasc += 20;
- if (pit == pars_.size() - 1 && row.endpos() == par.size())
+ if (pit + 1 == pars_.size() && row.endpos() == par.size())
maxdesc += 20;
}
current_font = rawtmpfont;
real_current_font = realtmpfont;
- setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+ //setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+ setCursor(cur, cur.pit(), cur.pos() + 1, false, true);
charInserted();
}
x2 = 0;
} else {
y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
- int const startx = cursorX(beg.top());
+ int const startx = cursorX(beg.top(), begin.boundary());
x1 = isRTL(par1) ? startx : 0;
x2 = isRTL(par1) ? 0 + dim_.wid : startx;
}
X2 = 0;
} else {
y2 = bv_funcs::getPos(end).y_ + row2.descent();
- int const endx = cursorX(end.top());
+ int const endx = cursorX(end.top(), end.boundary());
X1 = isRTL(par2) ? 0 : endx;
X2 = isRTL(par2) ? endx : 0 + dim_.wid;
}
x2 = dim_.wid;
} else {
Row const & row1 = par1.getRow(beg.pos());
- y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
+ y1 = bv_funcs::getPos(beg, beg.boundary()).y_ - row1.ascent();
y2 = y1 + row1.height();
- int const startx = cursorX(beg.top());
+ int const startx = cursorX(beg.top(), beg.boundary());
x1 = !isRTL(par1) ? startx : 0;
x2 = !isRTL(par1) ? 0 + dim_.wid : startx;
}
X2 = dim_.wid;
} else {
Row const & row2 = par2.getRow(end.pos());
- Y1 = bv_funcs::getPos(end).y_ - row2.ascent();
+ Y1 = bv_funcs::getPos(end, end.boundary()).y_ - row2.ascent();
Y2 = Y1 + row2.height();
- int const endx = cursorX(end.top());
+ int const endx = cursorX(end.top(), end.boundary());
X1 = !isRTL(par2) ? 0 : endx;
X2 = !isRTL(par2) ? endx : 0 + dim_.wid;
}
Y1 - y2, LColor::selection);
}
+
bool LyXText::isLastRow(pit_type pit, Row const & row) const
{
return row.endpos() >= pars_[pit].size()
}
-int LyXText::cursorX(CursorSlice const & cur) const
+int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
{
- pit_type const pit = cur.pit();
+ pit_type const pit = sl.pit();
Paragraph const & par = pars_[pit];
if (par.rows().empty())
return 0;
- Row const & row = par.getRow(cur.pos());
+ pos_type pos = sl.pos();
+ //// Correct position in front of big insets
+ //if (pos && boundary)
+ // --pos;
+
+ Row const & row = par.getRow(pos);
- pos_type pos = cur.pos();
pos_type cursor_vpos = 0;
RowMetrics const m = computeRowMetrics(pit, row);
} else
x += singleWidth(par, pos);
}
+
+ // see correction above
+ //if (pos && boundary)
+ // x += singleWidth(par, pos + 1);
+
return int(x);
}
-int LyXText::cursorY(CursorSlice const & cur) const
+int LyXText::cursorY(CursorSlice const & sl, bool boundary) const
{
- Paragraph const & par = getPar(cur.pit());
+ //lyxerr << "LyXText::cursorY: boundary: " << boundary << std::endl;
+ Paragraph const & par = getPar(sl.pit());
int h = 0;
h -= pars_[0].rows()[0].ascent();
- for (pit_type pit = 0; pit < cur.pit(); ++pit)
+ for (pit_type pit = 0; pit < sl.pit(); ++pit)
h += pars_[pit].height();
- for (size_t rit = 0, rend = par.pos2row(cur.pos()); rit != rend; ++rit)
+ //size_t const rend = par.pos2row(sl.pos() - boundary ? 1 : 0);
+ size_t const rend = par.pos2row(sl.pos());
+ for (size_t rit = 0; rit != rend; ++rit)
h += par.rows()[rit].height();
- h += par.rows()[par.pos2row(cur.pos())].ascent();
+ h += par.rows()[rend].ascent();
return h;
}
pos_type LyXText::x2pos(pit_type pit, int row, int x) const
{
- BOOST_ASSERT(row < pars_[pit].rows().size());
+ BOOST_ASSERT(row < int(pars_[pit].rows().size()));
bool bound = false;
Row const & r = pars_[pit].rows()[row];
return r.pos() + getColumnNearX(pit, r, x, bound);
{
LCursor old = cur;
setCursorIntern(cur, par, pos, setfont, boundary);
+ cur.boundary(boundary);
return deleteEmptyParagraphMechanism(cur, old);
}
BOOST_ASSERT(par != int(paragraphs().size()));
cur.pit() = par;
cur.pos() = pos;
- cur.boundary() = boundary;
// now some strict checking
Paragraph & para = getPar(par);
pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
cur.pit() = pit;
cur.pos() = pos;
- cur.boundary() = bound;
+ cur.boundary(bound);
cur.x_target() = x;
// try to descend into nested insets
int const x = cur.targetX();
if (!cur.selection()) {
- int const y = bv_funcs::getPos(cur).y_;
+ int const y = bv_funcs::getPos(cur, cur.boundary()).y_;
LCursor old = cur;
editXY(cur, x, y - par.rows()[row].ascent() - 1);
int const x = cur.targetX();
if (!cur.selection()) {
- int const y = bv_funcs::getPos(cur).y_;
+ int const y = bv_funcs::getPos(cur, cur.boundary()).y_;
LCursor old = cur;
editXY(cur, x, y + par.rows()[row].descent() + 1);
case LFUN_RIGHT:
case LFUN_RIGHTSEL:
- lyxerr << BOOST_CURRENT_FUNCTION
- << " LFUN_RIGHT[SEL]:\n" << cur << endl;
+ //lyxerr << BOOST_CURRENT_FUNCTION
+ // << " LFUN_RIGHT[SEL]:\n" << cur << endl;
cur.selHandle(cmd.action == LFUN_RIGHTSEL);
if (isRTL(cur.paragraph()))
needsUpdate = cursorLeft(cur);
break;
case LFUN_GETXY:
- cur.message(convert<string>(cursorX(cur.top())) + ' '
- + convert<string>(cursorY(cur.top())));
+ cur.message(convert<string>(cursorX(cur.top(), cur.boundary())) + ' '
+ + convert<string>(cursorY(cur.top(), cur.boundary())));
break;
case LFUN_SETXY: {