mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 05:25:26 +00:00
deep iterators for math insets;
use brute force for to determine "best" position when doing cursor up/down (will be sped up a bit again soonish...) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3153 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
6f5f012d3d
commit
ebe6d25126
@ -68,6 +68,8 @@ libmathed_la_SOURCES = \
|
||||
math_hullinset.h \
|
||||
math_inset.C \
|
||||
math_inset.h \
|
||||
math_iterator.C \
|
||||
math_iterator.h \
|
||||
math_kerninset.C \
|
||||
math_kerninset.h \
|
||||
math_lefteqninset.C \
|
||||
|
@ -26,12 +26,12 @@ Inset hierarchy:
|
||||
|
||||
/ \
|
||||
|
||||
Array "Matrix"
|
||||
Array Hull
|
||||
(base for eqnarray/align/...)
|
||||
|
||||
|
||||
|
||||
There are only two "real LyXInsets" in here:
|
||||
|
||||
Formula - containing a pointer to a MathMatrixInset (a misnomer...)
|
||||
Formula - containing a pointer to a MathHullInset
|
||||
FormulaMacro - containing a pointer to a MathMacroTemplate
|
||||
|
@ -28,22 +28,23 @@
|
||||
#include "debug.h"
|
||||
#include "LColor.h"
|
||||
#include "Painter.h"
|
||||
#include "math_support.h"
|
||||
#include "formulabase.h"
|
||||
#include "math_cursor.h"
|
||||
#include "math_casesinset.h"
|
||||
#include "math_factory.h"
|
||||
#include "math_arrayinset.h"
|
||||
#include "math_braceinset.h"
|
||||
#include "math_casesinset.h"
|
||||
#include "math_charinset.h"
|
||||
#include "math_cursor.h"
|
||||
#include "math_deliminset.h"
|
||||
#include "math_factory.h"
|
||||
#include "math_hullinset.h"
|
||||
#include "math_iterator.h"
|
||||
#include "math_mathmlstream.h"
|
||||
#include "math_parser.h"
|
||||
#include "math_replace.h"
|
||||
#include "math_scriptinset.h"
|
||||
#include "math_spaceinset.h"
|
||||
#include "math_specialcharinset.h"
|
||||
#include "math_mathmlstream.h"
|
||||
#include "math_replace.h"
|
||||
#include "math_parser.h"
|
||||
#include "math_support.h"
|
||||
|
||||
#define FILEDEBUG 0
|
||||
|
||||
@ -67,7 +68,7 @@ struct Selection
|
||||
data_.push_back(MathArray(i1.cell(), i1.pos_, i2.pos_));
|
||||
else {
|
||||
std::vector<MathInset::idx_type> indices =
|
||||
(*i1.par_)->idxBetween(i1.idx_, i2.idx_);
|
||||
i1.par_->idxBetween(i1.idx_, i2.idx_);
|
||||
for (MathInset::idx_type i = 0; i < indices.size(); ++i)
|
||||
data_.push_back(i1.cell(indices[i]));
|
||||
}
|
||||
@ -82,7 +83,7 @@ struct Selection
|
||||
i1.cell().erase(i1.pos_, i2.pos_);
|
||||
else {
|
||||
std::vector<MathInset::idx_type> indices =
|
||||
(*i1.par_)->idxBetween(i1.idx_, i2.idx_);
|
||||
i1.par_->idxBetween(i1.idx_, i2.idx_);
|
||||
for (unsigned i = 0; i < indices.size(); ++i)
|
||||
i1.cell(indices[i]).erase();
|
||||
}
|
||||
@ -116,13 +117,6 @@ struct Selection
|
||||
Selection theSelection;
|
||||
|
||||
|
||||
#if FILEDEBUG
|
||||
std::ostream & operator<<(std::ostream & os, MathCursorPos const & p)
|
||||
{
|
||||
os << "(par: " << p.par_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ")";
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -136,11 +130,7 @@ MathCursor::MathCursor(InsetFormulaBase * formula, bool left)
|
||||
|
||||
void MathCursor::push(MathAtom & t)
|
||||
{
|
||||
MathCursorPos p;
|
||||
p.par_ = &t;
|
||||
p.idx_ = 0;
|
||||
p.pos_ = 0;
|
||||
Cursor_.push_back(p);
|
||||
Cursor_.push_back(MathCursorPos(t.nucleus()));
|
||||
}
|
||||
|
||||
|
||||
@ -192,48 +182,19 @@ bool MathCursor::popRight()
|
||||
|
||||
|
||||
#if FILEDEBUG
|
||||
void MathCursor::dump(char const * what) const
|
||||
{
|
||||
lyxerr << "MC: " << what << "\n";
|
||||
for (unsigned i = 0; i < Cursor_.size(); ++i)
|
||||
lyxerr << " i: " << i
|
||||
<< " Cursor: pos: " << Cursor_[i].pos_
|
||||
<< " idx: " << Cursor_[i].idx_
|
||||
<< " par: " << Cursor_[i].par_ << "\n";
|
||||
|
||||
for (unsigned i = 0; i < Anchor_.size(); ++i)
|
||||
lyxerr << " i: " << i
|
||||
<< " Anchor: pos: " << Anchor_[i].pos_
|
||||
<< " idx: " << Anchor_[i].idx_
|
||||
<< " par: " << Anchor_[i].par_ << "\n";
|
||||
|
||||
lyxerr << " sel: " << selection_ << "\n";
|
||||
}
|
||||
|
||||
|
||||
void MathCursor::seldump(char const * str) const
|
||||
{
|
||||
//lyxerr << "SEL: " << str << ": '" << theSelection << "'\n";
|
||||
//dump(" Pos");
|
||||
|
||||
lyxerr << "\n\n\n=================vvvvvvvvvvvvv======================= "
|
||||
<< str << "\ntheSelection: " << selection_
|
||||
<< " '" /*<< theSelection.glue()*/ << "'\nCursor:";
|
||||
for (unsigned int i = 0; i < Cursor_.size(); ++i)
|
||||
lyxerr << Cursor_[i].par_ << "\n'" /*<< Cursor_[i].cell()*/ << "'\n";
|
||||
lyxerr << "\nAnchor: ";
|
||||
for (unsigned int i = 0; i < Anchor_.size(); ++i)
|
||||
lyxerr << Anchor_[i].par_ << "\n'" /*<< Anchor_[i].cell()*/ << "'\n";
|
||||
//lyxerr << "\ncursor.pos_: " << pos();
|
||||
//lyxerr << "\nanchor.pos_: " << anchor().pos_;
|
||||
lyxerr << "\n===================^^^^^^^^^^^^=====================\n\n\n";
|
||||
}
|
||||
|
||||
void MathCursor::dump(char const * what) const
|
||||
{
|
||||
lyxerr << "MC: " << what << "\n";
|
||||
lyxerr << " Cursor: " << Cursor_.size() << "\n";
|
||||
for (unsigned i = 0; i < Cursor_.size(); ++i)
|
||||
lyxerr << " i: " << i << " " << Cursor_[i] << "\n";
|
||||
lyxerr << " Anchor: " << Anchor_.size() << "\n";
|
||||
for (unsigned i = 0; i < Anchor_.size(); ++i)
|
||||
lyxerr << " i: " << i << " " << Anchor_[i] << "\n";
|
||||
lyxerr << " sel: " << selection_ << "\n";
|
||||
}
|
||||
#else
|
||||
|
||||
void MathCursor::seldump(char const *) const {}
|
||||
void MathCursor::dump(char const *) const {}
|
||||
|
||||
void MathCursor::dump(char const *) const {}
|
||||
#endif
|
||||
|
||||
|
||||
@ -246,7 +207,7 @@ UpdatableInset * MathCursor::asHyperActiveInset() const
|
||||
bool MathCursor::isInside(MathInset const * p) const
|
||||
{
|
||||
for (unsigned i = 0; i < Cursor_.size(); ++i)
|
||||
if (Cursor_[i].par_->nucleus() == p)
|
||||
if (Cursor_[i].par_ == p)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -267,7 +228,7 @@ bool MathCursor::openable(MathAtom const & t, bool sel) const
|
||||
// we can't move into anything new during selection
|
||||
if (Cursor_.size() == Anchor_.size())
|
||||
return false;
|
||||
if (&t != Anchor_[Cursor_.size()].par_)
|
||||
if (t.nucleus() != Anchor_[Cursor_.size()].par_)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -280,7 +241,7 @@ bool MathCursor::positionable(MathAtom const & t, int x, int y) const
|
||||
// we can't move into anything new during selection
|
||||
if (Cursor_.size() >= Anchor_.size())
|
||||
return false;
|
||||
if (&t != Anchor_[Cursor_.size()].par_)
|
||||
if (t.nucleus() != Anchor_[Cursor_.size()].par_)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -371,6 +332,7 @@ void MathCursor::last()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void MathCursor::setPos(int x, int y)
|
||||
{
|
||||
//dump("setPos 1");
|
||||
@ -407,6 +369,47 @@ void MathCursor::setPos(int x, int y)
|
||||
//dump("setPos 2");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void MathCursor::setPos(int x, int y)
|
||||
{
|
||||
dump("setPos 1");
|
||||
cursor_type best_cursor;
|
||||
double best_dist = 1e10;
|
||||
|
||||
MathIterator it(formula()->par().nucleus());
|
||||
MathIterator et;
|
||||
for ( ; it != et; ++it) {
|
||||
if (selection_) {
|
||||
// avoid deeper nested insets when selecting
|
||||
if (it.cursor().size() > Anchor_.size())
|
||||
continue;
|
||||
// anchor might be deeper!
|
||||
if (it.cursor().size() == Anchor_.size())
|
||||
if (it.par() != Anchor_.back().par_)
|
||||
continue;
|
||||
//if (it.par() != Anchor_[it.cursor().size()].par_)
|
||||
// continue;
|
||||
}
|
||||
//lyxerr << it.position() << endl;
|
||||
int xo = it.position().xpos();
|
||||
int yo = it.position().ypos();
|
||||
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
|
||||
if (d < best_dist) {
|
||||
best_dist = d;
|
||||
best_cursor = it.cursor();
|
||||
}
|
||||
}
|
||||
if (best_dist < 1e10)
|
||||
Cursor_ = best_cursor;
|
||||
//lyxerr << "x: " << x << " y: " << y << " dist: " << best_dist << "\n";
|
||||
dump("setPos 2");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void MathCursor::home(bool sel)
|
||||
{
|
||||
@ -687,7 +690,7 @@ string MathCursor::macroName() const
|
||||
|
||||
void MathCursor::selCopy()
|
||||
{
|
||||
seldump("selCopy");
|
||||
dump("selCopy");
|
||||
if (selection_) {
|
||||
theSelection.grab(*this);
|
||||
selClear();
|
||||
@ -697,7 +700,7 @@ void MathCursor::selCopy()
|
||||
|
||||
void MathCursor::selCut()
|
||||
{
|
||||
seldump("selCut");
|
||||
dump("selCut");
|
||||
if (selection_) {
|
||||
theSelection.grab(*this);
|
||||
theSelection.erase(*this);
|
||||
@ -710,7 +713,7 @@ void MathCursor::selCut()
|
||||
|
||||
void MathCursor::selDel()
|
||||
{
|
||||
seldump("selDel");
|
||||
dump("selDel");
|
||||
if (selection_) {
|
||||
theSelection.erase(*this);
|
||||
if (pos() > size())
|
||||
@ -722,7 +725,7 @@ void MathCursor::selDel()
|
||||
|
||||
void MathCursor::selPaste()
|
||||
{
|
||||
seldump("selPaste");
|
||||
dump("selPaste");
|
||||
theSelection.paste(*this);
|
||||
//theSelection.grab(*this);
|
||||
//selClear();
|
||||
@ -741,23 +744,25 @@ void MathCursor::selHandle(bool sel)
|
||||
|
||||
void MathCursor::selStart()
|
||||
{
|
||||
seldump("selStart");
|
||||
dump("selStart 1");
|
||||
//theSelection.clear();
|
||||
Anchor_ = Cursor_;
|
||||
selection_ = true;
|
||||
dump("selStart 2");
|
||||
}
|
||||
|
||||
|
||||
void MathCursor::selClear()
|
||||
{
|
||||
seldump("selClear");
|
||||
dump("selClear 1");
|
||||
selection_ = false;
|
||||
dump("selClear 2");
|
||||
}
|
||||
|
||||
|
||||
void MathCursor::selGet(MathArray & ar)
|
||||
{
|
||||
seldump("selGet");
|
||||
dump("selGet");
|
||||
if (!selection_)
|
||||
return;
|
||||
|
||||
@ -786,7 +791,7 @@ void MathCursor::drawSelection(Painter & pain) const
|
||||
pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
|
||||
} else {
|
||||
std::vector<MathInset::idx_type> indices
|
||||
= (*i1.par_)->idxBetween(i1.idx_, i2.idx_);
|
||||
= i1.par_->idxBetween(i1.idx_, i2.idx_);
|
||||
for (unsigned i = 0; i < indices.size(); ++i) {
|
||||
MathXArray & c = i1.xcell(indices[i]);
|
||||
int x1 = c.xo();
|
||||
@ -850,14 +855,16 @@ void MathCursor::getPos(int & x, int & y)
|
||||
#ifdef WITH_WARNINGS
|
||||
#warning This should probably take cellXOffset and cellYOffset into account
|
||||
#endif
|
||||
dump("getPos 1");
|
||||
x = xarray().xo() + xarray().pos2x(pos());
|
||||
y = xarray().yo();
|
||||
dump("getPos 2");
|
||||
}
|
||||
|
||||
|
||||
MathAtom & MathCursor::par() const
|
||||
MathInset * MathCursor::par() const
|
||||
{
|
||||
return *cursor().par_;
|
||||
return cursor().par_;
|
||||
}
|
||||
|
||||
|
||||
@ -906,7 +913,7 @@ bool MathCursor::selection() const
|
||||
MathGridInset * MathCursor::enclosingGrid(MathCursor::idx_type & idx) const
|
||||
{
|
||||
for (int i = Cursor_.size() - 1; i >= 0; --i) {
|
||||
MathGridInset * p = (*Cursor_[i].par_)->asGridInset();
|
||||
MathGridInset * p = Cursor_[i].par_->asGridInset();
|
||||
if (p) {
|
||||
idx = Cursor_[i].idx_;
|
||||
return p;
|
||||
@ -1153,8 +1160,12 @@ MathCursorPos const & MathCursor::cursor() const
|
||||
bool MathCursor::goUp()
|
||||
{
|
||||
// first ask the inset if it knows better then we
|
||||
if (par()->idxUp(idx(), pos()))
|
||||
if (par()->idxUp(idx(), pos())) {
|
||||
int xlow, xhigh, ylow, yhigh;
|
||||
xarray().boundingBox(xlow, xhigh, ylow, yhigh);
|
||||
bruteFind(xlow, xhigh, ylow, yhigh);
|
||||
return true;
|
||||
}
|
||||
|
||||
// leave subscript to the nearest side
|
||||
MathScriptInset * p = par()->asScriptInset();
|
||||
@ -1175,8 +1186,12 @@ bool MathCursor::goUp()
|
||||
bool MathCursor::goDown()
|
||||
{
|
||||
// first ask the inset if it knows better then we
|
||||
if (par()->idxDown(idx(), pos()))
|
||||
if (par()->idxDown(idx(), pos())) {
|
||||
int xlow, xhigh, ylow, yhigh;
|
||||
xarray().boundingBox(xlow, xhigh, ylow, yhigh);
|
||||
bruteFind(xlow, xhigh, ylow, yhigh);
|
||||
return true;
|
||||
}
|
||||
|
||||
// leave superscript to the nearest side
|
||||
MathScriptInset * p = par()->asScriptInset();
|
||||
@ -1200,8 +1215,8 @@ bool MathCursor::bruteUpDown(int ylow, int yhigh)
|
||||
int x0;
|
||||
int y0;
|
||||
getPos(x0, y0);
|
||||
std::vector<MathCursorPos> save = Cursor_;
|
||||
std::vector<MathCursorPos> best;
|
||||
cursor_type save = Cursor_;
|
||||
cursor_type best;
|
||||
double best_dist = 1e10; // large enough
|
||||
bool found = false;
|
||||
for (int y = ylow; y < yhigh; y += 4) {
|
||||
@ -1229,6 +1244,35 @@ bool MathCursor::bruteUpDown(int ylow, int yhigh)
|
||||
}
|
||||
|
||||
|
||||
bool MathCursor::bruteFind(int xlow, int xhigh, int ylow, int yhigh)
|
||||
{
|
||||
//lyxerr << "looking at range: " << ylow << " " << yhigh << "\n";
|
||||
int x;
|
||||
int y;
|
||||
getPos(x, y);
|
||||
|
||||
cursor_type best_cursor;
|
||||
double best_dist = 1e10;
|
||||
|
||||
MathIterator it(formula()->par().nucleus());
|
||||
MathIterator et;
|
||||
for ( ; it != et; ++it) {
|
||||
int xo = it.position().xpos();
|
||||
int yo = it.position().ypos();
|
||||
if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
|
||||
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
|
||||
if (d < best_dist) {
|
||||
best_dist = d;
|
||||
best_cursor = it.cursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best_dist < 1e10)
|
||||
Cursor_ = best_cursor;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MathCursor::idxLeft()
|
||||
{
|
||||
return par()->idxLeft(idx(), pos());
|
||||
@ -1443,51 +1487,6 @@ bool MathCursor::interpret(char c)
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
bool operator==(MathCursorPos const & ti, MathCursorPos const & it)
|
||||
{
|
||||
return ti.par_ == it.par_ && ti.idx_ == it.idx_ && ti.pos_ == it.pos_;
|
||||
}
|
||||
|
||||
|
||||
bool operator<(MathCursorPos const & ti, MathCursorPos const & it)
|
||||
{
|
||||
if (ti.par_ != it.par_) {
|
||||
lyxerr << "can't compare cursor and anchor in different insets\n";
|
||||
return true;
|
||||
}
|
||||
if (ti.idx_ != it.idx_)
|
||||
return ti.idx_ < it.idx_;
|
||||
return ti.pos_ < it.pos_;
|
||||
}
|
||||
|
||||
|
||||
MathArray & MathCursorPos::cell(MathCursor::idx_type idx) const
|
||||
{
|
||||
return (*par_)->cell(idx);
|
||||
}
|
||||
|
||||
|
||||
MathArray & MathCursorPos::cell() const
|
||||
{
|
||||
return (*par_)->cell(idx_);
|
||||
}
|
||||
|
||||
|
||||
MathXArray & MathCursorPos::xcell(MathCursor::idx_type idx) const
|
||||
{
|
||||
return (*par_)->xcell(idx);
|
||||
}
|
||||
|
||||
|
||||
MathXArray & MathCursorPos::xcell() const
|
||||
{
|
||||
return (*par_)->xcell(idx_);
|
||||
}
|
||||
|
||||
|
||||
MathCursorPos MathCursor::normalAnchor() const
|
||||
{
|
||||
// use Anchor on the same level as Cursor
|
||||
@ -1515,3 +1514,82 @@ void MathCursor::stripFromLastEqualSign()
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
MathCursorPos::MathCursorPos()
|
||||
: par_(0), idx_(0), pos_(0)
|
||||
{}
|
||||
|
||||
|
||||
MathCursorPos::MathCursorPos(MathInset * p)
|
||||
: par_(p), idx_(0), pos_(0)
|
||||
{}
|
||||
|
||||
|
||||
MathArray & MathCursorPos::cell(MathCursor::idx_type idx) const
|
||||
{
|
||||
return par_->cell(idx);
|
||||
}
|
||||
|
||||
|
||||
MathArray & MathCursorPos::cell() const
|
||||
{
|
||||
return par_->cell(idx_);
|
||||
}
|
||||
|
||||
|
||||
MathXArray & MathCursorPos::xcell(MathCursor::idx_type idx) const
|
||||
{
|
||||
return par_->xcell(idx);
|
||||
}
|
||||
|
||||
|
||||
MathXArray & MathCursorPos::xcell() const
|
||||
{
|
||||
return par_->xcell(idx_);
|
||||
}
|
||||
|
||||
|
||||
int MathCursorPos::xpos() const
|
||||
{
|
||||
return xcell().xo() + xcell().pos2x(pos_);
|
||||
}
|
||||
|
||||
|
||||
int MathCursorPos::ypos() const
|
||||
{
|
||||
return xcell().yo();
|
||||
}
|
||||
|
||||
std::ostream & operator<<(std::ostream & os, MathCursorPos const & p)
|
||||
{
|
||||
os << "(par: " << p.par_ << " idx: " << p.idx_ << " pos: " << p.pos_ << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
bool operator==(MathCursorPos const & ti, MathCursorPos const & it)
|
||||
{
|
||||
return ti.par_ == it.par_ && ti.idx_ == it.idx_ && ti.pos_ == it.pos_;
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(MathCursorPos const & ti, MathCursorPos const & it)
|
||||
{
|
||||
return ti.par_ != it.par_ || ti.idx_ != it.idx_ || ti.pos_ != it.pos_;
|
||||
}
|
||||
|
||||
|
||||
bool operator<(MathCursorPos const & ti, MathCursorPos const & it)
|
||||
{
|
||||
if (ti.par_ != it.par_) {
|
||||
lyxerr << "can't compare cursor and anchor in different insets\n";
|
||||
return true;
|
||||
}
|
||||
if (ti.idx_ != it.idx_)
|
||||
return ti.idx_ < it.idx_;
|
||||
return ti.pos_ < it.pos_;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,13 +42,12 @@ this formula's mathHullInset to the current position.
|
||||
|
||||
|
||||
/// Description of a position
|
||||
struct MathCursorPos {
|
||||
/// pointer to an inset
|
||||
MathAtom * par_;
|
||||
/// cell index of a position in this inset
|
||||
MathInset::idx_type idx_;
|
||||
/// position in this cell
|
||||
MathInset::pos_type pos_;
|
||||
class MathCursorPos {
|
||||
public:
|
||||
///
|
||||
MathCursorPos();
|
||||
///
|
||||
explicit MathCursorPos(MathInset * p);
|
||||
|
||||
/// returns cell corresponding to this position
|
||||
MathArray & cell() const;
|
||||
@ -58,12 +57,28 @@ struct MathCursorPos {
|
||||
MathXArray & xcell() const;
|
||||
/// returns xcell corresponding to this position
|
||||
MathXArray & xcell(MathInset::idx_type idx) const;
|
||||
///
|
||||
int xpos() const;
|
||||
///
|
||||
int ypos() const;
|
||||
|
||||
public:
|
||||
/// pointer to an inset
|
||||
MathInset * par_;
|
||||
/// cell index of a position in this inset
|
||||
MathInset::idx_type idx_;
|
||||
/// position in this cell
|
||||
MathInset::pos_type pos_;
|
||||
};
|
||||
|
||||
/// test for equality
|
||||
bool operator==(MathCursorPos const &, MathCursorPos const &);
|
||||
/// test for unequality
|
||||
/// test for inequality
|
||||
bool operator!=(MathCursorPos const &, MathCursorPos const &);
|
||||
/// test for order
|
||||
bool operator<(MathCursorPos const &, MathCursorPos const &);
|
||||
/// output
|
||||
std::ostream & operator<<(std::ostream &, MathCursorPos const &);
|
||||
|
||||
|
||||
/// see above
|
||||
@ -128,7 +143,7 @@ public:
|
||||
/// in pixels from top of screen
|
||||
void getPos(int & x, int & y);
|
||||
///
|
||||
MathAtom & par() const;
|
||||
MathInset * par() const;
|
||||
/// return the next enclosing grid inset and the cursor's index in it
|
||||
MathGridInset * enclosingGrid(idx_type &) const;
|
||||
///
|
||||
@ -275,6 +290,8 @@ private:
|
||||
bool goDown();
|
||||
/// moves position somehow down
|
||||
bool bruteUpDown(int ylow, int yhigh);
|
||||
/// moves position into box
|
||||
bool bruteFind(int xlow, int xhigh, int ylow, int yhigh);
|
||||
|
||||
///
|
||||
string macroName() const;
|
||||
|
@ -487,31 +487,27 @@ int MathGridInset::cellYOffset(idx_type idx) const
|
||||
}
|
||||
|
||||
|
||||
bool MathGridInset::idxUp(idx_type & /*idx*/, pos_type & /*pos*/) const
|
||||
bool MathGridInset::idxUp(idx_type & idx, pos_type & pos) const
|
||||
{
|
||||
return false;
|
||||
/*
|
||||
//return false;
|
||||
if (idx < ncols())
|
||||
return false;
|
||||
int x = cellXOffset(idx) + xcell(idx).pos2x(pos);
|
||||
idx -= ncols();
|
||||
pos = xcell(idx).x2pos(x - cellXOffset(idx));
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
bool MathGridInset::idxDown(idx_type & /*idx*/, pos_type & /*pos*/) const
|
||||
bool MathGridInset::idxDown(idx_type & idx, pos_type & pos) const
|
||||
{
|
||||
return false;
|
||||
/*
|
||||
//return false;
|
||||
if (idx >= ncols() * (nrows() - 1))
|
||||
return false;
|
||||
int x = cellXOffset(idx) + xcell(idx).pos2x(pos);
|
||||
idx += ncols();
|
||||
pos = xcell(idx).x2pos(x - cellXOffset(idx));
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,6 +72,7 @@ class LaTeXFeatures;
|
||||
class BufferView;
|
||||
class UpdatableInset;
|
||||
class MathMacroTemplate;
|
||||
class MathPosFinder;
|
||||
|
||||
|
||||
class MathInset {
|
||||
|
137
src/mathed/math_iterator.C
Normal file
137
src/mathed/math_iterator.C
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "math_iterator.h"
|
||||
|
||||
|
||||
MathIterator::MathIterator()
|
||||
{}
|
||||
|
||||
|
||||
MathIterator::MathIterator(MathInset * p)
|
||||
{
|
||||
push(p);
|
||||
}
|
||||
|
||||
|
||||
MathIterator::MathIterator(MathCursor::cursor_type const & c)
|
||||
: cursor_(c)
|
||||
{}
|
||||
|
||||
|
||||
MathCursorPos const & MathIterator::position() const
|
||||
{
|
||||
return cursor_.back();
|
||||
}
|
||||
|
||||
|
||||
MathCursorPos & MathIterator::position()
|
||||
{
|
||||
return cursor_.back();
|
||||
}
|
||||
|
||||
|
||||
MathCursor::cursor_type const & MathIterator::cursor() const
|
||||
{
|
||||
return cursor_;
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathIterator::par() const
|
||||
{
|
||||
return cursor_.size() ? cursor_.back().par_ : 0;
|
||||
}
|
||||
|
||||
|
||||
MathXArray const & MathIterator::xcell() const
|
||||
{
|
||||
if (!par())
|
||||
lyxerr << "MathIterator::xcell: no cell\n";
|
||||
return par()->xcell(position().idx_);
|
||||
}
|
||||
|
||||
|
||||
MathInset * MathIterator::nextInset() const
|
||||
{
|
||||
if (position().pos_ == xcell().data_.size())
|
||||
return 0;
|
||||
return (xcell().begin() + position().pos_)->nucleus();
|
||||
}
|
||||
|
||||
|
||||
void MathIterator::push(MathInset * p)
|
||||
{
|
||||
//lyxerr << "push: " << p << endl;
|
||||
cursor_.push_back(MathCursorPos(p));
|
||||
}
|
||||
|
||||
|
||||
void MathIterator::pop()
|
||||
{
|
||||
//lyxerr << "pop: " << endl;
|
||||
cursor_.pop_back();
|
||||
}
|
||||
|
||||
|
||||
MathCursorPos const & MathIterator::operator*() const
|
||||
{
|
||||
return position();
|
||||
}
|
||||
|
||||
|
||||
MathCursorPos const & MathIterator::operator->() const
|
||||
{
|
||||
return position();
|
||||
}
|
||||
|
||||
|
||||
void MathIterator::operator++()
|
||||
{
|
||||
// move into the current inset if possible
|
||||
// it is impossible for pos() == size()!
|
||||
if (nextInset() && nextInset()->isActive()) {
|
||||
push(nextInset());
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise move on one cell position if possible
|
||||
if (position().pos_ < xcell().data_.size()) {
|
||||
// pos() == size() is valid!
|
||||
++position().pos_;
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise move on one cell if possible
|
||||
if (position().idx_ + 1 < par()->nargs()) {
|
||||
// idx() == nargs() is _not_ valid!
|
||||
++position().idx_;
|
||||
position().pos_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise leave array, move on one cell
|
||||
// this might yield pos() == size(), but that's a ok.
|
||||
pop();
|
||||
++position().pos_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool operator==(MathIterator const & it, MathIterator const & jt)
|
||||
{
|
||||
//lyxerr << "==: " << it.cursor().size() << " " << jt.cursor().size() << endl;
|
||||
if (it.cursor().size() != jt.cursor().size())
|
||||
return false;
|
||||
return it.cursor() == jt.cursor();
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(MathIterator const & it, MathIterator const & jt)
|
||||
{
|
||||
//lyxerr << "!=: " << it.cursor().size() << " " << jt.cursor().size() << endl;
|
||||
if (it.cursor().size() != jt.cursor().size())
|
||||
return true;
|
||||
return it.cursor() != jt.cursor();
|
||||
}
|
||||
|
51
src/mathed/math_iterator.h
Normal file
51
src/mathed/math_iterator.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef MATH_ITERATOR_H
|
||||
#define MATH_ITERATOR_H
|
||||
|
||||
#include "math_cursor.h"
|
||||
|
||||
// this helper struct is used for traversing math insets
|
||||
|
||||
class MathIterator {
|
||||
public:
|
||||
/// default constructor, used for end of range
|
||||
MathIterator();
|
||||
/// start with given formula
|
||||
explicit MathIterator(MathInset * p);
|
||||
/// start with given position
|
||||
explicit MathIterator(MathCursor::cursor_type const & cursor);
|
||||
///
|
||||
MathCursorPos const & operator*() const;
|
||||
///
|
||||
MathCursorPos const & operator->() const;
|
||||
///
|
||||
void operator++();
|
||||
/// read access to top most item
|
||||
MathCursorPos const & position() const;
|
||||
/// write access to top most item
|
||||
MathCursorPos & position();
|
||||
/// read access to full path
|
||||
MathCursor::cursor_type const & cursor() const;
|
||||
/// read access to top most inset
|
||||
MathInset * par() const;
|
||||
|
||||
private:
|
||||
/// write access to top most item
|
||||
MathXArray const & xcell() const;
|
||||
/// write access to top most item
|
||||
MathInset * nextInset() const;
|
||||
/// own level down
|
||||
void push(MathInset *);
|
||||
/// own level up
|
||||
void pop();
|
||||
|
||||
/// current position
|
||||
MathCursor::cursor_type cursor_;
|
||||
};
|
||||
|
||||
///
|
||||
bool operator==(MathIterator const &, MathIterator const &);
|
||||
///
|
||||
bool operator!=(MathIterator const &, MathIterator const &);
|
||||
|
||||
|
||||
#endif
|
@ -151,3 +151,39 @@ bool MathXArray::covers(int x, int y) const
|
||||
int const y1 = yo_ + descent_;
|
||||
return x >= x0 && x <= x1 && y >= y0 && y <= y1;
|
||||
}
|
||||
|
||||
|
||||
void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2)
|
||||
{
|
||||
x1 = xo_;
|
||||
x2 = xo_ + width_;
|
||||
y1 = yo_ - ascent_;
|
||||
y2 = yo_ + descent_;
|
||||
}
|
||||
|
||||
/*
|
||||
void MathXArray::findPos(MathPosFinder & f) const
|
||||
{
|
||||
double x = xo_;
|
||||
double y = yo_;
|
||||
for (const_iterator it = begin(); it < end(); ++it) {
|
||||
// check this position in the cell first
|
||||
f.visit(x, y);
|
||||
f.nextPos();
|
||||
|
||||
// check inset
|
||||
MathInset const * p = it->nucleus();
|
||||
p->findPos(f);
|
||||
|
||||
// move on
|
||||
MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
|
||||
if (q) {
|
||||
x += q->width(p);
|
||||
f.nextPos();
|
||||
++it;
|
||||
} else {
|
||||
x += p->width();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -14,66 +14,75 @@
|
||||
|
||||
class Painter;
|
||||
|
||||
|
||||
/** This class extends a MathArray by drawing routines and caches for
|
||||
* metric information.
|
||||
*/
|
||||
class MathXArray
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// type for positions and sizes
|
||||
typedef MathArray::size_type size_type;
|
||||
///
|
||||
/// const iterator into the underlying MathArray
|
||||
typedef MathArray::const_iterator const_iterator;
|
||||
|
||||
///
|
||||
/// constructor
|
||||
MathXArray();
|
||||
///
|
||||
/// rebuild cached metrics information
|
||||
void metrics(MathMetricsInfo const & st) const;
|
||||
///
|
||||
/// redraw cell using cache metrics information
|
||||
void draw(Painter & pain, int x, int y) const;
|
||||
|
||||
///
|
||||
/// access to cached x coordinate of last drawing
|
||||
int xo() const { return xo_; }
|
||||
///
|
||||
/// access to cached y coordinate of last drawing
|
||||
int yo() const { return yo_; }
|
||||
///
|
||||
/// returns x coordinate of given position in the array
|
||||
int pos2x(size_type pos) const;
|
||||
///
|
||||
/// returns position of given x coordinate
|
||||
size_type x2pos(int pos) const;
|
||||
/// returns distance of this cell to the point given by x and y
|
||||
// assumes valid position and size cache
|
||||
int dist(int x, int y) const;
|
||||
|
||||
///
|
||||
/// ascent of this cell above the baseline
|
||||
int ascent() const { return ascent_; }
|
||||
///
|
||||
/// descent of this cell below the baseline
|
||||
int descent() const { return descent_; }
|
||||
///
|
||||
/// height of the cell
|
||||
int height() const { return ascent_ + descent_; }
|
||||
///
|
||||
/// width of this cell
|
||||
int width() const { return width_; }
|
||||
/// do we cover point(x, y)?
|
||||
bool covers(int x, int y) const;
|
||||
/// bounding box of this cell
|
||||
void boundingBox(int & xlow, int & xhigh, int & ylow, int & yhigh);
|
||||
/// find best position to do things
|
||||
//void findPos(PosFinder &) const;
|
||||
|
||||
///
|
||||
/// begin iterator of the underlying MathArray
|
||||
const_iterator begin() const { return data_.begin(); }
|
||||
///
|
||||
/// end iterator of the underlying MathArray
|
||||
const_iterator end() const { return data_.end(); }
|
||||
|
||||
public:
|
||||
///
|
||||
/// the underlying MathArray
|
||||
MathArray data_;
|
||||
///
|
||||
/// cached width of cell
|
||||
mutable int width_;
|
||||
///
|
||||
/// cached ascent of cell
|
||||
mutable int ascent_;
|
||||
///
|
||||
/// cached descent of cell
|
||||
mutable int descent_;
|
||||
///
|
||||
/// cached x coordinate of last drawing
|
||||
mutable int xo_;
|
||||
///
|
||||
/// cached y coordinate of last drawing
|
||||
mutable int yo_;
|
||||
///
|
||||
/// cache size information of last drawing
|
||||
mutable MathMetricsInfo size_;
|
||||
};
|
||||
|
||||
/// output cell on a stream
|
||||
std::ostream & operator<<(std::ostream & os, MathXArray const & ar);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user