int const last = top_y() + workarea().workHeight() - height;
LyXText * text = bv_->text();
- if (text->cursor.y() < first)
+ if (text->cursorY() < first)
text->setCursorFromCoordinates(0, first);
- else if (text->cursor.y() > last)
+ else if (text->cursorY() > last)
text->setCursorFromCoordinates(0, last);
owner_->updateLayoutChoice();
text->clearSelection();
int const half_height = workarea().workHeight() / 2;
- int new_y = std::max(0, text->cursor.y() - half_height);
+ int new_y = std::max(0, text->cursorY() - half_height);
// FIXME: look at this comment again ...
// This updates top_y() but means the fitCursor() call
+
+2003-12-15 André Pönitz <poenitz@gmx.net>
+
+ * cursor_slice.[Ch]: new class to cover texted and mathed's cursor slices
+
+ * Makefile.am:
+
+ * BufferView_pimpl.C:
+ * cursor.[Ch]:
+ * lyxcursor.[Ch]:
+ * rowpainter.[Ch]:
+ * lyxtext.h:
+ * text.C:
+ * text2.C:
+ * text3.C: adjust
+
2003-12-15 Angus Leeming <leeming@lyx.org>
* metricsinfo.C (ColorChanger): use LColor::getFromLyXName rather
2003-12-14 Angus Leeming <leeming@lyx.org>
- BranchList.[Ch]: minimize the API.
+ * BranchList.[Ch]: minimize the API.
(Branch::getBranch, getColor): now return a 'const &'.
(Branch::setSelected) now returns a bool set to true if the
selection status changes.
counters.h \
cursor.C \
cursor.h \
+ cursor_slice.C \
+ cursor_slice.h \
debug.C \
debug.h \
dimension.C \
using std::endl;
-std::ostream & operator<<(std::ostream & os, CursorItem const & item)
-{
- os << " inset: " << item.inset_
- << " code: " << item.inset_->lyxCode()
- << " text: " << item.text()
- << " idx: " << item.idx_
-// << " par: " << item.par_
-// << " pos: " << item.pos_
- << " x: " << item.inset_->x()
- << " y: " << item.inset_->y()
-;
- return os;
-}
-
-
-LyXText * CursorItem::text() const
-{
- return inset_->getText(0);
-}
-
-
std::ostream & operator<<(std::ostream & os, LCursor const & cursor)
{
os << "\n";
FuncRequest cmd = cmd0;
for (int i = data_.size() - 1; i >= 0; --i) {
- CursorItem const & citem = data_[i];
+ CursorSlice const & citem = data_[i];
lyxerr << "trying to dispatch to inset " << citem.inset_ << endl;
DispatchResult res = citem.inset_->dispatch(cmd);
if (res.dispatched()) {
void LCursor::push(UpdatableInset * inset)
{
lyxerr << "LCursor::push() inset: " << inset << endl;
- data_.push_back(CursorItem(inset));
+ data_.push_back(CursorSlice(inset));
updatePos();
}
UpdatableInset * LCursor::innerInset() const
{
- return data_.empty() ? 0 : data_.back().inset_;
+ return data_.empty() ? 0 : data_.back().asUpdatableInset();
}
void LCursor::getPos(int & x, int & y) const
{
if (data_.empty()) {
- x = bv_->text()->cursor.x();
- y = bv_->text()->cursor.y();
+ x = bv_->text()->cursorX();
+ y = bv_->text()->cursorY();
// y -= bv_->top_y();
} else {
// Would be nice to clean this up to make some understandable sense...
// inset->draw() is not called: this doesn't update
// inset.top_baseline, so getCursor() returns an old value.
// Ugly as you like.
- //inset->getCursorPos(bv_, x, y);
inset->getCursorPos(x, y);
x += inset->x();
y += cached_y_;
UpdatableInset * LCursor::innerInsetOfType(int code) const
{
for (int i = data_.size() - 1; i >= 0; --i)
- if (data_[i].inset_->lyxCode() == code)
- return data_[i].inset_;
+ if (data_[i].asUpdatableInset()->lyxCode() == code)
+ return data_[i].asUpdatableInset();
return 0;
}
#define CURSOR_H
#include "textcursor.h"
+#include "cursor_slice.h"
#include "support/types.h"
* The cursor class describes the position of a cursor within a document.
*/
-class CursorItem {
-public:
- ///
- CursorItem() : inset_(0), idx_(0), par_(0), pos_(0) {}
- ///
- explicit CursorItem(UpdatableInset * inset)
- : inset_(inset), idx_(0), par_(0), pos_(0)
- {}
- ///
- LyXText * text() const;
- ///
- friend std::ostream & operator<<(std::ostream &, CursorItem const &);
-public:
- ///
- UpdatableInset * inset_;
- ///
- int idx_;
- ///
- int par_;
- ///
- int pos_;
-};
-
class LCursor {
public:
friend std::ostream & operator<<(std::ostream &, LCursor const &);
public:
/// mainly used as stack, but wee need random access
- std::vector<CursorItem> data_;
+ std::vector<CursorSlice> data_;
///
BufferView * bv_;
private:
--- /dev/null
+/**
+ * \file cursor_slice.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "cursor_slice.h"
+#include "debug.h"
+
+#include "mathed/math_inset.h"
+#include "insets/updatableinset.h"
+
+#include <boost/assert.hpp>
+
+using std::endl;
+
+
+CursorSlice::CursorSlice()
+ : inset_(0), idx_(0), par_(0), pos_(0)
+{}
+
+
+CursorSlice::CursorSlice(InsetBase * p)
+ : inset_(p), idx_(0), par_(0), pos_(0)
+{
+ ///BOOST_ASSERT(inset_);
+}
+
+
+MathInset * CursorSlice::asMathInset() const
+{
+ return static_cast<MathInset *>(const_cast<InsetBase *>(inset_));
+}
+
+
+UpdatableInset * CursorSlice::asUpdatableInset() const
+{
+ return static_cast<UpdatableInset *>(const_cast<InsetBase *>(inset_));
+}
+
+
+MathArray & CursorSlice::cell(CursorSlice::idx_type idx) const
+{
+ BOOST_ASSERT(inset_);
+ return asMathInset()->cell(idx);
+}
+
+
+MathArray & CursorSlice::cell() const
+{
+ BOOST_ASSERT(inset_);
+ return asMathInset()->cell(idx_);
+}
+
+
+void CursorSlice::getPos(int & x, int & y) const
+{
+ asMathInset()->getPos(idx_, pos_, x, y);
+}
+
+
+void CursorSlice::setPos(int pos)
+{
+ pos_ = pos;
+}
+
+
+LyXText * CursorSlice::text() const
+{
+ return asUpdatableInset()->getText(idx_);
+}
+
+
+bool operator==(CursorSlice const & p, CursorSlice const & q)
+{
+ return p.inset_ == q.inset_
+ && p.idx_ == q.idx_
+ && p.par_ == q.par_
+ && p.pos_ == q.pos_;
+}
+
+
+bool operator!=(CursorSlice const & p, CursorSlice const & q)
+{
+ return p.inset_ != q.inset_
+ || p.idx_ != q.idx_
+ || p.par_ != q.par_
+ || p.pos_ != q.pos_;
+}
+
+
+bool operator<(CursorSlice const & p, CursorSlice const & q)
+{
+ if (p.inset_ != q.inset_) {
+ lyxerr << "can't compare cursor and anchor in different insets\n"
+ << "p: " << p << '\n' << "q: " << q << endl;
+ return true;
+ }
+ if (p.idx_ != q.idx_)
+ return p.idx_ < q.idx_;
+ if (p.par_ != q.par_)
+ return p.par_ < q.par_;
+ return p.pos_ < q.pos_;
+}
+
+
+//std::ostream & operator<<(std::ostream & os, CursorSlice const & p)
+//{
+// os << "(par: " << p.inset_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ')';
+// return os;
+//}
+
+
+std::ostream & operator<<(std::ostream & os, CursorSlice const & item)
+{
+ os << " inset: " << item.inset_
+// << " text: " << item.text()
+ << " idx: " << item.idx_
+// << " par: " << item.par_
+// << " pos: " << item.pos_
+// << " x: " << item.inset_->x()
+// << " y: " << item.inset_->y()
+;
+ return os;
+}
+
+
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file cursor_slice.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef CURSORSLICE_H
+#define CURSORSLICE_H
+
+#include <iosfwd>
+#include <cstddef>
+
+class InsetBase;
+class UpdatableInset;
+class MathInset;
+class LyXText;
+class MathArray;
+
+
+/// This encapsulates a single slice of a document iterator as used e.g.
+/// for cursors.
+
+// After IU, the distinction of MathInset and UpdatableInset as well as
+// that of MathArray and LyXText should vanish. They are conceptually the
+// same (now...)
+
+class CursorSlice {
+public:
+ /// type for cell number in inset
+ typedef size_t idx_type;
+ /// type for paragraph numbers positions within a cell
+ typedef size_t par_type;
+ /// type for cursor positions within a cell
+ typedef size_t pos_type;
+
+ ///
+ CursorSlice();
+ ///
+ explicit CursorSlice(InsetBase *);
+
+ ///
+ /// texted specific stuff
+ ///
+ ///
+ LyXText * text() const;
+ ///
+ UpdatableInset * asUpdatableInset() const;
+
+ ///
+ /// mathed specific stuff
+ ///
+ /// returns cell corresponding to this position
+ MathArray & cell() const;
+ /// returns cell corresponding to this position
+ MathArray & cell(idx_type idx) const;
+ /// gets screen position of the thing
+ void getPos(int & x, int & y) const;
+ /// set position
+ void setPos(int pos);
+ ///
+ MathInset * asMathInset() const;
+
+ ///
+ friend std::ostream & operator<<(std::ostream &, CursorSlice const &);
+public:
+ /// pointer to an inset
+ InsetBase * inset_;
+ /// cell index of a position in this inset
+ idx_type idx_;
+ /// paragraph in this cell (used by texted)
+ par_type par_;
+ /// position in this cell
+ pos_type pos_;
+};
+
+/// test for equality
+bool operator==(CursorSlice const &, CursorSlice const &);
+/// test for inequality
+bool operator!=(CursorSlice const &, CursorSlice const &);
+/// test for order
+bool operator<(CursorSlice const &, CursorSlice const &);
+
+#endif
+
+2003-12-15 André Pönitz <poenitz@gmx.net>
+
+ * insettabular.[Ch]:
+ * insettext.C: adjust to changed name in CursorItem -> CursorSlice
+
2003-12-12 Angus Leeming <leeming@lyx.org>
* insetbranch.C (c-tor): takes an InsetBranchParams arg rather than
tabular.setOwner(this);
actrow = 0;
actcell = 0;
- locked_cell = -1;
clearSelection();
in_reset_pos = 0;
}
actrow = 0;
actcell = 0;
clearSelection();
- locked_cell = -1;
in_reset_pos = 0;
}
void InsetTabular::drawCellSelection(Painter & pain, int x, int y,
int row, int column, int cell) const
{
- if (locked_cell != -1)
+ if (actcell != -1)
return;
BOOST_ASSERT(hasSelection());
lyxerr << "# InsetTabular::lfunMousePress cell: " << cell << endl;
if (cell == -1) {
bv->cursor() = theTempCursor;
- bv->cursor().data_.push_back(CursorItem(this));
+ bv->cursor().data_.push_back(CursorSlice(this));
bv->cursor().data_.back().idx_ = cell;
} else {
setPos(bv, cmd.x, cmd.y);
bv->cursor() = theTempCursor;
bv->cursor().data_.back().idx_ = cell;
}
- locked_cell = cell;
+ actcell = cell;
lyxerr << bv->cursor() << endl;
if (cmd.button() == mouse_button::button2)
bv->fitCursor();
bv->cursor().push(this);
bv->cursor().data_.back().idx_ = actcell;
- locked_cell = actcell;
lyxerr << bv->cursor() << endl;
}
int xx = cursorx_ - xo_ + tabular.getBeginningOfTextInCell(actcell);
bv->cursor().push(this);
if (x > xx)
- activateCellInset(bv, x - xx, y - cursory_, false);
+ activateCellInset(bv, actcell, x - xx, y - cursory_);
}
break;
}
-
int cell = bv->cursor().data_.back().idx_;
if (cell != -1) {
+
+ if (cell != actcell) {
+ lyxerr << "## ERROR ## InsetTabular::priv_dispatch: actcell: "
+ << actcell << " and cell " << cell << " should be the same "
+ << "here" << endl;
+ }
+
lyxerr << "# InsetTabular::dispatch 1: " << cmd << endl;
result = tabular.getCellInset(cell).dispatch(cmd, idx, pos);
switch (result.val()) {
- case LFUN_FINISHED_LEFT:
- lyxerr << "handle LFUN_FINISHED_LEFT, act: " << actcell << endl;
+ case FINISHED:
+ lyxerr << "# handle FINISHED_LEFT, act: " << actcell << endl;
if (movePrevCell(bv, false))
result = DispatchResult(true, true);
else
result = DispatchResult(false, FINISHED);
break;
- case LFUN_FINISHED_RIGHT:
- lyxerr << "handle LFUN_FINISHED_RIGHT, act: " << actcell << endl;
+ case FINISHED_RIGHT:
+ lyxerr << "# handle FINISHED_RIGHT, act: " << actcell << endl;
if (moveNextCell(bv, false))
result = DispatchResult(true, true);
else
result = DispatchResult(false, FINISHED_RIGHT);
break;
- case LFUN_FINISHED_UP:
- lyxerr << "handle LFUN_FINISHED_UP, act: " << actcell << endl;
+ case FINISHED_UP:
+ lyxerr << "# handle FINISHED_UP, act: " << actcell << endl;
result = moveUp(bv, true);
break;
- case LFUN_FINISHED_DOWN:
- lyxerr << "handle LFUN_FINISHED_DOWN, act: " << actcell << endl;
+ case FINISHED_DOWN:
+ lyxerr << "# handle FINISHED_DOWN, act: " << actcell << endl;
result = moveDown(bv, true);
break;
default:
+ lyxerr << "# don't handle dispatch in act: " << actcell << endl;
break;
}
void InsetTabular::getCursorPos(int & x, int & y) const
{
- if (locked_cell == -1) {
+ if (actcell == -1) {
x = TEXT_TO_INSET_OFFSET + cursorx_ - xo_;
y = TEXT_TO_INSET_OFFSET + cursory_;
} else {
- tabular.getCellInset(locked_cell).getCursorPos(x, y);
- x = TEXT_TO_INSET_OFFSET;
+ InsetText const & inset = tabular.getCellInset(actcell);
+ inset.getCursorPos(x, y);
+ x += inset.x() - xo_;
+ y += inset.y() - yo_;
}
}
if (!moved)
return DispatchResult(false, FINISHED_RIGHT);
if (lock) {
- activateCellInset(bv, 0, 0, false);
+ activateCellInset(bv, actcell, false);
return DispatchResult(true, true);
}
resetPos(bv);
return DispatchResult(false, FINISHED);
// behind the inset
if (lock) {
- activateCellInset(bv, 0, 0, true);
+ activateCellInset(bv, actcell, true);
return DispatchResult(true, true);
}
resetPos(bv);
return DispatchResult(false, FINISHED_UP);
resetPos(bv);
if (lock)
- activateCellInset(bv, bv->x_target(), 0, false);
+ activateCellInset(bv, actcell, bv->x_target(), 0);
return DispatchResult(true, true);
}
return DispatchResult(false, FINISHED_DOWN);
resetPos(bv);
if (lock)
- activateCellInset(bv, bv->x_target(), 0, false);
+ activateCellInset(bv, actcell, bv->x_target());
return DispatchResult(true, true);
}
bool InsetTabular::moveNextCell(BufferView * bv, bool lock)
{
+ lyxerr << "InsetTabular::moveNextCell 1 actcell: " << actcell << endl;
if (isRightToLeft(bv)) {
if (tabular.isFirstCellInRow(actcell)) {
int row = tabular.row_of_cell(actcell);
actcell = tabular.getLastCellInRow(row);
actcell = tabular.getCellBelow(actcell);
} else {
- if (!actcell)
+ if (actcell == 0)
return false;
--actcell;
}
return false;
++actcell;
}
+ lyxerr << "InsetTabular::moveNextCell 2 actcell: " << actcell << endl;
if (lock) {
bool rtl = tabular.getCellInset(actcell).paragraphs().begin()->
isRightToLeftPar(bv->buffer()->params());
- activateCellInset(bv, 0, 0, !rtl);
+ activateCellInset(bv, actcell, !rtl);
}
resetPos(bv);
return true;
if (lock) {
bool rtl = tabular.getCellInset(actcell).paragraphs().begin()->
isRightToLeftPar(bv->buffer()->params());
- activateCellInset(bv, 0, 0, !rtl);
+ activateCellInset(bv, actcell, !rtl);
}
lyxerr << "move prevcell 3" << endl;
resetPos(bv);
}
-void InsetTabular::activateCellInset(BufferView * bv, int x, int y, bool behind)
+void InsetTabular::activateCellInset(BufferView * bv, int cell, int x, int y)
{
- UpdatableInset & inset = tabular.getCellInset(actcell);
- if (behind) {
-#warning metrics?
- x = inset.x() + inset.width();
- y = inset.descent();
- }
- inset.edit(bv, x, y);
+ actcell = cell;
+ tabular.getCellInset(actcell).edit(bv, x, y);
bv->cursor().data_.back().idx_ = actcell;
- locked_cell = actcell;
updateLocal(bv);
}
+void InsetTabular::activateCellInset(BufferView * bv, int cell, bool behind)
+{
+ actcell = cell;
+ tabular.getCellInset(actcell).edit(bv, behind);
+ bv->cursor().data_.back().idx_ = actcell;
+ updateLocal(bv);
+}
+
+
+
bool InsetTabular::showInsetDialog(BufferView * bv) const
{
InsetTabularMailer(*this).showDialog(bv);
has_selection = true;
}
///
- void activateCellInset(BufferView *, int x, int y, bool behind);
+ void activateCellInset(BufferView *, int cell, int x, int y);
+ ///
+ void activateCellInset(BufferView *, int cell, bool behind);
///
bool hasPasteBuffer() const;
///
mutable int sel_cell_start;
/// the ending cell selection nr
mutable int sel_cell_end;
- /// -1: no cell, >= 0 cell
- mutable int locked_cell;
///
mutable int actcell;
///
DispatchResult InsetText::priv_dispatch(FuncRequest const & cmd,
idx_type &, pos_type &)
{
- lyxerr << "InsetText::priv_dispatch (begin), act: "
- << cmd.action << " " << endl;
+ //lyxerr << "InsetText::priv_dispatch (begin), act: "
+ // << cmd.action << " " << endl;
BufferView * bv = cmd.view();
setViewCache(bv);
text_.setFont(font, false);
}
- lyxerr << "InsetText::priv_dispatch (end)" << endl;
+ //lyxerr << "InsetText::priv_dispatch (end)" << endl;
return result;
}
void InsetText::getCursorPos(int & x, int & y) const
{
- x = text_.cursor.x() + TEXT_TO_INSET_OFFSET;
- y = text_.cursor.y() - dim_.asc + TEXT_TO_INSET_OFFSET;
+ x = text_.cursorX() + TEXT_TO_INSET_OFFSET;
+ y = text_.cursorY() - dim_.asc + TEXT_TO_INSET_OFFSET;
}
LyXCursor::LyXCursor()
- : par_(0), pos_(0), boundary_(false), x_(0), y_(0)
+ : par_(0), pos_(0), boundary_(false)
{}
}
-void LyXCursor::pos(lyx::pos_type p)
+void LyXCursor::pos(lyx::pos_type pos)
{
- pos_ = p;
+ pos_ = pos;
}
}
-void LyXCursor::boundary(bool b)
+void LyXCursor::boundary(bool boundary)
{
- boundary_ = b;
+ boundary_ = boundary;
}
}
-void LyXCursor::x(int n)
-{
- x_ = n;
-}
-
-
-int LyXCursor::x() const
-{
- return x_;
-}
-
-
-void LyXCursor::y(int i)
-{
- y_ = i;
-}
-
-
-int LyXCursor::y() const
-{
- return y_;
-}
-
-
bool operator==(LyXCursor const & a, LyXCursor const & b)
{
return a.par() == b.par()
void boundary(bool b);
/// FIXME
bool boundary() const;
- /// set the x position in pixels
- void x(int i);
- /// return the x position in pixels
- int x() const;
- /// set the y position in pixels
- void y(int i);
- /// return the y position in pixels
- int y() const;
private:
/// The paragraph the cursor is in.
* the user.
*/
bool boundary_;
- /// the pixel x position
- int x_;
- /// the pixel y position
- int y_;
};
///
int ascent() const;
///
int descent() const;
+ ///
+ int cursorX() const;
+ ///
+ int cursorY() const;
+ ///
+ int cursorX(LyXCursor const & cursor) const;
+ ///
+ int cursorY(LyXCursor const & cursor) const;
public:
///
private:
/// rebreaks the given par
void redoParagraphInternal(ParagraphList::iterator pit);
-
- ///
- float getCursorX(ParagraphList::iterator pit,
- Row const & row, lyx::pos_type pos, bool boundary) const;
/// used in setlayout
void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
+
+2003-12-15 André Pönitz <poenitz@gmx.net>
+
+ * math_pos.[Ch]: remove (it's now cursor_slice.[Ch])
+
+ * Makefile.am:
+ * math_cursor.[Ch]:
+ * math_iterator.[Ch]: adjust
+
2003-11-21 Michael Schmitt <michael.schmitt@teststep.org>
* formulabase.C (getCursorDim): squash unused variable
math_parinset.h \
math_parser.C \
math_parser.h \
- math_pos.C \
- math_pos.h \
math_replace.h \
math_rootinset.C \
math_rootinset.h \
void MathCursor::push(MathAtom & t)
{
- Cursor_.push_back(CursorPos(t.nucleus()));
+ Cursor_.push_back(CursorSlice(t.nucleus()));
}
bool MathCursor::isInside(MathInset const * p) const
{
for (unsigned i = 0; i < depth(); ++i)
- if (Cursor_[i].inset_ == p)
+ if (Cursor_[i].asMathInset() == p)
return true;
return false;
}
// we can't move into anything new during selection
if (depth() == Anchor_.size())
return false;
- if (t.operator->() != Anchor_[depth()].inset_)
+ if (t.operator->() != Anchor_[depth()].asMathInset())
return false;
}
return true;
// anchor might be deeper, should have same path then
for (MathIterator::size_type i = 0; i < cursor.size(); ++i)
- if (cursor[i].inset_ != anchor[i].inset_)
+ if (cursor[i].asMathInset() != anchor[i].asMathInset())
return false;
// position should be ok.
{
if (!selection_)
return;
- CursorPos i1;
- CursorPos i2;
+ CursorSlice i1;
+ CursorSlice i2;
getSelection(i1, i2);
- i1.inset_->drawSelection(pi, i1.idx_, i1.pos_, i2.idx_, i2.pos_);
+ i1.asMathInset()->drawSelection(pi, i1.idx_, i1.pos_, i2.idx_, i2.pos_);
}
MathInset * MathCursor::inset() const
{
- return cursor().inset_;
+ return cursor().asMathInset();
}
MathGridInset * MathCursor::enclosingGrid(MathCursor::idx_type & idx) const
{
for (MathInset::difference_type i = depth() - 1; i >= 0; --i) {
- MathGridInset * p = Cursor_[i].inset_->asGridInset();
+ MathGridInset * p = Cursor_[i].asMathInset()->asGridInset();
if (p) {
idx = Cursor_[i].idx_;
return p;
void MathCursor::popToHere(MathInset const * p)
{
- while (depth() && Cursor_.back().inset_ != p)
+ while (depth() && Cursor_.back().asMathInset() != p)
Cursor_.pop_back();
}
void MathCursor::popToEnclosingGrid()
{
- while (depth() && !Cursor_.back().inset_->asGridInset())
+ while (depth() && !Cursor_.back().asMathInset()->asGridInset())
Cursor_.pop_back();
}
void MathCursor::popToEnclosingHull()
{
- while (depth() && !Cursor_.back().inset_->asHullInset())
+ while (depth() && !Cursor_.back().asMathInset()->asHullInset())
Cursor_.pop_back();
}
}
-void MathCursor::getSelection(CursorPos & i1, CursorPos & i2) const
+void MathCursor::getSelection(CursorSlice & i1, CursorSlice & i2) const
{
- CursorPos anc = normalAnchor();
+ CursorSlice anc = normalAnchor();
if (anc < cursor()) {
i1 = anc;
i2 = cursor();
}
-CursorPos & MathCursor::cursor()
+CursorSlice & MathCursor::cursor()
{
BOOST_ASSERT(depth());
return Cursor_.back();
}
-CursorPos const & MathCursor::cursor() const
+CursorSlice const & MathCursor::cursor() const
{
BOOST_ASSERT(depth());
return Cursor_.back();
ostringstream os;
os << "Math editor mode. ";
for (int i = 0, n = depth(); i < n; ++i) {
- Cursor_[i].inset_->infoize(os);
+ Cursor_[i].asMathInset()->infoize(os);
os << " ";
}
if (hasPrevAtom())
namespace {
-void region(CursorPos const & i1, CursorPos const & i2,
+void region(CursorSlice const & i1, CursorSlice const & i2,
MathInset::row_type & r1, MathInset::row_type & r2,
MathInset::col_type & c1, MathInset::col_type & c2)
{
- MathInset * p = i1.inset_;
+ MathInset * p = i1.asMathInset();
c1 = p->col(i1.idx_);
c2 = p->col(i2.idx_);
if (c1 > c2)
if (!selection_)
return string();
- CursorPos i1;
- CursorPos i2;
+ CursorSlice i1;
+ CursorSlice i2;
getSelection(i1, i2);
if (i1.idx_ == i2.idx_) {
for (col_type col = c1; col <= c2; ++col) {
if (col > c1)
data += '&';
- data += asString(i1.inset_->cell(i1.inset_->index(row, col)));
+ data += asString(i1.asMathInset()->cell(i1.asMathInset()->index(row, col)));
}
}
return data;
void MathCursor::eraseSelection()
{
- CursorPos i1;
- CursorPos i2;
+ CursorSlice i1;
+ CursorSlice i2;
getSelection(i1, i2);
if (i1.idx_ == i2.idx_)
i1.cell().erase(i1.pos_, i2.pos_);
else {
- MathInset * p = i1.inset_;
+ MathInset * p = i1.asMathInset();
row_type r1, r2;
col_type c1, c2;
region(i1, i2, r1, r2, c1, c2);
}
-CursorPos MathCursor::normalAnchor() const
+CursorSlice MathCursor::normalAnchor() const
{
if (Anchor_.size() < depth()) {
Anchor_ = Cursor_;
}
//lyx::BOOST_ASSERT(Anchor_.size() >= cursor.depth());
// use Anchor on the same level as Cursor
- CursorPos normal = Anchor_[depth() - 1];
+ CursorSlice normal = Anchor_[depth() - 1];
if (depth() < Anchor_.size() && !(normal < cursor())) {
// anchor is behind cursor -> move anchor behind the inset
++normal.pos_;
case LFUN_MOUSE_MOTION:
case LFUN_MOUSE_RELEASE:
case LFUN_MOUSE_DOUBLE: {
- CursorPos & pos = Cursor_.back();
+ CursorSlice & pos = Cursor_.back();
int x = 0;
int y = 0;
getPos(x, y);
}
for (int i = Cursor_.size() - 1; i >= 0; --i) {
- CursorPos & pos = Cursor_[i];
+ CursorSlice & pos = Cursor_[i];
DispatchResult const res =
- pos.inset_->dispatch(cmd, pos.idx_, pos.pos_);
+ pos.asMathInset()->dispatch(cmd, pos.idx_, pos.pos_);
if (res.dispatched()) {
if (res.val() == FINISHED) {
Cursor_.shrink(i + 1);
MathInset::mode_type MathCursor::currentMode() const
{
for (int i = Cursor_.size() - 1; i >= 0; --i) {
- MathInset::mode_type res = Cursor_[i].inset_->currentMode();
+ MathInset::mode_type res = Cursor_[i].asMathInset()->currentMode();
if (res != MathInset::UNDECIDED_MODE)
return res;
}
#ifndef MATH_CURSOR
#define MATH_CURSOR
-
#include "math_inset.h"
+#include "math_data.h"
#include "math_iterator.h"
#include <string>
[Have a look at math_inset.h first]
The MathCursor is different from the kind of cursor used in the Outer
-World. It contains a stack of CursorPos, each of which is made
+World. It contains a stack of CursorSlice, each of which is made
up of a inset pointer, an index and a position offset, marking a path from
this formula's MathHullInset to the current position.
MathAtom & nextAtom();
/// returns the selection
- void getSelection(CursorPos &, CursorPos &) const;
+ void getSelection(CursorSlice &, CursorSlice &) const;
/// returns the normalized anchor of the selection
- CursorPos normalAnchor() const;
+ CursorSlice normalAnchor() const;
/// reference to the last item of the path, i.e. "The Cursor"
- CursorPos & cursor();
+ CursorSlice & cursor();
/// reference to the last item of the path, i.e. "The Cursor"
- CursorPos const & cursor() const;
+ CursorSlice const & cursor() const;
/// how deep are we nested?
unsigned depth() const;
/// describe the situation
#include "math_iterator.h"
#include "math_inset.h"
+#include "math_data.h"
#include <boost/assert.hpp>
MathInset const * MathIterator::inset() const
{
- return back().inset_;
+ return back().asMathInset();
}
MathInset * MathIterator::inset()
{
- return back().inset_;
+ return back().asMathInset();
}
MathArray const & MathIterator::cell() const
{
- CursorPos const & top = back();
- return top.inset_->cell(top.idx_);
+ CursorSlice const & top = back();
+ return top.asMathInset()->cell(top.idx_);
}
void MathIterator::push(MathInset * p)
{
//lyxerr << "push: " << p << endl;
- push_back(CursorPos(p));
+ push_back(CursorSlice(p));
}
}
-CursorPos const & MathIterator::operator*() const
+CursorSlice const & MathIterator::operator*() const
{
return back();
}
-CursorPos const & MathIterator::operator->() const
+CursorSlice const & MathIterator::operator->() const
{
return back();
}
void MathIterator::goEnd()
{
- CursorPos & top = back();
- top.idx_ = top.inset_->nargs() - 1;
+ CursorSlice & top = back();
+ top.idx_ = top.asMathInset()->nargs() - 1;
top.pos_ = cell().size();
}
void MathIterator::operator++()
{
- CursorPos & top = back();
- MathArray & ar = top.inset_->cell(top.idx_);
+ CursorSlice & top = back();
+ MathArray & ar = top.asMathInset()->cell(top.idx_);
// move into the current inset if possible
// it is impossible for pos() == size()!
}
// otherwise try to move on one cell if possible
- while (top.idx_ + 1 < top.inset_->nargs()) {
+ while (top.idx_ + 1 < top.asMathInset()->nargs()) {
// idx() == nargs() is _not_ valid!
++top.idx_;
- if (top.inset_->validCell(top.idx_)) {
+ if (top.asMathInset()->validCell(top.idx_)) {
top.pos_ = 0;
return;
}
#ifndef MATH_ITERATOR_H
#define MATH_ITERATOR_H
-#include "math_pos.h"
+#include "cursor_slice.h"
#include <vector>
// this is used for traversing math insets
-class MathIterator : private std::vector<CursorPos> {
+class MathIterator : private std::vector<CursorSlice> {
public:
// re-use inherited stuff
- typedef std::vector<CursorPos> base_type;
+ typedef std::vector<CursorSlice> base_type;
using base_type::clear;
using base_type::size;
using base_type::push_back;
/// start with given inset
explicit MathIterator(MathInset * p);
///
- CursorPos const & operator*() const;
+ CursorSlice const & operator*() const;
///
- CursorPos const & operator->() const;
+ CursorSlice const & operator->() const;
/// move on one step
void operator++();
/// move on several steps
+++ /dev/null
-/**
- * \file math_pos.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author André Pönitz
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "math_pos.h"
-#include "math_inset.h"
-#include "debug.h"
-
-#include <boost/assert.hpp>
-
-using std::endl;
-
-
-CursorPos::CursorPos()
- : inset_(0), idx_(0), pos_(0)
-{}
-
-
-CursorPos::CursorPos(MathInset * p)
- : inset_(p), idx_(0), pos_(0)
-{
- BOOST_ASSERT(inset_);
-}
-
-
-
-MathArray & CursorPos::cell(MathArray::idx_type idx) const
-{
- BOOST_ASSERT(inset_);
- return inset_->cell(idx);
-}
-
-
-MathArray & CursorPos::cell() const
-{
- BOOST_ASSERT(inset_);
- return inset_->cell(idx_);
-}
-
-
-void CursorPos::getPos(int & x, int & y) const
-{
- inset_->getPos(idx_, pos_, x, y);
-}
-
-
-void CursorPos::setPos(MathArray::pos_type pos)
-{
- pos_ = pos;
-}
-
-
-std::ostream & operator<<(std::ostream & os, CursorPos const & p)
-{
- os << "(par: " << p.inset_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ')';
- return os;
-}
-
-
-bool operator==(CursorPos const & p, CursorPos const & q)
-{
- return p.inset_ == q.inset_ && p.idx_ == q.idx_ && p.pos_ == q.pos_;
-}
-
-
-bool operator!=(CursorPos const & p, CursorPos const & q)
-{
- return p.inset_ != q.inset_ || p.idx_ != q.idx_ || p.pos_ != q.pos_;
-}
-
-
-bool operator<(CursorPos const & p, CursorPos const & q)
-{
- if (p.inset_ != q.inset_) {
- lyxerr << "can't compare cursor and anchor in different insets\n"
- << "p: " << p << '\n' << "q: " << q << endl;
- return true;
- }
- if (p.idx_ != q.idx_)
- return p.idx_ < q.idx_;
- return p.pos_ < q.pos_;
-}
+++ /dev/null
-// -*- C++ -*-
-/**
- * \file math_pos.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author André Pönitz
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#ifndef MATH_POS_H
-#define MATH_POS_H
-
-
-#include <iosfwd>
-#include "math_data.h"
-
-
-/// Description of a position
-class CursorPos {
-public:
- ///
- CursorPos();
- ///
- explicit CursorPos(MathInset *);
-
- /// returns cell corresponding to this position
- MathArray & cell() const;
- /// returns cell corresponding to this position
- MathArray & cell(MathArray::idx_type idx) const;
- /// gets screen position of the thing
- void getPos(int & x, int & y) const;
- /// set position
- void setPos(MathArray::pos_type pos);
-
-public:
- /// pointer to an inset
- MathInset * inset_;
- /// cell index of a position in this inset
- MathArray::idx_type idx_;
- /// position in this cell
- MathArray::pos_type pos_;
-};
-
-/// test for equality
-bool operator==(CursorPos const &, CursorPos const &);
-/// test for inequality
-bool operator!=(CursorPos const &, CursorPos const &);
-/// test for order
-bool operator<(CursorPos const &, CursorPos const &);
-/// output
-std::ostream & operator<<(std::ostream &, CursorPos const &);
-
-#endif
bool const is_rtl = pit_->isRightToLeftPar(bv_.buffer()->params());
// the current selection
- int const startx = text_.selStart().x();
- int const endx = text_.selEnd().x();
- int const starty = text_.selStart().y();
- int const endy = text_.selEnd().y();
+ int const startx = text_.cursorX(text_.selStart());
+ int const endx = text_.cursorX(text_.selEnd());
+ int const starty = text_.cursorY(text_.selStart());
+ int const endy = text_.cursorY(text_.selEnd());
ParagraphList::iterator startpit = text_.getPar(text_.selStart());
ParagraphList::iterator endpit = text_.getPar(text_.selEnd());
RowList::iterator startrow = startpit->getRow(text_.selStart().pos());
}
-void paintTextInset(BufferView const & bv, LyXText const & text, int xo, int yo)
+void paintTextInset(LyXText const & text, PainterInfo & pi, int xo, int yo)
{
- paintPars(bv, text, text.paragraphs().begin(), xo, yo, 0);
+ paintPars(*pi.base.bv, text, text.paragraphs().begin(), xo, yo, 0);
}
class LyXText;
class BufferView;
+class PainterInfo;
/// paint the rows of the main text, return last drawn y value
int paintText(BufferView const & bv);
/// paint the rows of a text inset
-void paintTextInset(BufferView const & bv, LyXText const & text, int x, int y);
+void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y);
#endif // ROWPAINTER_H
// only used for inset right now. should also be used for main text
-void LyXText::draw(PainterInfo &, int x, int y) const
+void LyXText::draw(PainterInfo & pi, int x, int y) const
{
xo_ = x;
yo_ = y;
- paintTextInset(*bv(), *this, x, y);
+ paintTextInset(*this, pi, x, y);
}
return height - firstRow()->ascent_of_text();
}
+
+int LyXText::cursorX() const
+{
+ return cursorX(cursor);
+}
+
+
+int LyXText::cursorY() const
+{
+ return cursorY(cursor);
+}
+
+
+int LyXText::cursorX(LyXCursor const & cur) const
+{
+ ParagraphList::iterator pit = getPar(cur);
+ Row const & row = *pit->getRow(cur.pos());
+ pos_type pos = cur.pos();
+ pos_type cursor_vpos = 0;
+ double x = row.x();
+ double fill_separator = row.fill_separator();
+ double fill_hfill = row.fill_hfill();
+ double fill_label_hfill = row.fill_label_hfill();
+ pos_type const row_pos = row.pos();
+ pos_type const end = row.endpos();
+
+ if (end <= row_pos)
+ cursor_vpos = row_pos;
+ else if (pos >= end)
+ cursor_vpos = (pit->isRightToLeftPar(bv()->buffer()->params()))
+ ? row_pos : end;
+ else if (pos > row_pos && pos >= end)
+ // Place cursor after char at (logical) position pos - 1
+ cursor_vpos = (bidi.level(pos - 1) % 2 == 0)
+ ? bidi.log2vis(pos - 1) + 1 : bidi.log2vis(pos - 1);
+ else
+ // Place cursor before char at (logical) position pos
+ cursor_vpos = (bidi.level(pos) % 2 == 0)
+ ? bidi.log2vis(pos) : bidi.log2vis(pos) + 1;
+
+ pos_type body_pos = pit->beginOfBody();
+ if (body_pos > 0 &&
+ (body_pos > end || !pit->isLineSeparator(body_pos - 1)))
+ body_pos = 0;
+
+ for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
+ pos_type pos = bidi.vis2log(vpos);
+ if (body_pos > 0 && pos == body_pos - 1) {
+ x += fill_label_hfill
+ + font_metrics::width(pit->layout()->labelsep,
+ getLabelFont(pit));
+ if (pit->isLineSeparator(body_pos - 1))
+ x -= singleWidth(pit, body_pos - 1);
+ }
+
+ if (hfillExpansion(*pit, row, pos)) {
+ x += singleWidth(pit, pos);
+ if (pos >= body_pos)
+ x += fill_hfill;
+ else
+ x += fill_label_hfill;
+ } else if (pit->isSeparator(pos)) {
+ x += singleWidth(pit, pos);
+ if (pos >= body_pos)
+ x += fill_separator;
+ } else
+ x += singleWidth(pit, pos);
+ }
+ return int(x);
+}
+
+
+int LyXText::cursorY(LyXCursor const & cur) const
+{
+ Paragraph & par = *getPar(cur);
+ Row & row = *par.getRow(cur.pos());
+ return par.y + row.y_offset() + row.baseline();
+}
+
ParagraphList::iterator pit = getPar(par);
Row const & row = *pit->getRow(pos);
-
- int y = pit->y + row.y_offset();
-
- // y is now the beginning of the cursor row
- y += row.baseline();
- // y is now the cursor baseline
- cur.y(y);
-
pos_type const end = row.endpos();
// None of these should happen, but we're scaredy-cats
cur.pos(pos);
BOOST_ASSERT(false);
}
- // now get the cursors x position
- cur.x(int(getCursorX(pit, row, pos, boundary)));
-}
-
-
-float LyXText::getCursorX(ParagraphList::iterator pit, Row const & row,
- pos_type pos, bool boundary) const
-{
- pos_type cursor_vpos = 0;
- double x = row.x();
- double fill_separator = row.fill_separator();
- double fill_hfill = row.fill_hfill();
- double fill_label_hfill = row.fill_label_hfill();
- pos_type const row_pos = row.pos();
- pos_type const end = row.endpos();
-
- if (end <= row_pos)
- cursor_vpos = row_pos;
- else if (pos >= end && !boundary)
- cursor_vpos = (pit->isRightToLeftPar(bv()->buffer()->params()))
- ? row_pos : end;
- else if (pos > row_pos && (pos >= end || boundary))
- // Place cursor after char at (logical) position pos - 1
- cursor_vpos = (bidi.level(pos - 1) % 2 == 0)
- ? bidi.log2vis(pos - 1) + 1 : bidi.log2vis(pos - 1);
- else
- // Place cursor before char at (logical) position pos
- cursor_vpos = (bidi.level(pos) % 2 == 0)
- ? bidi.log2vis(pos) : bidi.log2vis(pos) + 1;
-
- pos_type body_pos = pit->beginOfBody();
- if (body_pos > 0 &&
- (body_pos > end || !pit->isLineSeparator(body_pos - 1)))
- body_pos = 0;
-
- for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
- pos_type pos = bidi.vis2log(vpos);
- if (body_pos > 0 && pos == body_pos - 1) {
- x += fill_label_hfill
- + font_metrics::width(pit->layout()->labelsep,
- getLabelFont(pit));
- if (pit->isLineSeparator(body_pos - 1))
- x -= singleWidth(pit, body_pos - 1);
- }
-
- if (hfillExpansion(*pit, row, pos)) {
- x += singleWidth(pit, pos);
- if (pos >= body_pos)
- x += fill_hfill;
- else
- x += fill_label_hfill;
- } else if (pit->isSeparator(pos)) {
- x += singleWidth(pit, pos);
- if (pos >= body_pos)
- x += fill_separator;
- } else
- x += singleWidth(pit, pos);
- }
- return x;
}
pos_type pos, bool setfont, bool boundary)
{
setCursor(cursor, par, pos, boundary);
- bv()->x_target(cursor.x() + xo_);
+ bv()->x_target(cursorX() + xo_);
if (setfont)
setCurrentFont();
}
deleteEmptyParagraphMechanism(old_cursor);
}
+
// x,y are coordinates relative to this LyXText
void LyXText::setCursorFromCoordinates(LyXCursor & cur, int x, int y)
{
- // Get the row first.
ParagraphList::iterator pit;
Row const & row = *getRowNearY(y, pit);
- y = pit->y + row.y_offset();
-
bool bound = false;
pos_type const column = getColumnNearX(pit, row, x, bound);
cur.par(parOffset(pit));
cur.pos(row.pos() + column);
- cur.x(x);
- cur.y(y + row.baseline());
-
cur.boundary(bound);
}
{
Row const & row = *cursorRow();
int x = bv()->x_target() - xo_;
- int y = cursor.y() - row.baseline() - 1;
+ int y = cursorY() - row.baseline() - 1;
setCursorFromCoordinates(x, y);
if (!selecting) {
{
Row const & row = *cursorRow();
int x = bv()->x_target() - xo_;
- int y = cursor.y() - row.baseline() + row.height() + 1;
+ int y = cursorY() - row.baseline() + row.height() + 1;
setCursorFromCoordinates(x, y);
if (!selecting) {
break;
case LFUN_GETXY:
- cmd.message(tostr(cursor.x()) + ' ' + tostr(cursor.y()));
+ cmd.message(tostr(cursorX()) + ' ' + tostr(cursorY()));
break;
case LFUN_SETXY: {
setCursorFromCoordinates(cmd.x, cmd.y);
selection.cursor = cursor;
finishUndo();
- bv->x_target(cursor.x() + xo_);
+ bv->x_target(cursorX() + xo_);
if (bv->fitCursor())
selection_possible = false;