mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
CoordBranch merge
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9325 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
e171a6a69f
commit
a2cd656e25
@ -21,6 +21,7 @@
|
||||
#include "bufferparams.h"
|
||||
#include "BufferView_pimpl.h"
|
||||
#include "CutAndPaste.h"
|
||||
#include "coordcache.h"
|
||||
#include "debug.h"
|
||||
#include "funcrequest.h"
|
||||
#include "FuncStatus.h"
|
||||
@ -141,9 +142,9 @@ bool BufferView::fitCursor()
|
||||
}
|
||||
|
||||
|
||||
void BufferView::update()
|
||||
void BufferView::update(bool fitcursor, bool forceupdate)
|
||||
{
|
||||
pimpl_->update();
|
||||
pimpl_->update(fitcursor, forceupdate);
|
||||
}
|
||||
|
||||
|
||||
@ -159,12 +160,6 @@ void BufferView::scrollDocView(int value)
|
||||
}
|
||||
|
||||
|
||||
void BufferView::redoCurrentBuffer()
|
||||
{
|
||||
pimpl_->redoCurrentBuffer();
|
||||
}
|
||||
|
||||
|
||||
bool BufferView::available() const
|
||||
{
|
||||
return pimpl_->available();
|
||||
@ -213,18 +208,6 @@ void BufferView::center()
|
||||
}
|
||||
|
||||
|
||||
int BufferView::top_y() const
|
||||
{
|
||||
return pimpl_->top_y();
|
||||
}
|
||||
|
||||
|
||||
void BufferView::top_y(int y)
|
||||
{
|
||||
pimpl_->top_y(y);
|
||||
}
|
||||
|
||||
|
||||
string const BufferView::getClipboard() const
|
||||
{
|
||||
return pimpl_->workarea().getClipboard();
|
||||
@ -336,13 +319,11 @@ LyXText * BufferView::text() const
|
||||
|
||||
void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos)
|
||||
{
|
||||
int const last = par.size();
|
||||
for (int i = 0; i < last; ++i)
|
||||
for (int i = 0, n = par.size(); i < n; ++i)
|
||||
par[i].inset().edit(cursor(), true);
|
||||
|
||||
cursor().setCursor(makeDocIterator(par, pos));
|
||||
cursor().selection() = false;
|
||||
par.bottom().text()->redoParagraph(par.bottom().pit());
|
||||
}
|
||||
|
||||
|
||||
@ -375,3 +356,15 @@ LCursor const & BufferView::cursor() const
|
||||
{
|
||||
return pimpl_->cursor_;
|
||||
}
|
||||
|
||||
|
||||
lyx::pit_type BufferView::anchor_ref() const
|
||||
{
|
||||
return pimpl_->anchor_ref_;
|
||||
}
|
||||
|
||||
|
||||
int BufferView::offset_ref() const
|
||||
{
|
||||
return pimpl_->offset_ref_;
|
||||
}
|
||||
|
@ -65,12 +65,6 @@ public:
|
||||
/// return the owning main view
|
||||
LyXView * owner() const;
|
||||
|
||||
/// return the visible top y
|
||||
int top_y() const;
|
||||
|
||||
/// set the visible top y
|
||||
void top_y(int);
|
||||
|
||||
/// resize event has happened
|
||||
void resize();
|
||||
|
||||
@ -82,14 +76,17 @@ public:
|
||||
/// load a buffer into the view
|
||||
bool loadLyXFile(std::string const & name, bool tolastfiles = true);
|
||||
|
||||
/// fit the user cursor within the visible view
|
||||
/** perform pending painting updates. \c fitcursor means first
|
||||
* to do a fitcursor, and to force an update if screen
|
||||
* position changes. \c forceupdate means to force an update
|
||||
* in any case.
|
||||
*/
|
||||
void update(bool fitcursor = true, bool forceupdate = true);
|
||||
/// move the screen to fit the cursor. Only to be called with
|
||||
/// good y coordinates (after a bv::metrics)
|
||||
bool fitCursor();
|
||||
/// perform pending painting updates
|
||||
void update();
|
||||
/// reset the scrollbar to reflect current view position
|
||||
void updateScrollbar();
|
||||
/// FIXME
|
||||
void redoCurrentBuffer();
|
||||
|
||||
/// FIXME
|
||||
bool available() const;
|
||||
@ -153,6 +150,11 @@ public:
|
||||
/// clear the X selection
|
||||
void unsetXSel();
|
||||
|
||||
/// access to offset
|
||||
int offset_ref() const;
|
||||
/// access to anchor
|
||||
lyx::pit_type anchor_ref() const;
|
||||
|
||||
/// access to full cursor
|
||||
LCursor & cursor();
|
||||
/// access to full cursor
|
||||
@ -169,6 +171,7 @@ public:
|
||||
void putSelectionAt(DocIterator const & cur,
|
||||
int length, bool backwards);
|
||||
|
||||
|
||||
private:
|
||||
///
|
||||
struct Pimpl;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "lyxtext.h"
|
||||
#include "lyxrc.h"
|
||||
#include "lastfiles.h"
|
||||
#include "metricsinfo.h"
|
||||
#include "paragraph.h"
|
||||
#include "paragraph_funcs.h"
|
||||
#include "ParagraphParameters.h"
|
||||
@ -91,6 +92,7 @@ using std::endl;
|
||||
using std::istringstream;
|
||||
using std::make_pair;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::string;
|
||||
using std::mem_fun_ref;
|
||||
|
||||
@ -136,7 +138,8 @@ T * getInsetByCode(LCursor & cur, InsetBase::Code code)
|
||||
BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner,
|
||||
int width, int height)
|
||||
: bv_(&bv), owner_(owner), buffer_(0), cursor_timeout(400),
|
||||
using_xterm_cursor(false), cursor_(bv)
|
||||
using_xterm_cursor(false), cursor_(bv) ,
|
||||
anchor_ref_(0), offset_ref_(0)
|
||||
{
|
||||
xsel_cache_.set = false;
|
||||
|
||||
@ -311,18 +314,6 @@ Painter & BufferView::Pimpl::painter() const
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::top_y(int y)
|
||||
{
|
||||
top_y_ = y;
|
||||
}
|
||||
|
||||
|
||||
int BufferView::Pimpl::top_y() const
|
||||
{
|
||||
return top_y_;
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::setBuffer(Buffer * b)
|
||||
{
|
||||
lyxerr[Debug::INFO] << "Setting buffer in BufferView ("
|
||||
@ -343,8 +334,10 @@ void BufferView::Pimpl::setBuffer(Buffer * b)
|
||||
}
|
||||
|
||||
// reset old cursor
|
||||
top_y_ = 0;
|
||||
cursor_ = LCursor(*bv_);
|
||||
anchor_ref_ = 0;
|
||||
offset_ref_ = 0;
|
||||
|
||||
|
||||
// if we're quitting lyx, don't bother updating stuff
|
||||
if (quitting)
|
||||
@ -359,10 +352,6 @@ void BufferView::Pimpl::setBuffer(Buffer * b)
|
||||
buffer_->text().init(bv_);
|
||||
buffer_->text().setCurrentFont(cursor_);
|
||||
|
||||
// If we don't have a text object for this, we make one
|
||||
//if (bv_->text() == 0)
|
||||
// resizeCurrentBuffer();
|
||||
|
||||
// Buffer-dependent dialogs should be updated or
|
||||
// hidden. This should go here because some dialogs (eg ToC)
|
||||
// require bv_->text.
|
||||
@ -385,32 +374,6 @@ void BufferView::Pimpl::setBuffer(Buffer * b)
|
||||
}
|
||||
|
||||
|
||||
bool BufferView::Pimpl::fitCursor()
|
||||
{
|
||||
// to get the correct y cursor info
|
||||
lyxerr[Debug::DEBUG] << "BufferView::fitCursor" << std::endl;
|
||||
lyx::pit_type const pit = bv_->cursor().bottom().pit();
|
||||
bv_->text()->redoParagraph(pit);
|
||||
refreshPar(*bv_, *bv_->text(), pit);
|
||||
|
||||
if (!screen().fitCursor(bv_))
|
||||
return false;
|
||||
updateScrollbar();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::redoCurrentBuffer()
|
||||
{
|
||||
lyxerr[Debug::DEBUG] << "BufferView::redoCurrentBuffer" << endl;
|
||||
if (buffer_ && bv_->text()) {
|
||||
resizeCurrentBuffer();
|
||||
updateScrollbar();
|
||||
owner_->updateLayoutChoice();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::resizeCurrentBuffer()
|
||||
{
|
||||
lyxerr[Debug::DEBUG] << "resizeCurrentBuffer" << endl;
|
||||
@ -423,7 +386,6 @@ void BufferView::Pimpl::resizeCurrentBuffer()
|
||||
|
||||
text->init(bv_);
|
||||
update();
|
||||
fitCursor();
|
||||
|
||||
switchKeyMap();
|
||||
owner_->busy(false);
|
||||
@ -443,14 +405,23 @@ void BufferView::Pimpl::updateScrollbar()
|
||||
return;
|
||||
}
|
||||
|
||||
LyXText const & t = *bv_->text();
|
||||
|
||||
LyXText & t = *bv_->text();
|
||||
if (anchor_ref_ > int(t.paragraphs().size()) - 1) {
|
||||
anchor_ref_ = int(t.paragraphs().size()) - 1;
|
||||
offset_ref_ = 0;
|
||||
}
|
||||
|
||||
lyxerr[Debug::GUI]
|
||||
<< "Updating scrollbar: height: " << t.height()
|
||||
<< " top_y: " << top_y()
|
||||
<< "Updating scrollbar: height: " << t.paragraphs().size()
|
||||
<< " curr par: " << bv_->cursor().bottom().pit()
|
||||
<< " default height " << defaultRowHeight() << endl;
|
||||
|
||||
workarea().setScrollbarParams(t.height(), top_y(), defaultRowHeight());
|
||||
//it would be better to fix the scrollbar to understand
|
||||
//values in [0..1] and divide everything by wh
|
||||
int const wh = workarea().workHeight() / 4;
|
||||
int const h = t.getPar(anchor_ref_).height();
|
||||
workarea().setScrollbarParams(t.paragraphs().size() * wh, anchor_ref_ * wh + int(offset_ref_ * wh / float(h)), int (wh * defaultRowHeight() / float(h)));
|
||||
// workarea().setScrollbarParams(t.paragraphs().size(), anchor_ref_, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -463,48 +434,69 @@ void BufferView::Pimpl::scrollDocView(int value)
|
||||
|
||||
screen().hideCursor();
|
||||
|
||||
top_y(value);
|
||||
screen().redraw(*bv_);
|
||||
int const wh = workarea().workHeight() / 4;
|
||||
|
||||
LyXText & t = *bv_->text();
|
||||
|
||||
float const bar = value / float(wh * t.paragraphs().size());
|
||||
|
||||
anchor_ref_ = int(bar * t.paragraphs().size());
|
||||
t.redoParagraph(anchor_ref_);
|
||||
int const h = t.getPar(anchor_ref_).height();
|
||||
offset_ref_ = int((bar * t.paragraphs().size() - anchor_ref_) * h);
|
||||
lyxerr << "scrolling: " << value << std::endl;
|
||||
update();
|
||||
|
||||
if (!lyxrc.cursor_follows_scrollbar)
|
||||
return;
|
||||
|
||||
int const height = defaultRowHeight();
|
||||
int const first = top_y() + height;
|
||||
int const last = top_y() + workarea().workHeight() - height;
|
||||
|
||||
bv_->cursor().reset(bv_->buffer()->inset());
|
||||
LyXText * text = bv_->text();
|
||||
int y = text->cursorY(bv_->cursor().front());
|
||||
if (y < first)
|
||||
y = first;
|
||||
if (y > last)
|
||||
y = last;
|
||||
text->setCursorFromCoordinates(bv_->cursor(), 0, y);
|
||||
int const height = 2 * defaultRowHeight();
|
||||
int const first = height;
|
||||
int const last = workarea().workHeight() - height;
|
||||
LCursor & cur = bv_->cursor();
|
||||
|
||||
bv_funcs::CurStatus st = bv_funcs::status(bv_, cur);
|
||||
|
||||
switch (st) {
|
||||
case bv_funcs::CUR_ABOVE:
|
||||
t.setCursorFromCoordinates(cur, 0, first);
|
||||
cur.clearSelection();
|
||||
break;
|
||||
case bv_funcs::CUR_BELOW:
|
||||
t.setCursorFromCoordinates(cur, 0, last);
|
||||
cur.clearSelection();
|
||||
break;
|
||||
case bv_funcs::CUR_INSIDE:
|
||||
int const y = bv_funcs::getPos(cur).y_;
|
||||
int const newy = min(last, max(y, first));
|
||||
if (y != newy) {
|
||||
cur.reset(bv_->buffer()->inset());
|
||||
t.setCursorFromCoordinates(cur, 0, newy);
|
||||
}
|
||||
}
|
||||
owner_->updateLayoutChoice();
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::scroll(int lines)
|
||||
{
|
||||
if (!buffer_)
|
||||
return;
|
||||
|
||||
LyXText const * t = bv_->text();
|
||||
int const line_height = defaultRowHeight();
|
||||
|
||||
// The new absolute coordinate
|
||||
int new_top_y = top_y() + lines * line_height;
|
||||
|
||||
// Restrict to a valid value
|
||||
new_top_y = std::min(t->height() - 4 * line_height, new_top_y);
|
||||
new_top_y = std::max(0, new_top_y);
|
||||
|
||||
scrollDocView(new_top_y);
|
||||
|
||||
// Update the scrollbar.
|
||||
workarea().setScrollbarParams(t->height(), top_y(), defaultRowHeight());
|
||||
// if (!buffer_)
|
||||
// return;
|
||||
//
|
||||
// LyXText const * t = bv_->text();
|
||||
// int const line_height = defaultRowHeight();
|
||||
//
|
||||
// // The new absolute coordinate
|
||||
// int new_top_y = top_y() + lines * line_height;
|
||||
//
|
||||
// // Restrict to a valid value
|
||||
// new_top_y = std::min(t->height() - 4 * line_height, new_top_y);
|
||||
// new_top_y = std::max(0, new_top_y);
|
||||
//
|
||||
// scrollDocView(new_top_y);
|
||||
//
|
||||
// // Update the scrollbar.
|
||||
// workarea().setScrollbarParams(t->height(), top_y(), defaultRowHeight());
|
||||
}
|
||||
|
||||
|
||||
@ -591,33 +583,50 @@ void BufferView::Pimpl::workAreaResize()
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::update()
|
||||
bool BufferView::Pimpl::fitCursor()
|
||||
{
|
||||
//lyxerr << "BufferView::Pimpl::update(), buffer: " << buffer_ << endl;
|
||||
// fix cursor coordinate cache in case something went wrong
|
||||
if (bv_funcs::status(bv_, bv_->cursor()) == bv_funcs::CUR_INSIDE) {
|
||||
int asc, des;
|
||||
bv_->cursor().getDim(asc, des);
|
||||
Point p = bv_funcs::getPos(bv_->cursor());
|
||||
if (p.y_ - asc >= 0 && p.y_ + des < bv_->workHeight())
|
||||
return false;
|
||||
}
|
||||
bv_->center();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::update(bool fitcursor, bool forceupdate)
|
||||
{
|
||||
lyxerr << "BufferView::Pimpl::update(fc=" << fitcursor << ", fu="
|
||||
<< forceupdate << ") buffer: " << buffer_ << endl;
|
||||
|
||||
// check needed to survive LyX startup
|
||||
if (buffer_) {
|
||||
// update macro store
|
||||
buffer_->buildMacros();
|
||||
// first drawing step
|
||||
|
||||
// update all 'visible' paragraphs
|
||||
lyx::pit_type beg, end;
|
||||
getParsInRange(buffer_->paragraphs(),
|
||||
top_y(), top_y() + workarea().workHeight(),
|
||||
beg, end);
|
||||
bv_->text()->redoParagraphs(beg, end);
|
||||
CoordCache backup;
|
||||
std::swap(theCoords, backup);
|
||||
//
|
||||
ViewMetricsInfo vi = metrics();
|
||||
|
||||
// and the scrollbar
|
||||
updateScrollbar();
|
||||
}
|
||||
|
||||
// remove old position cache
|
||||
theCoords.clear();
|
||||
|
||||
// The real, big redraw.
|
||||
screen().redraw(*bv_);
|
||||
if (fitcursor && fitCursor()) {
|
||||
forceupdate = true;
|
||||
vi = metrics();
|
||||
}
|
||||
if (forceupdate) {
|
||||
// second drawing step
|
||||
screen().redraw(*bv_, vi);
|
||||
} else
|
||||
std::swap(theCoords, backup);
|
||||
} else
|
||||
screen().greyOut();
|
||||
|
||||
// and the scrollbar
|
||||
updateScrollbar();
|
||||
bv_->owner()->view_state_changed();
|
||||
}
|
||||
|
||||
@ -732,30 +741,19 @@ void BufferView::Pimpl::switchKeyMap()
|
||||
|
||||
void BufferView::Pimpl::center()
|
||||
{
|
||||
LyXText * text = bv_->text();
|
||||
|
||||
bv_->cursor().clearSelection();
|
||||
int const half_height = workarea().workHeight() / 2;
|
||||
int new_y = text->cursorY(bv_->cursor().front()) - half_height;
|
||||
if (new_y < 0)
|
||||
new_y = 0;
|
||||
|
||||
// FIXME: look at this comment again ...
|
||||
// This updates top_y() but means the fitCursor() call
|
||||
// from the update(FITCUR) doesn't realise that we might
|
||||
// have moved (e.g. from GOTOPARAGRAPH), so doesn't cause
|
||||
// the scrollbar to be updated as it should, so we have
|
||||
// to do it manually. Any operation that does a center()
|
||||
// and also might have moved top_y() must make sure to call
|
||||
// updateScrollbar() currently. Never mind that this is a
|
||||
// pretty obfuscated way of updating text->top_y()
|
||||
top_y(new_y);
|
||||
CursorSlice const & bot = bv_->cursor().bottom();
|
||||
lyx::pit_type const pit = bot.pit();
|
||||
bot.text()->redoParagraph(pit);
|
||||
Paragraph const & par = bot.text()->paragraphs()[pit];
|
||||
anchor_ref_ = pit;
|
||||
offset_ref_ = bv_funcs::coordOffset(bv_->cursor()).y_ + par.ascent()
|
||||
- workarea().workHeight() / 2;
|
||||
}
|
||||
|
||||
|
||||
void BufferView::Pimpl::stuffClipboard(string const & stuff) const
|
||||
void BufferView::Pimpl::stuffClipboard(string const & content) const
|
||||
{
|
||||
workarea().putClipboard(stuff);
|
||||
workarea().putClipboard(content);
|
||||
}
|
||||
|
||||
|
||||
@ -870,7 +868,6 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
|
||||
return true;
|
||||
}
|
||||
|
||||
cmd.y += bv_->top_y();
|
||||
if (!bv_->buffer())
|
||||
return false;
|
||||
|
||||
@ -891,8 +888,8 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
|
||||
// surrounding LyXText will handle this event.
|
||||
|
||||
// Build temporary cursor.
|
||||
cmd.y = min(max(cmd.y,-1), bv_->workHeight());
|
||||
InsetBase * inset = bv_->text()->editXY(cur, cmd.x, cmd.y);
|
||||
lyxerr << " * created temp cursor: " << inset << endl;
|
||||
lyxerr << " * hit inset at tip: " << inset << endl;
|
||||
lyxerr << " * created temp cursor:" << cur << endl;
|
||||
|
||||
@ -913,8 +910,7 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
|
||||
|
||||
if (cur.result().dispatched()) {
|
||||
// Redraw if requested or necessary.
|
||||
if (fitCursor() || cur.result().update())
|
||||
update();
|
||||
update(cur.result().update(), cur.result().update());
|
||||
}
|
||||
|
||||
// see workAreaKeyPress
|
||||
@ -962,12 +958,9 @@ FuncStatus BufferView::Pimpl::getStatus(FuncRequest const & cmd)
|
||||
case LFUN_MARK_ON:
|
||||
case LFUN_SETMARK:
|
||||
case LFUN_CENTER:
|
||||
case LFUN_BEGINNINGBUF:
|
||||
case LFUN_ENDBUF:
|
||||
case LFUN_BEGINNINGBUFSEL:
|
||||
case LFUN_ENDBUFSEL:
|
||||
flag.enabled(true);
|
||||
break;
|
||||
|
||||
case LFUN_BOOKMARK_GOTO:
|
||||
flag.enabled(bv_->isSavedPosition(strToUnsignedInt(cmd.argument)));
|
||||
break;
|
||||
@ -1137,25 +1130,80 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
|
||||
bv_->center();
|
||||
break;
|
||||
|
||||
case LFUN_BEGINNINGBUFSEL:
|
||||
bv_->cursor().reset(bv_->buffer()->inset());
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
bv_->text()->cursorTop(cur);
|
||||
finishUndo();
|
||||
break;
|
||||
|
||||
case LFUN_ENDBUFSEL:
|
||||
bv_->cursor().reset(bv_->buffer()->inset());
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
bv_->text()->cursorBottom(cur);
|
||||
finishUndo();
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ViewMetricsInfo BufferView::Pimpl::metrics()
|
||||
{
|
||||
// remove old position cache
|
||||
theCoords.clear();
|
||||
BufferView & bv = *bv_;
|
||||
LyXText * const text = bv.text();
|
||||
if (anchor_ref_ > int(text->paragraphs().size() - 1)) {
|
||||
anchor_ref_ = int(text->paragraphs().size() - 1);
|
||||
offset_ref_ = 0;
|
||||
}
|
||||
|
||||
lyx::pit_type const pit = anchor_ref_;
|
||||
int pit1 = pit;
|
||||
int pit2 = pit;
|
||||
size_t npit = text->paragraphs().size();
|
||||
lyxerr << "npit: " << npit << " pit1: " << pit1
|
||||
<< " pit2: " << pit2 << endl;
|
||||
|
||||
// rebreak anchor par
|
||||
text->redoParagraph(pit);
|
||||
int y0 = text->getPar(pit1).ascent() - offset_ref_;
|
||||
|
||||
// redo paragraphs above cursor if necessary
|
||||
int y1 = y0;
|
||||
while (y1 > 0 && pit1 > 0) {
|
||||
y1 -= text->getPar(pit1).ascent();
|
||||
--pit1;
|
||||
text->redoParagraph(pit1);
|
||||
y1 -= text->getPar(pit1).descent();
|
||||
}
|
||||
|
||||
|
||||
// take care of ascent of first line
|
||||
y1 -= text->getPar(pit1).ascent();
|
||||
|
||||
//normalize anchor for next time
|
||||
anchor_ref_ = pit1;
|
||||
offset_ref_ = -y1;
|
||||
|
||||
// grey at the beginning is ugly
|
||||
if (pit1 == 0 && y1 > 0) {
|
||||
y0 -= y1;
|
||||
y1 = 0;
|
||||
anchor_ref_ = 0;
|
||||
}
|
||||
|
||||
// redo paragraphs below cursor if necessary
|
||||
int y2 = y0;
|
||||
while (y2 < bv.workHeight() && pit2 < int(npit) - 1) {
|
||||
y2 += text->getPar(pit2).descent();
|
||||
++pit2;
|
||||
text->redoParagraph(pit2);
|
||||
y2 += text->getPar(pit2).ascent();
|
||||
}
|
||||
|
||||
// take care of descent of last line
|
||||
y2 += text->getPar(pit2).descent();
|
||||
|
||||
// the coordinates of all these paragraphs are correct, cache them
|
||||
int y = y1;
|
||||
for (lyx::pit_type pit = pit1; pit <= pit2; ++pit) {
|
||||
y += text->getPar(pit).ascent();
|
||||
theCoords.pars_[text][pit] = Point(0, y);
|
||||
y += text->getPar(pit).descent();
|
||||
}
|
||||
|
||||
lyxerr << "bv:metrics: y1: " << y1 << " y2: " << y2 << endl;
|
||||
return ViewMetricsInfo(pit1, pit2, y1, y2);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ class WorkArea;
|
||||
class LyXScreen;
|
||||
class FuncRequest;
|
||||
class FuncStatus;
|
||||
class ViewMetricsInfo;
|
||||
|
||||
|
||||
///
|
||||
@ -53,14 +54,12 @@ struct BufferView::Pimpl : public boost::signals::trackable {
|
||||
LyXScreen & screen() const;
|
||||
///
|
||||
void setBuffer(Buffer * buf);
|
||||
/// Return true if the cursor was fitted.
|
||||
bool fitCursor();
|
||||
///
|
||||
void redoCurrentBuffer();
|
||||
///
|
||||
void resizeCurrentBuffer();
|
||||
//
|
||||
bool fitCursor();
|
||||
///
|
||||
void update();
|
||||
void update(bool fitcursor = false, bool forceupdate = true);
|
||||
///
|
||||
void newFile(std::string const &, std::string const &, bool);
|
||||
///
|
||||
@ -103,13 +102,7 @@ struct BufferView::Pimpl : public boost::signals::trackable {
|
||||
FuncStatus getStatus(FuncRequest const & cmd);
|
||||
/// a function should be executed
|
||||
bool dispatch(FuncRequest const & ev);
|
||||
///
|
||||
int top_y() const;
|
||||
///
|
||||
void top_y(int y);
|
||||
private:
|
||||
/// the y coordinate of the top of the screen
|
||||
int top_y_;
|
||||
/// An error list (replaces the error insets)
|
||||
ErrorList errorlist_;
|
||||
/// add an error to the list
|
||||
@ -185,5 +178,14 @@ private:
|
||||
} xsel_cache_;
|
||||
///
|
||||
LCursor cursor_;
|
||||
///
|
||||
///
|
||||
lyx::pit_type anchor_ref_;
|
||||
///
|
||||
int offset_ref_;
|
||||
///
|
||||
ViewMetricsInfo metrics();
|
||||
|
||||
|
||||
};
|
||||
#endif // BUFFERVIEW_PIMPL_H
|
||||
|
@ -1,3 +1,58 @@
|
||||
|
||||
2004-11-24 Alfredo Braunstein <abraunst@lyx.org>
|
||||
|
||||
* BufferView.[Ch]: remove top_y, introduce anchor_ref,
|
||||
offset_ref accessors
|
||||
|
||||
* BufferView_Pimpl.[Ch]: introduce anchor_ref_, offser_ref_, remove
|
||||
top_y_, merge fitcursor with update
|
||||
(updateScrollbar, scrollDocView, fitCursor, center, update): new
|
||||
coord scheme
|
||||
(metrics): introduce
|
||||
(workAreaDispatch): adapt to new coord scheme
|
||||
(redoCurrentBuffer): remove
|
||||
|
||||
* FontIterator.[Ch]: Use Paragraph & instead of pit_type
|
||||
|
||||
* bufferview_funcs.[Ch]: introduce coordOffset, getPos, status,
|
||||
CurStatus enum.
|
||||
|
||||
* coordcache.[Ch]: add paragraph cache and helpers
|
||||
|
||||
* CursorSlice.[Ch]: rename CursorSlice::par to CursorSlice::pit,
|
||||
adjust everywhere
|
||||
|
||||
* cursor.[Ch] (getDim): fix, (getPos) use coordOffset
|
||||
(targetX, setTargetX): introduce
|
||||
|
||||
* lyxrow.[Ch]: simplify, remove ascent_of_text, y_offset, rename
|
||||
baseline -> ascent, as the rest of lyx
|
||||
|
||||
* lyxtext.h: remove redoParagraphs, updateParPositions,
|
||||
fullRebreak, redoParagraphInternal. move dist to anon namespace in
|
||||
tabular.C (doesn't belong here), remove xo_, yo_ cache, makes it
|
||||
have ascent/descent (ascent is ascent of first par)
|
||||
|
||||
* metricsinfo.h: add ViewMetricsInfo struct to use in the metrics
|
||||
step of BufferView
|
||||
|
||||
* paragraph.[Ch]: unify dimension handling with the rest of lyx
|
||||
|
||||
* paragraph_funcs.[Ch] (getParsInRange, outerPar): remove.
|
||||
|
||||
* pariterator.C: fix infinite loop introduced in par->pit renaming
|
||||
|
||||
* rowPainter.[Ch]: big rewrite: separate drawSelection from draw
|
||||
in insets and LyXText, draw two off-screen paragraphs using
|
||||
NullPainter, and adapt to new coord scheme
|
||||
|
||||
* text.C:
|
||||
* text2.C:
|
||||
* text3.C: adapt lfun handlers to the new coord scheme, which
|
||||
means: there's only guaranteed coord information for onscreen pars
|
||||
plus one above and one below. This implies that one can do search
|
||||
from y coordinates in the range [-1,workHeight]
|
||||
|
||||
2004-11-25 Lars Gullik Bjonnes <larsbj@gullik.net>
|
||||
|
||||
* rename a lot of InsetOld to InsetBase
|
||||
@ -41,7 +96,6 @@
|
||||
* text3.C:
|
||||
* undo.C: par->pit renaming
|
||||
|
||||
|
||||
2004-11-23 Lars Gullik Bjonnes <larsbj@gullik.net>
|
||||
|
||||
* tabular.C (cellstruct): use initialization, store a shared_ptr
|
||||
|
@ -466,7 +466,6 @@ void cutSelection(LCursor & cur, bool doclear, bool realcut)
|
||||
if (doclear)
|
||||
text->paragraphs()[begpit].stripLeadingSpaces();
|
||||
|
||||
text->redoParagraphs(begpit, begpit + 1);
|
||||
// cutSelection can invalidate the cursor so we need to set
|
||||
// it anew. (Lgb)
|
||||
// we prefer the end for when tracking changes
|
||||
@ -564,8 +563,6 @@ void pasteSelection(LCursor & cur, size_t sel_index)
|
||||
bufferErrors(cur.buffer(), el);
|
||||
cur.bv().showErrorList(_("Paste"));
|
||||
|
||||
text->redoParagraphs(cur.pit(), endpit);
|
||||
|
||||
cur.clearSelection();
|
||||
cur.resetAnchor();
|
||||
text->setCursor(cur, ppp.first, ppp.second);
|
||||
|
@ -18,12 +18,12 @@
|
||||
#include "paragraph.h"
|
||||
|
||||
|
||||
FontIterator::FontIterator(LyXText const & text, lyx::pit_type pit,
|
||||
FontIterator::FontIterator(LyXText const & text, Paragraph const & par,
|
||||
lyx::pos_type pos)
|
||||
: text_(text), pit_(pit), pos_(pos),
|
||||
font_(text.getFont(text.getPar(pit), pos)),
|
||||
endspan_(text.getPar(pit).getEndPosOfFontSpan(pos)),
|
||||
bodypos_(text.getPar(pit).beginOfBody())
|
||||
: text_(text), par_(par), pos_(pos),
|
||||
font_(text.getFont(par, pos)),
|
||||
endspan_(par.getEndPosOfFontSpan(pos)),
|
||||
bodypos_(par.beginOfBody())
|
||||
{}
|
||||
|
||||
|
||||
@ -43,8 +43,8 @@ FontIterator & FontIterator::operator++()
|
||||
{
|
||||
++pos_;
|
||||
if (pos_ > endspan_ || pos_ == bodypos_) {
|
||||
font_ = text_.getFont(text_.getPar(pit_), pos_);
|
||||
endspan_ = text_.getPar(pit_).getEndPosOfFontSpan(pos_);
|
||||
font_ = text_.getFont(par_, pos_);
|
||||
endspan_ = par_.getEndPosOfFontSpan(pos_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -25,13 +25,14 @@
|
||||
#include "support/types.h"
|
||||
|
||||
class LyXText;
|
||||
class Paragraph;
|
||||
|
||||
|
||||
class FontIterator : std::iterator<std::forward_iterator_tag, LyXFont>
|
||||
{
|
||||
public:
|
||||
///
|
||||
FontIterator(LyXText const & text, lyx::pit_type pit, lyx::pos_type pos);
|
||||
FontIterator(LyXText const & text, Paragraph const & par, lyx::pos_type pos);
|
||||
///
|
||||
LyXFont operator*() const;
|
||||
///
|
||||
@ -43,7 +44,7 @@ private:
|
||||
///
|
||||
LyXText const & text_;
|
||||
///
|
||||
lyx::pit_type pit_;
|
||||
Paragraph const & par_;
|
||||
///
|
||||
lyx::pos_type pos_;
|
||||
///
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "bufferparams.h"
|
||||
#include "BufferView.h"
|
||||
#include "cursor.h"
|
||||
#include "coordcache.h"
|
||||
#include "gettext.h"
|
||||
#include "language.h"
|
||||
#include "LColor.h"
|
||||
@ -145,4 +146,64 @@ bool string2font(string const & data, LyXFont & font, bool & toggle)
|
||||
return (nset > 0);
|
||||
}
|
||||
|
||||
|
||||
// the next two should probably go elsewhere
|
||||
// this give the position relative to (0, baseline) of outermost
|
||||
// paragraph
|
||||
Point coordOffset(DocIterator const & dit)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
// Contribution of nested insets
|
||||
for (size_t i = 1; i != dit.size(); ++i) {
|
||||
CursorSlice const & sl = dit[i];
|
||||
int xx = 0, yy = 0;
|
||||
sl.inset().getCursorPos(sl, xx, yy);
|
||||
x += xx;
|
||||
y += yy;
|
||||
//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)
|
||||
y += par.rows()[rit].height();
|
||||
y += par.rows()[par.pos2row(sl.pos())].ascent();
|
||||
x += dit.bottom().text()->cursorX(dit.bottom());
|
||||
return Point(x,y);
|
||||
}
|
||||
|
||||
|
||||
Point getPos(DocIterator const & dit)
|
||||
{
|
||||
CursorSlice const & bot = dit.bottom();
|
||||
CoordCache::InnerParPosCache & cache = theCoords.pars_[bot.text()];
|
||||
CoordCache::InnerParPosCache::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
|
||||
p.y_ += it->second.y_;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// this could be used elsewhere as well?
|
||||
CurStatus status(BufferView const * bv, DocIterator const & dit)
|
||||
{
|
||||
CoordCache::InnerParPosCache & cache = theCoords.pars_[dit.bottom().text()];
|
||||
|
||||
if (cache.find(dit.bottom().pit()) != cache.end())
|
||||
return CUR_INSIDE;
|
||||
else if (dit.bottom().pit() < bv->anchor_ref())
|
||||
return CUR_ABOVE;
|
||||
else
|
||||
return CUR_BELOW;
|
||||
}
|
||||
|
||||
|
||||
} // namespace bv_funcs
|
||||
|
@ -17,6 +17,9 @@
|
||||
#include <string>
|
||||
|
||||
class LyXFont;
|
||||
class Point;
|
||||
class DocIterator;
|
||||
class BufferView;
|
||||
|
||||
|
||||
namespace bv_funcs {
|
||||
@ -32,6 +35,21 @@ bool string2font(std::string const & data, LyXFont & font, bool & toggle);
|
||||
*/
|
||||
std::string const freefont2string();
|
||||
|
||||
Point getPos(DocIterator const & dit);
|
||||
|
||||
enum CurStatus {
|
||||
CUR_INSIDE,
|
||||
CUR_ABOVE,
|
||||
CUR_BELOW
|
||||
};
|
||||
|
||||
|
||||
CurStatus status(BufferView const * bv, DocIterator const & dit);
|
||||
|
||||
|
||||
Point coordOffset(DocIterator const & dit);
|
||||
|
||||
|
||||
} // namespace bv_funcs
|
||||
|
||||
#endif
|
||||
|
@ -2,23 +2,45 @@
|
||||
#include "coordcache.h"
|
||||
#include "debug.h"
|
||||
|
||||
CoordCache theCoords;
|
||||
#include "lyxtext.h"
|
||||
|
||||
#include "mathed/math_data.h"
|
||||
#include "insets/insetbase.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
|
||||
CoordCache theCoords;
|
||||
|
||||
// just a helper to be able to set a breakpoint
|
||||
void lyxbreaker(void const * data, const char * hint, int size)
|
||||
{
|
||||
lyxerr << "break on pointer: " << data << " hint: " << hint
|
||||
<< " size: " << size << std::endl;
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
void lyxaborter(int x, int y)
|
||||
{
|
||||
lyxerr << "abort on x: " << x << " y: " << y << std::endl;
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
void CoordCache::clear()
|
||||
{
|
||||
// lyxerr << "CoordCache: removing " << arrays_.data_.size()
|
||||
// << " arrays" << std::endl;
|
||||
// lyxerr << "CoordCache: removing " << insets_.data_.size()
|
||||
// << " insets" << std::endl;
|
||||
arrays_.clear();
|
||||
insets_.clear();
|
||||
pars_.clear();
|
||||
}
|
||||
|
||||
|
||||
Point CoordCache::get(LyXText const * text, lyx::pit_type pit)
|
||||
{
|
||||
ParPosCache::iterator const it = pars_.find(text);
|
||||
BOOST_ASSERT(it != pars_.end());
|
||||
InnerParPosCache::iterator const posit = it->second.find(pit);
|
||||
BOOST_ASSERT(posit != it->second.end());
|
||||
return posit->second;
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
#ifndef COORDCACHE_H
|
||||
#define COORDCACHE_H
|
||||
|
||||
#include "mathed/math_data.h"
|
||||
#include "insets/insetbase.h"
|
||||
#include "lyxtext.h"
|
||||
class InsetBase;
|
||||
class LyXText;
|
||||
class MathArray;
|
||||
class Paragraph;
|
||||
|
||||
#include "support/types.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
@ -15,6 +18,7 @@
|
||||
// to the right, y increases downwords.
|
||||
|
||||
void lyxbreaker(void const * data, const char * hint, int size);
|
||||
void lyxaborter(int x, int y);
|
||||
|
||||
struct Point {
|
||||
Point()
|
||||
@ -79,10 +83,8 @@ private:
|
||||
|
||||
void check(T const * thing, char const * hint) const
|
||||
{
|
||||
if (!has(thing)) {
|
||||
if (!has(thing))
|
||||
lyxbreaker(thing, hint, data_.size());
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<T const *, Point> cache_type;
|
||||
@ -93,9 +95,17 @@ private:
|
||||
class CoordCache {
|
||||
public:
|
||||
void clear();
|
||||
Point get(LyXText const *, lyx::pit_type);
|
||||
|
||||
CoordCacheBase<MathArray> arrays_;
|
||||
|
||||
// all insets
|
||||
CoordCacheBase<InsetBase> insets_;
|
||||
|
||||
// paragraph grouped by owning text
|
||||
typedef std::map<lyx::pit_type, Point> InnerParPosCache;
|
||||
typedef std::map<LyXText const *, InnerParPosCache> ParPosCache;
|
||||
ParPosCache pars_;
|
||||
};
|
||||
|
||||
extern CoordCache theCoords;
|
||||
|
72
src/cursor.C
72
src/cursor.C
@ -15,6 +15,7 @@
|
||||
#include "BufferView.h"
|
||||
#include "buffer.h"
|
||||
#include "cursor.h"
|
||||
#include "coordcache.h"
|
||||
#include "CutAndPaste.h"
|
||||
#include "debug.h"
|
||||
#include "dispatchresult.h"
|
||||
@ -42,6 +43,7 @@
|
||||
#include "support/limited_stack.h"
|
||||
|
||||
#include "frontends/LyXView.h"
|
||||
#include "frontends/font_metrics.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
@ -80,9 +82,10 @@ namespace {
|
||||
|
||||
|
||||
// Find position closest to (x, y) in cell given by iter.
|
||||
// Used only in mathed
|
||||
DocIterator bruteFind2(LCursor const & c, int x, int y)
|
||||
{
|
||||
double best_dist = 1e10;
|
||||
double best_dist = std::numeric_limits<double>::max();
|
||||
|
||||
DocIterator result;
|
||||
|
||||
@ -94,11 +97,12 @@ namespace {
|
||||
int xo, yo;
|
||||
LCursor cur = c;
|
||||
cur.setCursor(it);
|
||||
cur.inset().getCursorPos(cur, xo, yo);
|
||||
cur.inset().getCursorPos(cur.top(), 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'
|
||||
lyxerr[Debug::DEBUG] << "i: " << i << " d: " << d << " best: " << best_dist << endl;
|
||||
lyxerr[Debug::DEBUG] << "i: " << i << " d: " << d
|
||||
<< " best: " << best_dist << endl;
|
||||
if (d <= best_dist) {
|
||||
best_dist = d;
|
||||
result = it;
|
||||
@ -120,27 +124,20 @@ namespace {
|
||||
CursorSlice bottom = cursor[0];
|
||||
LyXText * text = bottom.text();
|
||||
BOOST_ASSERT(text);
|
||||
getParsInRange(text->paragraphs(), ylow, yhigh, beg, end);
|
||||
|
||||
DocIterator it = doc_iterator_begin(bottom.inset());
|
||||
DocIterator const et = doc_iterator_end(bottom.inset());
|
||||
|
||||
DocIterator it = doc_iterator_begin(cursor.bv().buffer()->inset());
|
||||
DocIterator et = doc_iterator_end(cursor.bv().buffer()->inset());
|
||||
//lyxerr << "x: " << x << " y: " << y << endl;
|
||||
//lyxerr << "xlow: " << xlow << " ylow: " << ylow << endl;
|
||||
//lyxerr << "xhigh: " << xhigh << " yhigh: " << yhigh << endl;
|
||||
|
||||
it.pit() = beg;
|
||||
//et.pit() = text->parOffset(end);
|
||||
|
||||
double best_dist = 10e10;
|
||||
DocIterator best_cursor = it;
|
||||
double best_dist = std::numeric_limits<double>::max();;
|
||||
DocIterator best_cursor = et;
|
||||
|
||||
for ( ; it != et; it.forwardPos()) {
|
||||
// avoid invalid nesting when selecting
|
||||
if (!cursor.selection() || positionable(it, cursor.anchor_)) {
|
||||
int xo = 0, yo = 0;
|
||||
LCursor cur = cursor;
|
||||
cur.setCursor(it);
|
||||
cur.inset().getCursorPos(cur, xo, yo);
|
||||
if (bv_funcs::status(&cursor.bv(), it) == bv_funcs::CUR_INSIDE
|
||||
&& (!cursor.selection() || positionable(it, cursor.anchor_))) {
|
||||
Point p = bv_funcs::getPos(it);
|
||||
int xo = p.x_;
|
||||
int yo = p.y_;
|
||||
if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
|
||||
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
|
||||
//lyxerr << "xo: " << xo << " yo: " << yo << " d: " << d << endl;
|
||||
@ -156,15 +153,20 @@ namespace {
|
||||
}
|
||||
|
||||
//lyxerr << "best_dist: " << best_dist << " cur:\n" << best_cursor << endl;
|
||||
if (best_dist < 1e10)
|
||||
if (best_cursor != et) {
|
||||
cursor.setCursor(best_cursor);
|
||||
return best_dist < 1e10;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
// be careful: this is called from the bv's constructor, too, so
|
||||
// bv functions are not yet available!
|
||||
LCursor::LCursor(BufferView & bv)
|
||||
: DocIterator(), bv_(&bv), anchor_(), x_target_(-1),
|
||||
selection_(false), mark_(false)
|
||||
@ -348,11 +350,11 @@ void LCursor::getDim(int & asc, int & des) const
|
||||
BOOST_ASSERT(inset().asMathInset());
|
||||
//inset().asMathInset()->getCursorDim(asc, des);
|
||||
asc = 10;
|
||||
des = 10;
|
||||
des = 2;
|
||||
} else if (inTexted()) {
|
||||
Row const & row = textRow();
|
||||
asc = row.baseline();
|
||||
des = row.height() - asc;
|
||||
LyXFont const & realfont = text()->real_current_font;
|
||||
asc = font_metrics::maxAscent(realfont);
|
||||
des = font_metrics::maxDescent(realfont);
|
||||
} else {
|
||||
lyxerr << "should this happen?" << endl;
|
||||
asc = 10;
|
||||
@ -363,10 +365,9 @@ void LCursor::getDim(int & asc, int & des) const
|
||||
|
||||
void LCursor::getPos(int & x, int & y) const
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
if (!empty())
|
||||
inset().getCursorPos(*this, x, y);
|
||||
Point p = bv_funcs::getPos(*this);
|
||||
x = p.x_;
|
||||
y = p.y_;
|
||||
}
|
||||
|
||||
|
||||
@ -857,6 +858,17 @@ int LCursor::targetX() const
|
||||
}
|
||||
|
||||
|
||||
void LCursor::setTargetX()
|
||||
{
|
||||
//for now this is good enough. A better solution would be to
|
||||
//avoid this rebreak by setting cursorX only after drawing
|
||||
bottom().text()->redoParagraph(bottom().pit());
|
||||
int x, y;
|
||||
getPos(x, y);
|
||||
x_target_ = x;
|
||||
}
|
||||
|
||||
|
||||
bool LCursor::inMacroMode() const
|
||||
{
|
||||
if (pos() == 0)
|
||||
|
15
src/cursor.h
15
src/cursor.h
@ -22,6 +22,7 @@ class Buffer;
|
||||
class BufferView;
|
||||
class FuncStatus;
|
||||
class FuncRequest;
|
||||
class Point;
|
||||
|
||||
// these should go
|
||||
class MathUnknownInset;
|
||||
@ -119,10 +120,14 @@ public:
|
||||
/// insert a string
|
||||
void insert(std::string const & str);
|
||||
|
||||
/// in pixels from left of screen
|
||||
int targetX() const;
|
||||
/// write acess to target x position of cursor
|
||||
int & x_target();
|
||||
/// return target x position of cursor
|
||||
int x_target() const;
|
||||
/// set targetX in current position
|
||||
void setTargetX();
|
||||
/// clear target x position of cursor
|
||||
void clearTargetX();
|
||||
|
||||
@ -165,6 +170,7 @@ public:
|
||||
///
|
||||
DispatchResult disp_;
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* The target x position of the cursor. This is used for when
|
||||
@ -184,11 +190,6 @@ private:
|
||||
/// are we on the way to get one?
|
||||
bool mark_;
|
||||
|
||||
public:
|
||||
/// the actual cursor position
|
||||
int xo_;
|
||||
int yo_;
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
@ -232,8 +233,6 @@ public:
|
||||
|
||||
/// in pixels from top of screen
|
||||
void setScreenPos(int x, int y);
|
||||
/// in pixels from left of screen
|
||||
int targetX() const;
|
||||
/// current offset in the top cell
|
||||
/// interpret name a name of a macro
|
||||
void macroModeClose();
|
||||
@ -281,4 +280,6 @@ public:
|
||||
Encoding const * getEncoding() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // LYXCURSOR_H
|
||||
|
@ -64,9 +64,9 @@ public:
|
||||
idx_type & idx() { return idx_; }
|
||||
/// return the last cell in this inset
|
||||
idx_type lastidx() const { return nargs() - 1; }
|
||||
/// return the paragraph this cursor is in
|
||||
/// return the offset of the paragraph this cursor is in
|
||||
pit_type pit() const { return pit_; }
|
||||
/// set the paragraph this cursor is in
|
||||
/// set the offset of the paragraph this cursor is in
|
||||
pit_type & pit() { return pit_; }
|
||||
/// increments the paragraph this cursor is in
|
||||
void incrementPar();
|
||||
|
@ -146,13 +146,13 @@ Paragraph const & DocIterator::paragraph() const
|
||||
|
||||
Row & DocIterator::textRow()
|
||||
{
|
||||
return *paragraph().getRow(pos());
|
||||
return paragraph().getRow(pos());
|
||||
}
|
||||
|
||||
|
||||
Row const & DocIterator::textRow() const
|
||||
{
|
||||
return *paragraph().getRow(pos());
|
||||
return paragraph().getRow(pos());
|
||||
}
|
||||
|
||||
|
||||
@ -168,18 +168,6 @@ DocIterator::pos_type DocIterator::lastpos() const
|
||||
}
|
||||
|
||||
|
||||
DocIterator::row_type DocIterator::crow() const
|
||||
{
|
||||
return paragraph().row(pos());
|
||||
}
|
||||
|
||||
|
||||
DocIterator::row_type DocIterator::lastcrow() const
|
||||
{
|
||||
return paragraph().rows.size();
|
||||
}
|
||||
|
||||
|
||||
DocIterator::idx_type DocIterator::lastidx() const
|
||||
{
|
||||
return top().lastidx();
|
||||
@ -314,7 +302,7 @@ void DocIterator::forwardPos()
|
||||
top.pos() = 0;
|
||||
return;
|
||||
}
|
||||
//lyxerr << "... no next par" << endl;
|
||||
//lyxerr << "... no next pit" << endl;
|
||||
|
||||
// otherwise try to move on one cell if possible
|
||||
if (top.idx() < lastidx()) {
|
||||
|
@ -92,10 +92,6 @@ public:
|
||||
pos_type & pos() { return back().pos(); }
|
||||
/// return the last position within the paragraph
|
||||
pos_type lastpos() const;
|
||||
/// return the display row of the cursor with in the top par
|
||||
row_type crow() const;
|
||||
/// return the display row of the cursor with in the top par
|
||||
row_type lastcrow() const;
|
||||
|
||||
/// return the number of embedded cells
|
||||
size_t nargs() const;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2004-11-26 Alfredo Braunstein <abraunst@lyx.org>
|
||||
|
||||
* Painter.C: adjust * screen.[Ch] (fitCursor): remove,
|
||||
(showCursor): adjust, (redraw): adjust
|
||||
|
||||
2004-11-20 Lars Gullik Bjonnes <larsbj@gullik.net>
|
||||
|
||||
* Dialogs.h: include <map> since it is used in this file, fixes
|
||||
|
@ -41,20 +41,20 @@ void Painter::buttonFrame(int x, int y, int w, int h)
|
||||
int x1[4], y1[4];
|
||||
|
||||
x1[0] = x + d; y1[0] = y + d;
|
||||
x1[1] = x + d; y1[1] = (y + h - d);
|
||||
x1[2] = x; y1[2] = y + h;
|
||||
x1[3] = x; y1[3] = y;
|
||||
x1[1] = x + d; y1[1] = y + h - d;
|
||||
x1[2] = x; y1[2] = y + h;
|
||||
x1[3] = x; y1[3] = y;
|
||||
fillPolygon(x1, y1, 4, LColor::left);
|
||||
|
||||
x1[0] = (x + w - d); y1[0] = y + d;
|
||||
x1[1] = (x + w - d); y1[1] = (y + h - d);
|
||||
x1[2] = x + w; y1[2] = (y + h - d);
|
||||
x1[3] = x + w; y1[3] = y;
|
||||
x1[0] = x + w - d; y1[0] = y + d;
|
||||
x1[1] = x + w - d; y1[1] = y + h - d;
|
||||
x1[2] = x + w; y1[2] = y + h - d;
|
||||
x1[3] = x + w; y1[3] = y;
|
||||
fillPolygon(x1, y1, 4, LColor::right);
|
||||
}
|
||||
|
||||
|
||||
void Painter::rectText(int x, int baseline,
|
||||
void Painter::rectText(int x, int y,
|
||||
string const & str,
|
||||
LyXFont const & font,
|
||||
LColor_color back,
|
||||
@ -66,22 +66,18 @@ void Painter::rectText(int x, int baseline,
|
||||
|
||||
font_metrics::rectText(str, font, width, ascent, descent);
|
||||
|
||||
if (back != LColor::none) {
|
||||
fillRectangle(x + 1, baseline - ascent + 1, width - 1,
|
||||
if (back != LColor::none)
|
||||
fillRectangle(x + 1, y - ascent + 1, width - 1,
|
||||
ascent + descent - 1, back);
|
||||
}
|
||||
|
||||
if (frame != LColor::none) {
|
||||
rectangle(x, baseline - ascent, width, ascent + descent, frame);
|
||||
}
|
||||
if (frame != LColor::none)
|
||||
rectangle(x, y - ascent, width, ascent + descent, frame);
|
||||
|
||||
text(x + 3, baseline, str, font);
|
||||
text(x + 3, y, str, font);
|
||||
}
|
||||
|
||||
|
||||
void Painter::buttonText(int x, int baseline,
|
||||
string const & str,
|
||||
LyXFont const & font)
|
||||
void Painter::buttonText(int x, int y, string const & str, LyXFont const & font)
|
||||
{
|
||||
int width;
|
||||
int ascent;
|
||||
@ -89,8 +85,8 @@ void Painter::buttonText(int x, int baseline,
|
||||
|
||||
font_metrics::buttonText(str, font, width, ascent, descent);
|
||||
|
||||
button(x, baseline - ascent, width, descent + ascent);
|
||||
text(x + 4, baseline, str, font);
|
||||
button(x, y - ascent, width, descent + ascent);
|
||||
text(x + 4, y, str, font);
|
||||
}
|
||||
|
||||
|
||||
@ -99,10 +95,8 @@ void Painter::underline(LyXFont const & f, int x, int y, int width)
|
||||
int const below = max(font_metrics::maxDescent(f) / 2, 2);
|
||||
int const height = max((font_metrics::maxDescent(f) / 4) - 1, 1);
|
||||
|
||||
if (height < 2) {
|
||||
if (height < 2)
|
||||
line(x, y + below, x + width, y + below, f.color());
|
||||
} else {
|
||||
fillRectangle(x, y + below, width, below + height,
|
||||
f.color());
|
||||
}
|
||||
else
|
||||
fillRectangle(x, y + below, width, below + height, f.color());
|
||||
}
|
||||
|
@ -235,9 +235,6 @@ void ControlSpellchecker::check()
|
||||
// if we used a lfun like in find/replace, dispatch would do
|
||||
// that for us
|
||||
kernel().bufferview()->update();
|
||||
if (kernel().bufferview()->fitCursor())
|
||||
kernel().bufferview()->update();
|
||||
|
||||
|
||||
// set suggestions
|
||||
if (res != SpellBase::OK && res != SpellBase::IGNORE) {
|
||||
|
@ -121,12 +121,12 @@ SplashScreen::SplashScreen()
|
||||
|
||||
|
||||
LyXScreen::LyXScreen()
|
||||
: cursor_visible_(false), greyed_out_(true)
|
||||
: greyed_out_(true), cursor_visible_(false)
|
||||
{
|
||||
// Start loading the pixmap as soon as possible
|
||||
if (lyxrc.show_banner) {
|
||||
SplashScreen const & splash = SplashScreen::get();
|
||||
splash.connect(boost::bind(&LyXScreen::greyOut, this));
|
||||
splash.connect(boost::bind(&LyXScreen::checkAndGreyOut, this));
|
||||
splash.startLoading();
|
||||
}
|
||||
}
|
||||
@ -137,6 +137,13 @@ LyXScreen::~LyXScreen()
|
||||
}
|
||||
|
||||
|
||||
void LyXScreen::checkAndGreyOut()
|
||||
{
|
||||
if (greyed_out_)
|
||||
greyOut();
|
||||
}
|
||||
|
||||
|
||||
void LyXScreen::showCursor(BufferView & bv)
|
||||
{
|
||||
// this is needed to make sure we copy back the right
|
||||
@ -167,13 +174,13 @@ void LyXScreen::showCursor(BufferView & bv)
|
||||
if (realfont.language() == latex_language)
|
||||
shape = BAR_SHAPE;
|
||||
|
||||
int ascent = font_metrics::maxAscent(realfont);
|
||||
int descent = font_metrics::maxDescent(realfont);
|
||||
int ascent, descent;
|
||||
bv.cursor().getDim(ascent, descent);
|
||||
int h = ascent + descent;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
bv.cursor().getPos(x, y);
|
||||
y -= ascent + bv.top_y();
|
||||
y -= ascent;
|
||||
//lyxerr << "LyXScreen::showCursor x: " << x << " y: " << y << endl;
|
||||
|
||||
// if it doesn't fit entirely on the screen, don't try to show it
|
||||
@ -204,84 +211,22 @@ void LyXScreen::toggleCursor(BufferView & bv)
|
||||
}
|
||||
|
||||
|
||||
bool LyXScreen::fitCursor(BufferView * bv)
|
||||
void LyXScreen::redraw(BufferView & bv, ViewMetricsInfo const & vi)
|
||||
{
|
||||
int const top_y = bv->top_y();
|
||||
int const h = workarea().workHeight();
|
||||
int newtop = top_y;
|
||||
int x, y, asc, desc;
|
||||
|
||||
bv->cursor().getPos(x, y);
|
||||
bv->cursor().getDim(asc, desc);
|
||||
lyxerr[Debug::DEBUG] << "LyXScreen::fitCursor: x: " << x
|
||||
<< " y: " << y
|
||||
<< " top_y: " << top_y
|
||||
<< endl;
|
||||
|
||||
bool const big_row = h / 4 < asc + desc && asc + desc < h;
|
||||
|
||||
if (y + desc - top_y >= h) {
|
||||
if (big_row)
|
||||
newtop = y + desc - h;
|
||||
else
|
||||
newtop = y - h / 2;
|
||||
|
||||
} else if (top_y > max(y - asc, 0)) {
|
||||
if (big_row)
|
||||
newtop = y - asc;
|
||||
else {
|
||||
newtop = y - h / 2;
|
||||
newtop = min(newtop, top_y);
|
||||
}
|
||||
}
|
||||
|
||||
newtop = max(newtop, 0);
|
||||
if (newtop == top_y)
|
||||
return false;
|
||||
|
||||
bv->top_y(newtop);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LyXScreen::redraw(BufferView & bv)
|
||||
{
|
||||
greyed_out_ = !bv.text();
|
||||
|
||||
if (greyed_out_) {
|
||||
greyOut();
|
||||
return;
|
||||
}
|
||||
|
||||
greyed_out_ = false;
|
||||
workarea().getPainter().start();
|
||||
|
||||
hideCursor();
|
||||
|
||||
int const y = paintText(bv);
|
||||
|
||||
// maybe we have to clear the screen at the bottom
|
||||
int const y2 = workarea().workHeight();
|
||||
if (y < y2 && bv.text()->isMainText()) {
|
||||
workarea().getPainter().fillRectangle(0, y,
|
||||
workarea().workWidth(), y2 - y,
|
||||
LColor::bottomarea);
|
||||
}
|
||||
|
||||
paintText(bv, vi);
|
||||
lyxerr[Debug::DEBUG] << "Redraw screen" << endl;
|
||||
|
||||
expose(0, 0, workarea().workWidth(), workarea().workHeight());
|
||||
|
||||
workarea().getPainter().end();
|
||||
|
||||
showCursor(bv);
|
||||
}
|
||||
|
||||
|
||||
void LyXScreen::greyOut()
|
||||
{
|
||||
if (!greyed_out_)
|
||||
return;
|
||||
|
||||
greyed_out_ = true;
|
||||
workarea().getPainter().start();
|
||||
|
||||
workarea().getPainter().fillRectangle(0, 0,
|
||||
|
@ -13,10 +13,13 @@
|
||||
#ifndef SCREEN_H
|
||||
#define SCREEN_H
|
||||
|
||||
|
||||
class LyXText;
|
||||
class CursorSlice;
|
||||
class WorkArea;
|
||||
class BufferView;
|
||||
class ViewMetricsInfo;
|
||||
|
||||
|
||||
/**
|
||||
* LyXScreen - document rendering management
|
||||
@ -37,16 +40,10 @@ public:
|
||||
virtual ~LyXScreen();
|
||||
|
||||
/// redraw the screen, without using existing pixmap
|
||||
virtual void redraw(BufferView & bv);
|
||||
virtual void redraw(BufferView & bv, ViewMetricsInfo const & vi);
|
||||
|
||||
/**
|
||||
* fitCursor - fit the cursor onto the work area
|
||||
* @param bv the bufferview
|
||||
* @return true if a change was necessary
|
||||
*
|
||||
* Scrolls the screen so that the cursor is visible
|
||||
*/
|
||||
virtual bool fitCursor(BufferView *);
|
||||
/// grey out (no buffer)
|
||||
void greyOut();
|
||||
|
||||
/// hide the visible cursor, if it is visible
|
||||
void hideCursor();
|
||||
@ -81,14 +78,14 @@ protected:
|
||||
virtual void removeCursor() = 0;
|
||||
|
||||
private:
|
||||
/// grey out (no buffer)
|
||||
void greyOut();
|
||||
///
|
||||
void checkAndGreyOut();
|
||||
|
||||
///
|
||||
bool greyed_out_;
|
||||
|
||||
/// is the cursor currently displayed
|
||||
bool cursor_visible_;
|
||||
|
||||
/// is the screen displaying text or the splash screen?
|
||||
bool greyed_out_;
|
||||
};
|
||||
|
||||
#endif // SCREEN_H
|
||||
|
@ -1,3 +1,14 @@
|
||||
2004-11-26 Alfredo Braunstein <abraunst@lyx.org>
|
||||
|
||||
* insettabular.[Ch]: adjust, introduce "do not draw
|
||||
offscreen" optimization using NullPainter, (dist): introduce,
|
||||
(getCursorPos): implement, (drawSelection): implement
|
||||
|
||||
* insetcollapsable.[Ch]: adjust
|
||||
|
||||
* insettext.C: adjust, (metrics): set the font before calling
|
||||
LyXText::metrics
|
||||
|
||||
2004-11-25 Lars Gullik Bjonnes <larsbj@gullik.net>
|
||||
|
||||
* rename a lot of InsetOld to InsetBase
|
||||
|
@ -238,7 +238,7 @@ void InsetBase::markErased()
|
||||
{}
|
||||
|
||||
|
||||
void InsetBase::getCursorPos(LCursor const &, int & x, int & y) const
|
||||
void InsetBase::getCursorPos(CursorSlice const &, int & x, int & y) const
|
||||
{
|
||||
lyxerr << "InsetBase::getCursorPos called directly" << std::endl;
|
||||
x = 100;
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
/// 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(LCursor const & cur, int & x, int & y) const;
|
||||
virtual void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
|
||||
|
||||
/// is this an inset that can be moved into?
|
||||
virtual bool isActive() const { return nargs() > 0; }
|
||||
|
@ -62,11 +62,8 @@ void InsetBibitem::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
case LFUN_INSET_MODIFY: {
|
||||
InsetCommandParams p;
|
||||
InsetCommandMailer::string2params("bibitem", cmd.argument, p);
|
||||
if (p.getCmdName().empty())
|
||||
break;
|
||||
setParams(p);
|
||||
cur.bv().update();
|
||||
cur.bv().fitCursor();
|
||||
if (!p.getCmdName().empty())
|
||||
setParams(p);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -100,11 +97,10 @@ void InsetBibitem::write(Buffer const &, std::ostream & os) const
|
||||
// This should be changed!!! (Jug)
|
||||
void InsetBibitem::read(Buffer const &, LyXLex & lex)
|
||||
{
|
||||
if (lex.eatLine()) {
|
||||
if (lex.eatLine())
|
||||
scanCommand(lex.getString());
|
||||
} else {
|
||||
else
|
||||
lex.printError("InsetCommand: Parse error: `$$Token'");
|
||||
}
|
||||
|
||||
if (prefixIs(getContents(), key_prefix)) {
|
||||
int key = strToInt(getContents().substr(key_prefix.length()));
|
||||
|
@ -50,8 +50,8 @@ void leaveInset(LCursor & cur, InsetBase const & in)
|
||||
}
|
||||
|
||||
|
||||
InsetCollapsable::InsetCollapsable(BufferParams const & bp,
|
||||
CollapseStatus status)
|
||||
InsetCollapsable::InsetCollapsable
|
||||
(BufferParams const & bp, CollapseStatus status)
|
||||
: InsetText(bp), label("Label"), status_(status), openinlined_(false)
|
||||
{
|
||||
setAutoBreakRows(true);
|
||||
@ -122,9 +122,11 @@ void InsetCollapsable::read(Buffer const & buf, LyXLex & lex)
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::dimension_collapsed(Dimension & dim) const
|
||||
Dimension InsetCollapsable::dimensionCollapsed() const
|
||||
{
|
||||
Dimension dim;
|
||||
font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des);
|
||||
return dim;
|
||||
}
|
||||
|
||||
|
||||
@ -134,14 +136,14 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
if (status_ == Inlined) {
|
||||
InsetText::metrics(mi, dim);
|
||||
} else {
|
||||
dimension_collapsed(dim);
|
||||
dim = dimensionCollapsed();
|
||||
if (status_ == Open) {
|
||||
InsetText::metrics(mi, textdim_);
|
||||
openinlined_ = (textdim_.wid + dim.wid <= mi.base.textwidth);
|
||||
if (openinlined_) {
|
||||
dim.wid += textdim_.wid;
|
||||
dim.des = max(dim.des, textdim_.des);
|
||||
dim.asc = max(dim.asc, textdim_.asc);
|
||||
dim.des = max(dim.des - textdim_.asc + dim.asc, textdim_.des);
|
||||
dim.asc = textdim_.asc;
|
||||
} else {
|
||||
dim.des += textdim_.height() + TEXT_TO_BOTTOM_OFFSET;
|
||||
dim.wid = max(dim.wid, textdim_.wid);
|
||||
@ -156,42 +158,71 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::draw_collapsed(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
pi.pain.buttonText(x, y, label, labelfont_);
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
x += TEXT_TO_INSET_OFFSET;
|
||||
y += TEXT_TO_INSET_OFFSET;
|
||||
|
||||
const int xx = x + TEXT_TO_INSET_OFFSET;
|
||||
if (status_ == Inlined) {
|
||||
InsetText::draw(pi, x, y);
|
||||
InsetText::draw(pi, xx, y);
|
||||
} else {
|
||||
Dimension dimc;
|
||||
dimension_collapsed(dimc);
|
||||
int const aa = ascent();
|
||||
button_dim.x1 = x + 0;
|
||||
button_dim.x2 = x + dimc.width();
|
||||
button_dim.y1 = y - aa + pi.base.bv->top_y();
|
||||
button_dim.y2 = y - aa + pi.base.bv->top_y() + dimc.height();
|
||||
Dimension dimc = dimensionCollapsed();
|
||||
int const top = y - ascent() + TEXT_TO_INSET_OFFSET;
|
||||
button_dim.x1 = xx + 0;
|
||||
button_dim.x2 = xx + dimc.width();
|
||||
button_dim.y1 = top;
|
||||
button_dim.y2 = top + dimc.height();
|
||||
|
||||
draw_collapsed(pi, x, y - aa + dimc.asc);
|
||||
pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
|
||||
if (status_ == Open) {
|
||||
if (openinlined_)
|
||||
InsetText::draw(pi, x + dimc.width(),
|
||||
y - aa + textdim_.asc);
|
||||
else
|
||||
InsetText::draw(pi, x, dimc.height()
|
||||
+ y - aa + textdim_.asc);
|
||||
int textx, texty;
|
||||
if (openinlined_) {
|
||||
textx = xx + dimc.width();
|
||||
texty = top + textdim_.asc;
|
||||
} else {
|
||||
textx = xx;
|
||||
texty = top + dimc.height() + textdim_.asc;
|
||||
}
|
||||
InsetText::draw(pi, textx, texty);
|
||||
}
|
||||
}
|
||||
setPosCache(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
x += TEXT_TO_INSET_OFFSET;
|
||||
if (status_ == Open) {
|
||||
if (openinlined_)
|
||||
x += dimensionCollapsed().wid;
|
||||
else
|
||||
y += dimensionCollapsed().des + textdim_.asc;
|
||||
}
|
||||
if (status_ != Collapsed)
|
||||
InsetText::drawSelection(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::getCursorPos
|
||||
(CursorSlice const & sl, 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;
|
||||
}
|
||||
|
||||
x += TEXT_TO_INSET_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
InsetBase::EDITABLE InsetCollapsable::editable() const
|
||||
{
|
||||
return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE;
|
||||
@ -242,21 +273,17 @@ void InsetCollapsable::edit(LCursor & cur, bool left)
|
||||
|
||||
InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y) const
|
||||
{
|
||||
cur.push(const_cast<InsetCollapsable&>(*this));
|
||||
//lyxerr << "InsetCollapsable: edit xy" << endl;
|
||||
if (status_ == Collapsed) {
|
||||
return const_cast<InsetCollapsable*>(this);
|
||||
}
|
||||
cur.push(const_cast<InsetCollapsable&>(*this));
|
||||
return InsetText::editXY(cur, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
{
|
||||
// lyxerr << "InsetCollapsable::doDispatch (begin): cmd: " << cmd
|
||||
// << " button y: " << button_dim.y2
|
||||
// << " coll/inline/open: " << status_ << endl;
|
||||
|
||||
lyxerr << "InsetCollapsable::doDispatch (begin): cmd: " << cmd
|
||||
<< " cur: " << cur << " bvcur: " << cur.bv().cursor() << endl;
|
||||
|
||||
@ -267,7 +294,7 @@ void InsetCollapsable::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
else if (status_ == Open && !hitButton(cmd))
|
||||
InsetText::doDispatch(cur, cmd);
|
||||
else
|
||||
cur.noUpdate();
|
||||
cur.noUpdate();
|
||||
break;
|
||||
|
||||
case LFUN_MOUSE_MOTION:
|
||||
@ -275,6 +302,8 @@ void InsetCollapsable::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
InsetText::doDispatch(cur, cmd);
|
||||
else if (status_ == Open && !hitButton(cmd))
|
||||
InsetText::doDispatch(cur, cmd);
|
||||
else
|
||||
cur.undispatched();
|
||||
break;
|
||||
|
||||
case LFUN_MOUSE_RELEASE:
|
||||
@ -287,8 +316,7 @@ void InsetCollapsable::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
|
||||
case Collapsed:
|
||||
lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl;
|
||||
open();
|
||||
InsetText::edit(cur, true);
|
||||
edit(cur, true);
|
||||
cur.bv().cursor() = cur;
|
||||
break;
|
||||
|
||||
@ -367,9 +395,9 @@ void InsetCollapsable::setLabel(string const & l)
|
||||
}
|
||||
|
||||
|
||||
void InsetCollapsable::setStatus(CollapseStatus st)
|
||||
void InsetCollapsable::setStatus(CollapseStatus status)
|
||||
{
|
||||
status_ = st;
|
||||
status_ = status;
|
||||
setButtonLabel();
|
||||
}
|
||||
|
||||
@ -391,8 +419,3 @@ void InsetCollapsable::scroll(BufferView & bv, int offset) const
|
||||
UpdatableInset::scroll(bv, offset);
|
||||
}
|
||||
|
||||
|
||||
Box const & InsetCollapsable::buttonDim() const
|
||||
{
|
||||
return button_dim;
|
||||
}
|
||||
|
@ -51,6 +51,10 @@ public:
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
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;
|
||||
///
|
||||
bool hitButton(FuncRequest &) const;
|
||||
///
|
||||
std::string const getNewLabel(std::string const & l) const;
|
||||
@ -91,9 +95,7 @@ protected:
|
||||
///
|
||||
virtual void doDispatch(LCursor & cur, FuncRequest & cmd);
|
||||
///
|
||||
void dimension_collapsed(Dimension &) const;
|
||||
///
|
||||
void draw_collapsed(PainterInfo & pi, int x, int y) const;
|
||||
Dimension dimensionCollapsed() const;
|
||||
///
|
||||
int getMaxTextWidth(Painter & pain, UpdatableInset const *) const;
|
||||
///
|
||||
|
@ -79,10 +79,12 @@ auto_ptr<InsetBase> InsetERT::doClone() const
|
||||
|
||||
|
||||
InsetERT::InsetERT(BufferParams const & bp,
|
||||
Language const * l, string const & contents, CollapseStatus status)
|
||||
Language const *, string const & contents, CollapseStatus status)
|
||||
: InsetCollapsable(bp, status)
|
||||
{
|
||||
LyXFont font(LyXFont::ALL_INHERIT, l);
|
||||
//LyXFont font(LyXFont::ALL_INHERIT, lang);
|
||||
LyXFont font;
|
||||
getDrawFont(font);
|
||||
string::const_iterator cit = contents.begin();
|
||||
string::const_iterator end = contents.end();
|
||||
pos_type pos = 0;
|
||||
@ -259,7 +261,7 @@ bool InsetERT::getStatus(LCursor & cur, FuncRequest const & cmd,
|
||||
|
||||
void InsetERT::setButtonLabel()
|
||||
{
|
||||
setLabel(status() == Collapsed ? getNewLabel(_("P-ERT")) : _("P-ERT"));
|
||||
setLabel(status() == Collapsed ? getNewLabel(_("ERT")) : _("ERT"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "bufferparams.h"
|
||||
#include "BufferView.h"
|
||||
#include "cursor.h"
|
||||
#include "coordcache.h"
|
||||
#include "debug.h"
|
||||
#include "dispatchresult.h"
|
||||
#include "funcrequest.h"
|
||||
@ -36,6 +37,7 @@
|
||||
#include "frontends/font_metrics.h"
|
||||
#include "frontends/LyXView.h"
|
||||
#include "frontends/Painter.h"
|
||||
#include "frontends/nullpainter.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
@ -251,7 +253,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
}
|
||||
|
||||
dim.asc = tabular.getAscentOfRow(0);
|
||||
dim.des = tabular.getHeightOfTabular() - tabular.getAscentOfRow(0) + 1;
|
||||
dim.des = tabular.getHeightOfTabular() - dim.asc;
|
||||
dim.wid = tabular.getWidthOfTabular() + 2 * ADD_TO_TABULAR_WIDTH;
|
||||
dim_ = dim;
|
||||
}
|
||||
@ -260,8 +262,13 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
void InsetTabular::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
//lyxerr << "InsetTabular::draw: " << x << " " << y << endl;
|
||||
|
||||
BufferView * bv = pi.base.bv;
|
||||
|
||||
static NullPainter nop;
|
||||
static PainterInfo nullpi(bv, nop);
|
||||
|
||||
resetPos(bv->cursor());
|
||||
|
||||
setPosCache(pi, x, y);
|
||||
|
||||
x += scroll();
|
||||
@ -271,45 +278,76 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
|
||||
first_visible_cell = -1;
|
||||
for (int i = 0; i < tabular.rows(); ++i) {
|
||||
int nx = x;
|
||||
int const a = tabular.getAscentOfRow(i);
|
||||
int const d = tabular.getDescentOfRow(i);
|
||||
idx = tabular.getCellNumber(i, 0);
|
||||
if (y + tabular.getDescentOfRow(i) <= 0
|
||||
&& y - tabular.getAscentOfRow(i) < pi.pain.paperHeight()) {
|
||||
y += tabular.getDescentOfRow(i)
|
||||
+ tabular.getAscentOfRow(i + 1)
|
||||
if (y + d <= 0 && y - a < pi.pain.paperHeight()) {
|
||||
y += d + tabular.getAscentOfRow(i + 1)
|
||||
+ tabular.getAdditionalHeight(i + 1);
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < tabular.columns(); ++j) {
|
||||
if (nx > bv->workWidth())
|
||||
break;
|
||||
if (tabular.isPartOfMultiColumn(i, j))
|
||||
continue;
|
||||
if (first_visible_cell < 0)
|
||||
first_visible_cell = idx;
|
||||
if (bv->cursor().selection())
|
||||
drawCellSelection(pi, nx, y, i, j, idx);
|
||||
|
||||
int const cx = nx + tabular.getBeginningOfTextInCell(idx);
|
||||
cell(idx)->draw(pi, cx, y);
|
||||
drawCellLines(pi.pain, nx, y, i, idx);
|
||||
if (nx + tabular.getWidthOfColumn(idx) < 0
|
||||
|| nx > bv->workWidth()
|
||||
|| y - a > bv->workHeight()) {
|
||||
cell(idx)->draw(nullpi, cx, y);
|
||||
drawCellLines(nop, nx, y, i, idx);
|
||||
} else {
|
||||
cell(idx)->draw(pi, cx, y);
|
||||
drawCellLines(pi.pain, nx, y, i, idx);
|
||||
}
|
||||
nx += tabular.getWidthOfColumn(idx);
|
||||
++idx;
|
||||
}
|
||||
|
||||
// Would be nice, but for some completely unfathomable reason,
|
||||
// on a col resize to a new fixed width, even though the insettexts
|
||||
// are resized, the cell isn't, but drawing all cells in a tall table
|
||||
// has the desired effect somehow. Complete dark magic.
|
||||
#if 0
|
||||
// avoiding drawing the rest of a long table is
|
||||
// a pretty big speedup
|
||||
if (y > bv->workHeight())
|
||||
break;
|
||||
#endif
|
||||
if (i + 1 < tabular.rows())
|
||||
y += d + tabular.getAscentOfRow(i + 1) +
|
||||
tabular.getAdditionalHeight(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
y += tabular.getDescentOfRow(i) +
|
||||
tabular.getAscentOfRow(i + 1) +
|
||||
tabular.getAdditionalHeight(i + 1);
|
||||
|
||||
void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
LCursor & cur = pi.base.bv->cursor();
|
||||
if (!cur.selection())
|
||||
return;
|
||||
if (!ptr_cmp(&cur.inset(), this))
|
||||
return;
|
||||
|
||||
x += scroll();
|
||||
x += ADD_TO_TABULAR_WIDTH;
|
||||
|
||||
if (tablemode(cur)) {
|
||||
int rs, re, cs, ce;
|
||||
getSelection(cur, rs, re, cs, ce);
|
||||
for (int j = 0; j < tabular.rows(); ++j) {
|
||||
int const a = tabular.getAscentOfRow(j);
|
||||
int const h = a + tabular.getDescentOfRow(j);
|
||||
int xx = x;
|
||||
y += tabular.getAdditionalHeight(j);
|
||||
for (int i = 0; i < tabular.columns(); ++i) {
|
||||
if (tabular.isPartOfMultiColumn(j, i))
|
||||
continue;
|
||||
int const cell = tabular.getCellNumber(j, i);
|
||||
int const w = tabular.getWidthOfColumn(cell);
|
||||
if (i >= cs && i <= ce && j >= rs && j <= re)
|
||||
pi.pain.fillRectangle(xx, y - a, w, h,
|
||||
LColor::selection);
|
||||
xx += w;
|
||||
|
||||
}
|
||||
y += h;
|
||||
}
|
||||
|
||||
} else {
|
||||
cur.text()->drawSelection(pi, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,24 +387,6 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
|
||||
}
|
||||
|
||||
|
||||
void InsetTabular::drawCellSelection(PainterInfo & pi, int x, int y,
|
||||
int row, int column, int cell) const
|
||||
{
|
||||
LCursor & cur = pi.base.bv->cursor();
|
||||
BOOST_ASSERT(cur.selection());
|
||||
if (tablemode(cur)) {
|
||||
int rs, re, cs, ce;
|
||||
getSelection(cur, rs, re, cs, ce);
|
||||
if (column >= cs && column <= ce && row >= rs && row <= re) {
|
||||
int w = tabular.getWidthOfColumn(cell);
|
||||
int h = tabular.getAscentOfRow(row) + tabular.getDescentOfRow(row)-1;
|
||||
pi.pain.fillRectangle(x, y - tabular.getAscentOfRow(row) + 1,
|
||||
w, h, LColor::selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string const InsetTabular::editMessage() const
|
||||
{
|
||||
return _("Opened table");
|
||||
@ -446,7 +466,8 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
setPos(cur, cmd.x, cmd.y);
|
||||
bvcur.setCursor(cur);
|
||||
bvcur.selection() = true;
|
||||
}
|
||||
} else
|
||||
cur.undispatched();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -513,6 +534,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
if (sl == cur.top()) {
|
||||
cmd = FuncRequest(LFUN_FINISHED_DOWN);
|
||||
cur.undispatched();
|
||||
resetPos(cur);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -530,45 +552,46 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
|
||||
if (sl == cur.top()) {
|
||||
cmd = FuncRequest(LFUN_FINISHED_UP);
|
||||
cur.undispatched();
|
||||
resetPos(cur);
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_NEXT: {
|
||||
//if (hasSelection())
|
||||
// cur.selection() = false;
|
||||
int const col = tabular.column_of_cell(cur.idx());
|
||||
int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
|
||||
if (t < yo() + tabular.getHeightOfTabular()) {
|
||||
cur.bv().scrollDocView(t);
|
||||
cur.idx() = tabular.getCellBelow(first_visible_cell) + col;
|
||||
} else {
|
||||
cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col;
|
||||
}
|
||||
cur.pit() = 0;
|
||||
cur.pos() = 0;
|
||||
resetPos(cur);
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_PRIOR: {
|
||||
//if (hasSelection())
|
||||
// cur.selection() = false;
|
||||
int const col = tabular.column_of_cell(cur.idx());
|
||||
int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
|
||||
if (yo() < 0) {
|
||||
cur.bv().scrollDocView(t);
|
||||
if (yo() > 0)
|
||||
cur.idx() = col;
|
||||
else
|
||||
cur.idx() = tabular.getCellBelow(first_visible_cell) + col;
|
||||
} else {
|
||||
cur.idx() = col;
|
||||
}
|
||||
cur.pit() = cur.lastpit();
|
||||
cur.pos() = cur.lastpos();
|
||||
resetPos(cur);
|
||||
break;
|
||||
}
|
||||
// case LFUN_NEXT: {
|
||||
// //if (hasSelection())
|
||||
// // cur.selection() = false;
|
||||
// int const col = tabular.column_of_cell(cur.idx());
|
||||
// int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
|
||||
// if (t < yo() + tabular.getHeightOfTabular()) {
|
||||
// cur.bv().scrollDocView(t);
|
||||
// cur.idx() = tabular.getCellBelow(first_visible_cell) + col;
|
||||
// } else {
|
||||
// cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col;
|
||||
// }
|
||||
// cur.par() = 0;
|
||||
// cur.pos() = 0;
|
||||
// resetPos(cur);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// case LFUN_PRIOR: {
|
||||
// //if (hasSelection())
|
||||
// // cur.selection() = false;
|
||||
// int const col = tabular.column_of_cell(cur.idx());
|
||||
// int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
|
||||
// if (yo() < 0) {
|
||||
// cur.bv().scrollDocView(t);
|
||||
// if (yo() > 0)
|
||||
// cur.idx() = col;
|
||||
// else
|
||||
// cur.idx() = tabular.getCellBelow(first_visible_cell) + col;
|
||||
// } else {
|
||||
// cur.idx() = col;
|
||||
// }
|
||||
// cur.par() = cur.lastpar();
|
||||
// cur.pos() = cur.lastpos();
|
||||
// resetPos(cur);
|
||||
// break;
|
||||
// }
|
||||
|
||||
case LFUN_LAYOUT_TABULAR:
|
||||
InsetTabularMailer(*this).showDialog(&cur.bv());
|
||||
@ -955,28 +978,86 @@ shared_ptr<InsetText> InsetTabular::cell(int idx)
|
||||
}
|
||||
|
||||
|
||||
void InsetTabular::getCursorPos(LCursor const & cur, int & x, int & y) const
|
||||
void InsetTabular::getCursorPos(CursorSlice const & sl, int & x, int & y) const
|
||||
{
|
||||
cell(cur.idx())->getCursorPos(cur, x, y);
|
||||
cell(sl.idx())->getCursorPos(sl, x, y);
|
||||
|
||||
// y offset correction
|
||||
int const row = tabular.row_of_cell(sl.idx());
|
||||
for (int i = 0; i <= row; ++i) {
|
||||
if (i != 0) {
|
||||
y += tabular.getAscentOfRow(i);
|
||||
y += tabular.getAdditionalHeight(i);
|
||||
}
|
||||
if (i != row)
|
||||
y += tabular.getDescentOfRow(i);
|
||||
}
|
||||
|
||||
// x offset correction
|
||||
int const col = tabular.column_of_cell(sl.idx());
|
||||
int idx = tabular.getCellNumber(row, 0);
|
||||
for (int j = 0; j < col; ++j) {
|
||||
if (tabular.isPartOfMultiColumn(row, j))
|
||||
continue;
|
||||
x += tabular.getWidthOfColumn(idx);
|
||||
++idx;
|
||||
}
|
||||
x += tabular.getBeginningOfTextInCell(idx);
|
||||
x += ADD_TO_TABULAR_WIDTH;
|
||||
x += scroll();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// Manhattan distance to nearest corner
|
||||
int dist(InsetOld const & inset, int x, int y)
|
||||
{
|
||||
int xx = 0;
|
||||
int yy = 0;
|
||||
Point o = theCoords.insets_.xy(&inset);
|
||||
int const xo = o.x_;
|
||||
int const yo = o.y_;
|
||||
|
||||
if (x < xo)
|
||||
xx = xo - x;
|
||||
else if (x > xo + inset.width())
|
||||
xx = x - xo - inset.width();
|
||||
|
||||
if (y < yo - inset.ascent())
|
||||
yy = yo - inset.ascent() - y;
|
||||
else if (y > yo + inset.descent())
|
||||
yy = y - yo - inset.descent();
|
||||
|
||||
lyxerr << " xo_=" << xo << " yo_=" << yo
|
||||
<< " width_=" << inset.width() << " ascent=" << inset.ascent()
|
||||
<< " descent=" << inset.descent()
|
||||
<< " dist=" << xx + yy << endl;
|
||||
return xx + yy;
|
||||
}
|
||||
|
||||
|
||||
} //namespace anon
|
||||
|
||||
|
||||
InsetBase * InsetTabular::setPos(LCursor & cur, int x, int y) const
|
||||
{
|
||||
lyxerr << "# InsetTabular::setPos() x=" << x << " y=" << y << endl;
|
||||
int idx_min = 0;
|
||||
int dist_min = 1000000;
|
||||
int dist_min = std::numeric_limits<int>::max();
|
||||
for (idx_type i = 0; i < nargs(); ++i) {
|
||||
int d = getText(i)->dist(x, y);
|
||||
if (d < dist_min) {
|
||||
dist_min = d;
|
||||
idx_min = i;
|
||||
if (theCoords.insets_.has(tabular.getCellInset(i).get())) {
|
||||
int d = dist(*tabular.getCellInset(i), x, y);
|
||||
if (d < dist_min) {
|
||||
dist_min = d;
|
||||
idx_min = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur.idx() = idx_min;
|
||||
InsetBase * inset = cell(cur.idx())->text_.editXY(cur, x, y);
|
||||
//lyxerr << "# InsetTabular::setPos()\n" << cur << endl;
|
||||
return inset;
|
||||
return cell(cur.idx())->text_.editXY(cur, x, y);
|
||||
}
|
||||
|
||||
|
||||
@ -996,28 +1077,49 @@ int InsetTabular::getCellXPos(int const cell) const
|
||||
|
||||
void InsetTabular::resetPos(LCursor & cur) const
|
||||
{
|
||||
|
||||
|
||||
BufferView & bv = cur.bv();
|
||||
int const actcol = tabular.column_of_cell(cur.idx());
|
||||
int const offset = ADD_TO_TABULAR_WIDTH + 2;
|
||||
int const new_x = getCellXPos(cur.idx()) + offset;
|
||||
int const old_x = cursorx_;
|
||||
int const col_width = tabular.getWidthOfColumn(cur.idx());
|
||||
cursorx_ = new_x;
|
||||
|
||||
// int const actcol = tabular.column_of_cell(cur.idx());
|
||||
// int const offset = ADD_TO_TABULAR_WIDTH + 2;
|
||||
// int const new_x = getCellXPos(cur.idx()) + offset;
|
||||
// int const old_x = cursorx_;
|
||||
// int const col_width = tabular.getWidthOfColumn(cur.idx());
|
||||
// cursorx_ = new_x;
|
||||
// cursor.x(getCellXPos(cur.idx()) + offset);
|
||||
if (actcol < tabular.columns() - 1 && scroll(false) &&
|
||||
tabular.getWidthOfTabular() < bv.workWidth()-20)
|
||||
{
|
||||
scroll(bv, 0.0F);
|
||||
} else if (cursorx_ - offset > 20 &&
|
||||
cursorx_ - offset + col_width > bv.workWidth() - 20) {
|
||||
scroll(bv, - col_width - 20);
|
||||
} else if (cursorx_ - offset < 20) {
|
||||
scroll(bv, 20 - cursorx_ + offset);
|
||||
} else if (scroll() && xo() > 20 &&
|
||||
xo() + tabular.getWidthOfTabular() > bv.workWidth() - 20) {
|
||||
scroll(bv, old_x - cursorx_);
|
||||
// if (actcol < tabular.columns() - 1 && scroll(false) &&
|
||||
// tabular.getWidthOfTabular() < bv.workWidth()-20)
|
||||
// {
|
||||
// scroll(bv, 0.0F);
|
||||
// } else if (cursorx_ - offset > 20 &&
|
||||
// cursorx_ - offset + col_width > bv.workWidth() - 20) {
|
||||
// scroll(bv, - col_width - 20);
|
||||
// } else if (cursorx_ - offset < 20) {
|
||||
// scroll(bv, 20 - cursorx_ + offset);
|
||||
// } else if (scroll() && xo() > 20 &&
|
||||
// xo() + tabular.getWidthOfTabular() > bv.workWidth() - 20) {
|
||||
// scroll(bv, old_x - cursorx_);
|
||||
// }
|
||||
|
||||
if (&cur.inset() != this) {
|
||||
scroll(bv, 0);
|
||||
} else {
|
||||
int const X1 = 0;
|
||||
int const X2 = bv.workWidth();
|
||||
int const offset = ADD_TO_TABULAR_WIDTH + 2;
|
||||
int const col_width = tabular.getWidthOfColumn(cur.idx());
|
||||
int const x1 = getCellXPos(cur.idx()) + offset + scroll();
|
||||
int const x2 = x1 + col_width;
|
||||
|
||||
if (x1 < X1 + 20)
|
||||
scroll(bv, X1 + 20 - x1);
|
||||
else if (x2 > X2 - 20)
|
||||
scroll(bv, X2 - 20 - x2);
|
||||
}
|
||||
|
||||
cur.needsUpdate();
|
||||
|
||||
InsetTabularMailer(*this).updateDialog(&bv);
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,8 @@ public:
|
||||
///
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
void drawSelection(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
std::string const editMessage() const;
|
||||
///
|
||||
bool insetAllowed(InsetBase::Code) const { return true; }
|
||||
@ -87,8 +89,8 @@ public:
|
||||
void validate(LaTeXFeatures & features) const;
|
||||
///
|
||||
Code lyxCode() const { return InsetBase::TABULAR_CODE; }
|
||||
/// get the absolute screen x,y of the cursor
|
||||
void getCursorPos(LCursor const & cur, int & x, int & y) const;
|
||||
/// get offset of this cursor slice relative to our upper left corner
|
||||
void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
|
||||
///
|
||||
bool tabularFeatures(LCursor & cur, std::string const & what);
|
||||
///
|
||||
@ -147,11 +149,7 @@ private:
|
||||
virtual std::auto_ptr<InsetBase> doClone() const;
|
||||
|
||||
///
|
||||
void drawCellLines(Painter &, int x, int baseline,
|
||||
int row, int cell) const;
|
||||
///
|
||||
void drawCellSelection(PainterInfo &, int x, int baseline,
|
||||
int row, int column, int cell) const;
|
||||
void drawCellLines(Painter &, int x, int y, int row, int cell) const;
|
||||
///
|
||||
InsetBase * setPos(LCursor & cur, int x, int y) const;
|
||||
|
||||
|
@ -102,7 +102,7 @@ void InsetText::init()
|
||||
{
|
||||
for_each(paragraphs().begin(), paragraphs().end(),
|
||||
bind(&Paragraph::setInsetOwner, _1, this));
|
||||
old_par = -1;
|
||||
old_pit = -1;
|
||||
}
|
||||
|
||||
|
||||
@ -160,7 +160,7 @@ void InsetText::read(Buffer const & buf, LyXLex & lex)
|
||||
}
|
||||
|
||||
// sanity check
|
||||
// ensure we have at least one par.
|
||||
// ensure we have at least one paragraph.
|
||||
if (paragraphs().empty())
|
||||
paragraphs().push_back(oldpar);
|
||||
}
|
||||
@ -170,16 +170,16 @@ void InsetText::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
//lyxerr << "InsetText::metrics: width: " << mi.base.textwidth << endl;
|
||||
setViewCache(mi.base.bv);
|
||||
text_.metrics(mi, dim);
|
||||
dim_ = dim;
|
||||
font_ = mi.base.font;
|
||||
text_.font_ = mi.base.font;
|
||||
text_.metrics(mi, dim);
|
||||
dim_ = dim;
|
||||
}
|
||||
|
||||
|
||||
void InsetText::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
BOOST_ASSERT(!text_.paragraphs().begin()->rows.empty());
|
||||
BOOST_ASSERT(!text_.paragraphs().front().rows().empty());
|
||||
// update our idea of where we are
|
||||
setPosCache(pi, x, y);
|
||||
|
||||
@ -187,13 +187,10 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
|
||||
bv->hideCursor();
|
||||
|
||||
x += scroll();
|
||||
y -= text_.ascent();
|
||||
//y -= text_.ascent();
|
||||
|
||||
// repaint the background if needed
|
||||
if (backgroundColor() != LColor::background)
|
||||
clearInset(pi.pain, x, y);
|
||||
|
||||
text_.draw(pi, x, y + bv->top_y());
|
||||
text_.draw(pi, x, y);
|
||||
|
||||
if (drawFrame_)
|
||||
drawFrame(pi.pain, x, y);
|
||||
@ -202,15 +199,19 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
|
||||
|
||||
void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
// repaint the background if needed
|
||||
if (backgroundColor() != LColor::background)
|
||||
clearInset(pi.pain, x, y);
|
||||
text_.drawSelection(pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
void InsetText::drawFrame(Painter & pain, int x, int y) const
|
||||
{
|
||||
int const w = text_.width();
|
||||
int const w = max(1, text_.width());
|
||||
int const h = text_.height();
|
||||
pain.rectangle(x, y, w, h, frameColor());
|
||||
int const a = text_.ascent();
|
||||
pain.rectangle(x, y - a, w, h, frameColor());
|
||||
}
|
||||
|
||||
|
||||
@ -218,14 +219,15 @@ void InsetText::clearInset(Painter & pain, int x, int y) const
|
||||
{
|
||||
int const w = text_.width();
|
||||
int const h = text_.height();
|
||||
pain.fillRectangle(x, y, w, h, backgroundColor());
|
||||
int const a = text_.ascent();
|
||||
pain.fillRectangle(x, y - a, w, h, backgroundColor());
|
||||
}
|
||||
|
||||
|
||||
void InsetText::updateLocal(LCursor & cur)
|
||||
{
|
||||
if (!autoBreakRows_ && paragraphs().size() > 1) {
|
||||
// collapseParagraphs
|
||||
// collapse paragraphs
|
||||
while (paragraphs().size() > 1) {
|
||||
ParagraphList::iterator const first = paragraphs().begin();
|
||||
ParagraphList::iterator second = first;
|
||||
@ -250,9 +252,9 @@ void InsetText::updateLocal(LCursor & cur)
|
||||
lv->view_state_changed();
|
||||
lv->updateMenubar();
|
||||
lv->updateToolbars();
|
||||
if (old_par != cur.pit()) {
|
||||
if (old_pit != cur.pit()) {
|
||||
lv->setLayout(text_.getPar(cur.pit()).layout()->name());
|
||||
old_par = cur.pit();
|
||||
old_pit = cur.pit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,11 +268,11 @@ string const InsetText::editMessage() const
|
||||
void InsetText::edit(LCursor & cur, bool left)
|
||||
{
|
||||
//lyxerr << "InsetText: edit left/right" << endl;
|
||||
old_par = -1;
|
||||
old_pit = -1;
|
||||
setViewCache(&cur.bv());
|
||||
int const par = left ? 0 : paragraphs().size() - 1;
|
||||
int const pit = left ? 0 : paragraphs().size() - 1;
|
||||
int const pos = left ? 0 : paragraphs().back().size();
|
||||
text_.setCursor(cur.top(), par, pos);
|
||||
text_.setCursor(cur.top(), pit, pos);
|
||||
cur.clearSelection();
|
||||
finishUndo();
|
||||
#ifdef WITH_WARNINGS
|
||||
@ -283,7 +285,7 @@ void InsetText::edit(LCursor & cur, bool left)
|
||||
|
||||
InsetBase * InsetText::editXY(LCursor & cur, int x, int y) const
|
||||
{
|
||||
old_par = -1;
|
||||
old_pit = -1;
|
||||
return text_.editXY(cur, x, y);
|
||||
//sanitizeEmptyText(cur.bv());
|
||||
//updateLocal(cur);
|
||||
@ -354,10 +356,10 @@ void InsetText::validate(LaTeXFeatures & features) const
|
||||
}
|
||||
|
||||
|
||||
void InsetText::getCursorPos(LCursor const & cur, int & x, int & y) const
|
||||
void InsetText::getCursorPos(CursorSlice const & sl, int & x, int & y) const
|
||||
{
|
||||
x = text_.cursorX(cur.top());
|
||||
y = text_.cursorY(cur.top());
|
||||
x = text_.cursorX(sl);
|
||||
y = text_.cursorY(sl);
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,10 +72,11 @@ public:
|
||||
OutputParams const &) const;
|
||||
///
|
||||
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;
|
||||
///
|
||||
Code lyxCode() const { return TEXT_CODE; }
|
||||
/// FIXME, document
|
||||
void getCursorPos(LCursor const & cur, int & x, int & y) const;
|
||||
///
|
||||
void setFont(BufferView *, LyXFont const &,
|
||||
bool toggleall = false,
|
||||
@ -165,7 +166,7 @@ private:
|
||||
*/
|
||||
int frame_color_;
|
||||
///
|
||||
mutable lyx::pit_type old_par;
|
||||
mutable lyx::pit_type old_pit;
|
||||
public:
|
||||
///
|
||||
mutable LyXText text_;
|
||||
|
@ -366,8 +366,6 @@ bool findNextChange(BufferView * bv)
|
||||
// if we used a lfun like in find/replace, dispatch would do
|
||||
// that for us
|
||||
bv->update();
|
||||
if (bv->fitCursor())
|
||||
bv->update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -601,6 +601,7 @@ void loadTextclass(string const & name)
|
||||
|
||||
void LyXFunc::dispatch(FuncRequest const & cmd)
|
||||
{
|
||||
BOOST_ASSERT(view());
|
||||
string const argument = cmd.argument;
|
||||
kb_action const action = cmd.action;
|
||||
|
||||
@ -1450,7 +1451,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
|
||||
update |= view()->cursor().result().update();
|
||||
else
|
||||
update |= view()->dispatch(cmd);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1459,14 +1459,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
|
||||
// Redraw screen unless explicitly told otherwise.
|
||||
// This also initializes the position cache for all insets
|
||||
// in (at least partially) visible top-level paragraphs.
|
||||
if (update)
|
||||
view()->update();
|
||||
view()->update(true, update);
|
||||
|
||||
// fitCursor() needs valid inset position. The previous call to
|
||||
// update() makes sure we have such even for freshly created
|
||||
// insets.
|
||||
if (view()->fitCursor())
|
||||
view()->update();
|
||||
// if we executed a mutating lfun, mark the buffer as dirty
|
||||
if (getStatus(cmd).enabled()
|
||||
&& !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)
|
||||
|
61
src/lyxrow.C
61
src/lyxrow.C
@ -22,19 +22,18 @@
|
||||
using lyx::pos_type;
|
||||
|
||||
|
||||
RowMetrics::RowMetrics() : separator(0), hfill(0), label_hfill(0), x(0)
|
||||
RowMetrics::RowMetrics()
|
||||
: separator(0), hfill(0), label_hfill(0), x(0)
|
||||
{}
|
||||
|
||||
|
||||
Row::Row()
|
||||
: pos_(0), end_(0), height_(0), width_(0), y_offset_(0),
|
||||
ascent_of_text_(0), baseline_(0)
|
||||
: pos_(0), end_(0), ascent_(0), descent_(0), width_(0)
|
||||
{}
|
||||
|
||||
|
||||
Row::Row(pos_type pos)
|
||||
: pos_(pos), end_(0), height_(0), width_(0), y_offset_(0),
|
||||
ascent_of_text_(0), baseline_(0)
|
||||
: pos_(pos), end_(0), ascent_(0), descent_(0), width_(0)
|
||||
{}
|
||||
|
||||
|
||||
@ -62,65 +61,35 @@ pos_type Row::endpos() const
|
||||
}
|
||||
|
||||
|
||||
void Row::width(unsigned int w)
|
||||
void Row::width(int w)
|
||||
{
|
||||
width_ = w;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Row::width() const
|
||||
int Row::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
|
||||
void Row::ascent_of_text(unsigned int a)
|
||||
void Row::ascent(int b)
|
||||
{
|
||||
ascent_of_text_ = a;
|
||||
ascent_ = b;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Row::ascent_of_text() const
|
||||
int Row::ascent() const
|
||||
{
|
||||
return ascent_of_text_;
|
||||
}
|
||||
|
||||
|
||||
void Row::top_of_text(unsigned int top)
|
||||
{
|
||||
top_of_text_ = top;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Row::top_of_text() const
|
||||
{
|
||||
return top_of_text_;
|
||||
}
|
||||
|
||||
|
||||
void Row::baseline(unsigned int b)
|
||||
{
|
||||
baseline_ = b;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Row::baseline() const
|
||||
{
|
||||
return baseline_;
|
||||
}
|
||||
|
||||
|
||||
bool Row::isParStart() const
|
||||
{
|
||||
return !pos();
|
||||
return ascent_;
|
||||
}
|
||||
|
||||
|
||||
void Row::dump(const char * s) const
|
||||
{
|
||||
lyxerr << s << " pos: " << pos_ << " width: " << width_
|
||||
<< " height: " << height_
|
||||
<< " ascent_of_text: " << ascent_of_text_
|
||||
<< " top_of_text: " << top_of_text_
|
||||
<< " y_offset: " << y_offset_ << std::endl;
|
||||
lyxerr << s << " pos: " << pos_ << " end: " << end_
|
||||
<< " width: " << width_
|
||||
<< " ascent: " << ascent_
|
||||
<< " descent: " << descent_
|
||||
<< std::endl;
|
||||
}
|
||||
|
38
src/lyxrow.h
38
src/lyxrow.h
@ -33,31 +33,19 @@ public:
|
||||
///
|
||||
lyx::pos_type endpos() const;
|
||||
///
|
||||
void height(unsigned int h) { height_ = h; }
|
||||
int height() const { return ascent_ + descent_; }
|
||||
///
|
||||
unsigned int height() const { return height_; }
|
||||
void width(int w);
|
||||
///
|
||||
void width(unsigned int w);
|
||||
int width() const;
|
||||
///
|
||||
unsigned int width() const;
|
||||
void ascent(int b);
|
||||
///
|
||||
void ascent_of_text(unsigned int a);
|
||||
int ascent() const;
|
||||
///
|
||||
unsigned int ascent_of_text() const;
|
||||
void descent(int b) { descent_ = b; }
|
||||
///
|
||||
void top_of_text(unsigned int top);
|
||||
///
|
||||
unsigned int top_of_text() const;
|
||||
///
|
||||
void baseline(unsigned int b);
|
||||
///
|
||||
unsigned int baseline() const;
|
||||
/// return true if this row is the start of a paragraph
|
||||
bool isParStart() const;
|
||||
/// return the cached y position
|
||||
unsigned int y_offset() const { return y_offset_; }
|
||||
/// cache the y position
|
||||
void y_offset(unsigned int newy) { y_offset_ = newy; }
|
||||
int descent() const { return descent_; }
|
||||
/// current debugging only
|
||||
void dump(const char * = "") const;
|
||||
|
||||
@ -67,17 +55,11 @@ private:
|
||||
/// one behind last pos covered by this row
|
||||
lyx::pos_type end_;
|
||||
///
|
||||
unsigned int height_;
|
||||
int ascent_;
|
||||
///
|
||||
unsigned int width_;
|
||||
/// cached y position
|
||||
unsigned int y_offset_;
|
||||
/// ascent from baseline including prelude space
|
||||
unsigned short ascent_of_text_;
|
||||
/// the top of the real text in the row
|
||||
unsigned int top_of_text_;
|
||||
int descent_;
|
||||
///
|
||||
unsigned int baseline_;
|
||||
int width_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "bufferview_funcs.h"
|
||||
#include "Bidi.h"
|
||||
#include "dispatchresult.h"
|
||||
#include "dimension.h"
|
||||
#include "lyxfont.h"
|
||||
#include "layout.h"
|
||||
#include "lyxlayout_ptr_fwd.h"
|
||||
@ -56,8 +57,6 @@ public:
|
||||
///
|
||||
void init(BufferView *);
|
||||
|
||||
/// update y coordinate cache of all paragraphs
|
||||
void updateParPositions();
|
||||
///
|
||||
LyXFont getFont(Paragraph const & par, pos_type pos) const;
|
||||
///
|
||||
@ -93,12 +92,8 @@ public:
|
||||
/// Set font over selection paragraphs and rebreak.
|
||||
void setFont(LCursor & cur, LyXFont const &, bool toggleall = false);
|
||||
|
||||
/// rebreaks all paragaphs between the given pars.
|
||||
void redoParagraphs(pit_type begin, pit_type end);
|
||||
/// rebreaks the given par
|
||||
void redoParagraph(pit_type pit);
|
||||
/// rebreaks the cursor par
|
||||
void redoParagraph(LCursor & cur);
|
||||
|
||||
/// returns pos in given par at given x coord
|
||||
pos_type x2pos(pit_type pit, int row, int x) const;
|
||||
@ -115,17 +110,12 @@ public:
|
||||
/// insert an inset at cursor position
|
||||
void insertInset(LCursor & cur, InsetBase * inset);
|
||||
|
||||
/// a full rebreak of the whole text
|
||||
void fullRebreak();
|
||||
/// compute text metrics
|
||||
void metrics(MetricsInfo & mi, Dimension & dim);
|
||||
/// draw text (only used for insets)
|
||||
void draw(PainterInfo & pi, int x, int y) const;
|
||||
/// draw textselection
|
||||
void drawSelection(PainterInfo & pi, int x, int y) 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;
|
||||
|
||||
/// try to handle that request
|
||||
void dispatch(LCursor & cur, FuncRequest & cmd);
|
||||
@ -143,11 +133,11 @@ public:
|
||||
// Returns the current font and depth as a message.
|
||||
std::string LyXText::currentState(LCursor & cur);
|
||||
|
||||
/** returns an iterator pointing to the row near the specified
|
||||
* y-coordinate (relative to the whole text). y is set to the
|
||||
* real beginning of this row
|
||||
/** returns row near the specified
|
||||
* y-coordinate in given paragraph (relative to the screen).
|
||||
*/
|
||||
Row const & getRowNearY(int y, pit_type & pit) const;
|
||||
Row const & getRowNearY(int y, pit_type pit) const;
|
||||
pit_type getPitNearY(int y) const;
|
||||
|
||||
/** returns the column near the specified x-coordinate of the row
|
||||
x is set to the real beginning of this column
|
||||
@ -339,11 +329,9 @@ public:
|
||||
|
||||
public:
|
||||
///
|
||||
unsigned int width_;
|
||||
Dimension dim_;
|
||||
///
|
||||
int maxwidth_;
|
||||
///
|
||||
int height_;
|
||||
/// the current font settings
|
||||
LyXFont current_font;
|
||||
/// the current font
|
||||
@ -361,10 +349,6 @@ public:
|
||||
///
|
||||
ParagraphList pars_;
|
||||
|
||||
/// absolute document pixel coordinates of this LyXText
|
||||
mutable int xo_;
|
||||
mutable int yo_;
|
||||
|
||||
/// our 'outermost' Font
|
||||
LyXFont font_;
|
||||
|
||||
@ -373,8 +357,6 @@ private:
|
||||
/// change on pit
|
||||
pit_type undoSpan(pit_type pit);
|
||||
|
||||
/// rebreaks the given par
|
||||
void redoParagraphInternal(pit_type pit);
|
||||
/// used in setlayout
|
||||
void makeFontEntriesLayoutSpecific(BufferParams const &, Paragraph & par);
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
|
||||
2004-11-26 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
* math_nestinset.C (getCursorPos): implement.
|
||||
|
||||
2004-11-26 Georg Baum <Georg.Baum@post.rwth-aachen.de>
|
||||
|
||||
* math_hullinset.C (getStatus): add status messages
|
||||
|
@ -153,6 +153,3 @@ libmathed_la_SOURCES = \
|
||||
command_inset.C \
|
||||
ref_inset.h \
|
||||
ref_inset.C
|
||||
|
||||
# math_tfracinset.C
|
||||
# math_tfracinset.h
|
||||
|
@ -56,7 +56,7 @@ void MathMBoxInset::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
|
||||
void MathMBoxInset::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
text_.draw(pi, x + 1, y - text_.ascent());
|
||||
text_.draw(pi, x + 1, y);
|
||||
drawMarkers(pi, x, y);
|
||||
}
|
||||
|
||||
@ -102,8 +102,15 @@ LyXText * MathMBoxInset::getText(int) const
|
||||
}
|
||||
|
||||
|
||||
void MathMBoxInset::getCursorPos(LCursor const & cur, int & x, int & y) const
|
||||
void MathMBoxInset::getCursorPos(CursorSlice const & sl, int & x, int & y) const
|
||||
{
|
||||
x = text_.cursorX(cur.top());
|
||||
y = text_.cursorY(cur.top());
|
||||
x = text_.cursorX(sl);
|
||||
y = text_.cursorY(sl);
|
||||
}
|
||||
|
||||
|
||||
void MathMBoxInset::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
text_.drawSelection(pi, x, y);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ public:
|
||||
/// draw according to cached metrics
|
||||
void draw(PainterInfo &, int x, int y) const;
|
||||
///
|
||||
void drawSelection(PainterInfo & pi, int x, int y) const;
|
||||
///
|
||||
bool inMathed() const { return false; }
|
||||
///
|
||||
bool isActive() const { return true; }
|
||||
@ -39,7 +41,7 @@ public:
|
||||
///
|
||||
LyXText * getText(int) const;
|
||||
///
|
||||
void getCursorPos(LCursor const & cur, int & x, int & y) const;
|
||||
void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
|
||||
protected:
|
||||
virtual void doDispatch(LCursor & cur, FuncRequest & cmd);
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "FuncStatus.h"
|
||||
#include "LColor.h"
|
||||
#include "bufferview_funcs.h"
|
||||
#include "coordcache.h"
|
||||
#include "cursor.h"
|
||||
#include "debug.h"
|
||||
#include "dispatchresult.h"
|
||||
@ -97,22 +98,51 @@ MathArray const & MathNestInset::cell(idx_type i) const
|
||||
}
|
||||
|
||||
|
||||
void MathNestInset::getCursorPos(LCursor const & cur, int & x, int & y) const
|
||||
void MathNestInset::getCursorPos(CursorSlice const & sl,
|
||||
int & x, int & y) const
|
||||
{
|
||||
BOOST_ASSERT(ptr_cmp(&cur.inset(), this));
|
||||
MathArray const & ar = cur.cell();
|
||||
x = ar.xo() + ar.pos2x(cur.pos());
|
||||
y = ar.yo() + cur.bv().top_y();
|
||||
// FIXME: This is a hack. Ideally, the coord cache should not store
|
||||
// absolute positions, but relative ones. This would mean to call
|
||||
// setXY() not in MathArray::draw(), but in the parent insets' draw()
|
||||
// with the correctly adjusted x,y values. But this means that we'd have
|
||||
// to touch all (math)inset's draw() methods. Right now, we'll store
|
||||
// absolute value, and make them here relative, only to make them
|
||||
// absolute again when actually drawing the cursor. What a mess.
|
||||
BOOST_ASSERT(ptr_cmp(&sl.inset(), this));
|
||||
MathArray const & ar = sl.cell();
|
||||
if (!theCoords.arrays_.has(&ar)) {
|
||||
// this can (semi-)legally happen if we jsut created this cell
|
||||
// and it never has been drawn before. So don't ASSERT.
|
||||
//lyxerr << "no cached data for array " << &ar << endl;
|
||||
x = 0;
|
||||
y = 0;
|
||||
return;
|
||||
}
|
||||
Point const pt = theCoords.arrays_.xy(&ar);
|
||||
if (!theCoords.insets_.has(this)) {
|
||||
// same as above
|
||||
//lyxerr << "no cached data for inset " << this << endl;
|
||||
x = 0;
|
||||
y = 0;
|
||||
return;
|
||||
}
|
||||
Point const pt2 = theCoords.insets_.xy(this);
|
||||
//lyxerr << "retrieving position cache for MathArray "
|
||||
// << pt.x_ << ' ' << pt.y_ << std::endl;
|
||||
x = pt.x_ - pt2.x_ + ar.pos2x(sl.pos());
|
||||
y = pt.y_ - pt2.y_;
|
||||
// lyxerr << "pt.y_ : " << pt.y_ << " pt2_.y_ : " << pt2.y_
|
||||
// << " asc: " << ascent() << " des: " << descent()
|
||||
// << " ar.asc: " << ar.ascent() << " ar.des: " << ar.descent() << endl;
|
||||
// move cursor visually into empty cells ("blue rectangles");
|
||||
if (cur.cell().empty())
|
||||
if (ar.empty())
|
||||
x += 2;
|
||||
}
|
||||
|
||||
|
||||
void MathNestInset::metrics(MetricsInfo const & mi) const
|
||||
{
|
||||
MetricsInfo m = mi;
|
||||
for (idx_type i = 0; i < nargs(); ++i)
|
||||
for (idx_type i = 0, n = nargs(); i != n; ++i)
|
||||
cell(i).metrics(m);
|
||||
}
|
||||
|
||||
@ -179,7 +209,7 @@ void MathNestInset::dump() const
|
||||
os << "---------------------------------------------\n";
|
||||
write(os);
|
||||
os << "\n";
|
||||
for (idx_type i = 0; i < nargs(); ++i)
|
||||
for (idx_type i = 0, n = nargs(); i != n; ++i)
|
||||
os << cell(i) << "\n";
|
||||
os << "---------------------------------------------\n";
|
||||
}
|
||||
@ -207,6 +237,7 @@ void MathNestInset::drawSelection(PainterInfo & pi, int x, int y) const
|
||||
return;
|
||||
if (!ptr_cmp(&cur.inset(), this))
|
||||
return;
|
||||
|
||||
CursorSlice s1 = cur.selBegin();
|
||||
CursorSlice s2 = cur.selEnd();
|
||||
//lyxerr << "MathNestInset::drawing selection: "
|
||||
@ -936,7 +967,8 @@ void MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest & cmd)
|
||||
|
||||
bvcur.setCursor(cur);
|
||||
bvcur.selection() = true;
|
||||
}
|
||||
} else
|
||||
cur.undispatched();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
/// identifies NestInsets
|
||||
MathNestInset const * asNestInset() const { return this; }
|
||||
/// get cursor position
|
||||
void getCursorPos(LCursor const & cur, int & x, int & y) const;
|
||||
void getCursorPos(CursorSlice const & sl, int & x, int & y) const;
|
||||
///
|
||||
void edit(LCursor & cur, bool left);
|
||||
///
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define METRICSINFO_H
|
||||
|
||||
#include "lyxfont.h"
|
||||
#include "support/types.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -88,10 +89,20 @@ struct PainterInfo {
|
||||
bool ltr_pos;
|
||||
};
|
||||
|
||||
|
||||
struct TextMetricsInfo {};
|
||||
|
||||
|
||||
struct ViewMetricsInfo
|
||||
{
|
||||
ViewMetricsInfo(lyx::pit_type p1, lyx::pit_type p2,
|
||||
int y1, int y2) : p1(p1), p2(p2), y1(y1), y2(y2) {}
|
||||
lyx::pit_type p1;
|
||||
lyx::pit_type p2;
|
||||
int y1;
|
||||
int y2;
|
||||
};
|
||||
|
||||
|
||||
// Generic base for temporarily changing things.
|
||||
// The original state gets restored when the Changer is destructed.
|
||||
|
||||
|
@ -69,10 +69,8 @@ ParagraphList::ParagraphList()
|
||||
|
||||
|
||||
Paragraph::Paragraph()
|
||||
: y(0), height(0), begin_of_body_(0),
|
||||
pimpl_(new Paragraph::Pimpl(this))
|
||||
: begin_of_body_(0), pimpl_(new Paragraph::Pimpl(this))
|
||||
{
|
||||
//lyxerr << "sizeof Paragraph::Pimpl: " << sizeof(Paragraph::Pimpl) << endl;
|
||||
itemdepth = 0;
|
||||
params().clear();
|
||||
}
|
||||
@ -80,8 +78,8 @@ Paragraph::Paragraph()
|
||||
|
||||
Paragraph::Paragraph(Paragraph const & par)
|
||||
: itemdepth(par.itemdepth), insetlist(par.insetlist),
|
||||
rows(par.rows), y(par.y), height(par.height),
|
||||
width(par.width), layout_(par.layout_),
|
||||
dim_(par.dim_),
|
||||
rows_(par.rows_), layout_(par.layout_),
|
||||
text_(par.text_), begin_of_body_(par.begin_of_body_),
|
||||
pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
|
||||
{
|
||||
@ -105,10 +103,8 @@ Paragraph & Paragraph::operator=(Paragraph const & par)
|
||||
for (; it != end; ++it)
|
||||
it->inset = it->inset->clone().release();
|
||||
|
||||
rows = par.rows;
|
||||
y = par.y;
|
||||
height = par.height;
|
||||
width = par.width;
|
||||
rows_ = par.rows_;
|
||||
dim_ = par.dim_;
|
||||
layout_ = par.layout();
|
||||
text_ = par.text_;
|
||||
begin_of_body_ = par.begin_of_body_;
|
||||
@ -407,8 +403,8 @@ LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos,
|
||||
}
|
||||
|
||||
|
||||
LyXFont const Paragraph::getLabelFont(BufferParams const & bparams,
|
||||
LyXFont const & outerfont) const
|
||||
LyXFont const Paragraph::getLabelFont
|
||||
(BufferParams const & bparams, LyXFont const & outerfont) const
|
||||
{
|
||||
LyXFont tmpfont = layout()->labelfont;
|
||||
tmpfont.setLanguage(getParLanguage(bparams));
|
||||
@ -418,8 +414,8 @@ LyXFont const Paragraph::getLabelFont(BufferParams const & bparams,
|
||||
}
|
||||
|
||||
|
||||
LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams,
|
||||
LyXFont const & outerfont) const
|
||||
LyXFont const Paragraph::getLayoutFont
|
||||
(BufferParams const & bparams, LyXFont const & outerfont) const
|
||||
{
|
||||
LyXFont tmpfont = layout()->font;
|
||||
tmpfont.setLanguage(getParLanguage(bparams));
|
||||
@ -430,9 +426,8 @@ LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams,
|
||||
|
||||
|
||||
/// Returns the height of the highest font in range
|
||||
LyXFont_size
|
||||
Paragraph::highestFontInRange(pos_type startpos, pos_type endpos,
|
||||
LyXFont_size def_size) const
|
||||
LyXFont_size Paragraph::highestFontInRange
|
||||
(pos_type startpos, pos_type endpos, LyXFont_size def_size) const
|
||||
{
|
||||
if (pimpl_->fontlist.empty())
|
||||
return def_size;
|
||||
@ -1792,34 +1787,34 @@ bool Paragraph::allowEmpty() const
|
||||
}
|
||||
|
||||
|
||||
RowList::iterator Paragraph::getRow(pos_type pos)
|
||||
Row & Paragraph::getRow(pos_type pos)
|
||||
{
|
||||
RowList::iterator rit = rows.end();
|
||||
RowList::iterator const begin = rows.begin();
|
||||
RowList::iterator rit = rows_.end();
|
||||
RowList::iterator const begin = rows_.begin();
|
||||
|
||||
for (--rit; rit != begin && rit->pos() > pos; --rit)
|
||||
;
|
||||
|
||||
return rit;
|
||||
return *rit;
|
||||
}
|
||||
|
||||
|
||||
RowList::const_iterator Paragraph::getRow(pos_type pos) const
|
||||
Row const & Paragraph::getRow(pos_type pos) const
|
||||
{
|
||||
RowList::const_iterator rit = rows.end();
|
||||
RowList::const_iterator const begin = rows.begin();
|
||||
RowList::const_iterator rit = rows_.end();
|
||||
RowList::const_iterator const begin = rows_.begin();
|
||||
|
||||
for (--rit; rit != begin && rit->pos() > pos; --rit)
|
||||
;
|
||||
|
||||
return rit;
|
||||
return *rit;
|
||||
}
|
||||
|
||||
|
||||
size_t Paragraph::row(pos_type pos) const
|
||||
size_t Paragraph::pos2row(pos_type pos) const
|
||||
{
|
||||
RowList::const_iterator rit = rows.end();
|
||||
RowList::const_iterator const begin = rows.begin();
|
||||
RowList::const_iterator rit = rows_.end();
|
||||
RowList::const_iterator const begin = rows_.begin();
|
||||
|
||||
for (--rit; rit != begin && rit->pos() > pos; --rit)
|
||||
;
|
||||
@ -1861,3 +1856,23 @@ unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const
|
||||
return Encodings::TransformChar(c, Encodings::FORM_ISOLATED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::dump() const
|
||||
{
|
||||
lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
|
||||
for (size_t i = 0; i != rows_.size(); ++i) {
|
||||
lyxerr << " row " << i << ": ";
|
||||
rows_[i].dump();
|
||||
}
|
||||
}
|
||||
|
||||
//void Paragraph::metrics(MetricsInfo & mi, Dimension & dim, LyXText & text)
|
||||
//{
|
||||
//}
|
||||
//
|
||||
//
|
||||
//void draw(PainterInfo & pi, int x, int y, LyXText & text) const
|
||||
//{
|
||||
//}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define PARAGRAPH_H
|
||||
|
||||
#include "changes.h"
|
||||
#include "dimension.h"
|
||||
#include "InsetList.h"
|
||||
#include "lyxlayout_ptr_fwd.h"
|
||||
#include "RowList_fwd.h"
|
||||
@ -35,12 +36,14 @@ class BufferView;
|
||||
class Counters;
|
||||
class InsetBase;
|
||||
class InsetBibitem;
|
||||
class LaTeXFeatures;
|
||||
class InsetBase_code;
|
||||
class Language;
|
||||
class LaTeXFeatures;
|
||||
class OutputParams;
|
||||
class LyXFont;
|
||||
class LyXFont_size;
|
||||
class MetricsInfo;
|
||||
class OutputParams;
|
||||
class PainterInfo;
|
||||
class ParagraphParameters;
|
||||
class TexRow;
|
||||
class UpdatableInset;
|
||||
@ -76,6 +79,7 @@ public:
|
||||
///
|
||||
int id() const;
|
||||
|
||||
|
||||
///
|
||||
Language const * getParLanguage(BufferParams const &) const;
|
||||
///
|
||||
@ -358,25 +362,39 @@ public:
|
||||
ParagraphParameters const & params() const;
|
||||
|
||||
///
|
||||
RowList::iterator getRow(lyx::pos_type pos);
|
||||
Row & getRow(lyx::pos_type pos);
|
||||
///
|
||||
RowList::const_iterator getRow(lyx::pos_type pos) const;
|
||||
Row const & getRow(lyx::pos_type pos) const;
|
||||
///
|
||||
size_t row(lyx::pos_type pos) const;
|
||||
size_t pos2row(lyx::pos_type pos) const;
|
||||
|
||||
///
|
||||
InsetList insetlist;
|
||||
|
||||
///
|
||||
mutable RowList rows;
|
||||
/// last draw y position (baseline of top row)
|
||||
int y;
|
||||
/// total height of paragraph
|
||||
unsigned int height;
|
||||
unsigned int height() const { return dim_.height(); }
|
||||
/// total width of paragraph, may differ from workwidth
|
||||
unsigned int width;
|
||||
unsigned int width() const { return dim_.width(); }
|
||||
unsigned int ascent() const { return dim_.ascent(); }
|
||||
unsigned int descent() const { return dim_.descent(); }
|
||||
///
|
||||
RowList & rows() { return rows_; }
|
||||
///
|
||||
RowList const & rows() const { return rows_; }
|
||||
|
||||
// compute paragraph metrics
|
||||
void metrics(MetricsInfo & mi, Dimension & dim, LyXText & text);
|
||||
// draw paragraph
|
||||
void draw(PainterInfo & pi, int x, int y, LyXText & text) const;
|
||||
/// dump some information
|
||||
void dump() const;
|
||||
|
||||
/// cached dimensions of paragraph
|
||||
Dimension dim_;
|
||||
|
||||
private:
|
||||
///
|
||||
mutable RowList rows_;
|
||||
///
|
||||
LyXLayout_ptr layout_;
|
||||
/// keeping this here instead of in the pimpl makes LyX >10% faster
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "encoding.h"
|
||||
#include "gettext.h"
|
||||
#include "language.h"
|
||||
#include "lyxrow.h"
|
||||
#include "lyxtext.h"
|
||||
#include "outputparams.h"
|
||||
#include "paragraph_pimpl.h"
|
||||
@ -96,6 +97,9 @@ void breakParagraph(BufferParams const & bparams,
|
||||
|
||||
Paragraph & par = pars[par_offset];
|
||||
|
||||
// we will invalidate the row cache
|
||||
par.rows().clear();
|
||||
|
||||
// without doing that we get a crash when typing <Return> at the
|
||||
// end of a paragraph
|
||||
tmp->layout(bparams.getLyXTextClass().defaultLayout());
|
||||
@ -316,45 +320,6 @@ LyXFont const outerFont(pit_type par_offset, ParagraphList const & pars)
|
||||
}
|
||||
|
||||
|
||||
pit_type outerPar(Buffer const & buf, InsetBase const * inset)
|
||||
{
|
||||
ParIterator pit = const_cast<Buffer &>(buf).par_iterator_begin();
|
||||
ParIterator end = const_cast<Buffer &>(buf).par_iterator_end();
|
||||
for ( ; pit != end; ++pit) {
|
||||
LyXText * text;
|
||||
// the second '=' below is intentional
|
||||
for (int i = 0; (text = inset->getText(i)); ++i)
|
||||
if (&text->paragraphs() == &pit.plist())
|
||||
return pit.outerPar();
|
||||
|
||||
InsetList::const_iterator ii = pit->insetlist.begin();
|
||||
InsetList::const_iterator iend = pit->insetlist.end();
|
||||
for ( ; ii != iend; ++ii)
|
||||
if (ii->inset == inset)
|
||||
return pit.outerPar();
|
||||
}
|
||||
lyxerr << "outerPar: should not happen" << endl;
|
||||
BOOST_ASSERT(false);
|
||||
return buf.paragraphs().size(); // shut up compiler
|
||||
}
|
||||
|
||||
|
||||
/// return the range of pars [beg, end[ owning the range of y [ystart, yend]
|
||||
void getParsInRange(ParagraphList & pars, int ystart, int yend,
|
||||
pit_type & beg, pit_type & end)
|
||||
{
|
||||
BOOST_ASSERT(!pars.empty());
|
||||
pit_type const endpar = pars.size();
|
||||
pit_type const begpar = 0;
|
||||
|
||||
for (beg = endpar - 1; beg != begpar && pars[beg].y > ystart; --beg)
|
||||
;
|
||||
|
||||
for (end = beg ; end != endpar && pars[end].y <= yend; ++end)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/// return the number of InsetOptArg in a paragraph
|
||||
int numberOfOptArgs(Paragraph const & par)
|
||||
{
|
||||
@ -368,5 +333,3 @@ int numberOfOptArgs(Paragraph const & par)
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,19 +56,9 @@ bool isFirstInSequence(lyx::pit_type par, ParagraphList const & plist);
|
||||
proof environment */
|
||||
int getEndLabel(lyx::pit_type par, ParagraphList const & plist);
|
||||
|
||||
LyXFont const outerFont(lyx::pit_type par, ParagraphList const & plist);
|
||||
|
||||
/// find outermost paragraph containing an inset
|
||||
lyx::pit_type outerPar(Buffer const & buf, InsetBase const * inset);
|
||||
|
||||
/// return the range of pars [beg, end[ owning the range of y [ystart, yend]
|
||||
void getParsInRange(ParagraphList & plist,
|
||||
int ystart, int yend,
|
||||
lyx::pit_type & beg,
|
||||
lyx::pit_type & end);
|
||||
LyXFont const outerFont(lyx::pit_type par_offset, ParagraphList const & pars);
|
||||
|
||||
/// return the number of InsetOptArg in a paragraph
|
||||
int numberOfOptArgs(Paragraph const & par);
|
||||
|
||||
|
||||
#endif // PARAGRAPH_FUNCS_H
|
||||
|
@ -84,7 +84,7 @@ Paragraph & ParIterator::operator*() const
|
||||
|
||||
pit_type ParIterator::pit() const
|
||||
{
|
||||
return pit();
|
||||
return DocIterator::pit();
|
||||
}
|
||||
|
||||
|
||||
|
344
src/rowpainter.C
344
src/rowpainter.C
@ -45,6 +45,7 @@ using lyx::pit_type;
|
||||
|
||||
using std::endl;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::string;
|
||||
|
||||
|
||||
@ -56,23 +57,23 @@ namespace {
|
||||
class RowPainter {
|
||||
public:
|
||||
/// initialise and run painter
|
||||
RowPainter(BufferView const & bv, Painter & pain, LyXText const & text,
|
||||
pit_type pit, RowList::iterator rit, int y);
|
||||
private:
|
||||
RowPainter(PainterInfo & pi, LyXText const & text,
|
||||
pit_type pit, Row & row, int x, int y);
|
||||
|
||||
// paint various parts
|
||||
void paintBackground();
|
||||
void paintSelection();
|
||||
void paintAppendix();
|
||||
void paintDepthBar();
|
||||
void paintChangeBar();
|
||||
void paintFirst();
|
||||
void paintLast();
|
||||
void paintText();
|
||||
|
||||
private:
|
||||
void paintForeignMark(double orig_x, LyXFont const & orig_font);
|
||||
void paintHebrewComposeChar(lyx::pos_type & vpos);
|
||||
void paintArabicComposeChar(lyx::pos_type & vpos);
|
||||
void paintChars(lyx::pos_type & vpos, bool hebrew, bool arabic);
|
||||
int paintAppendixStart(int y);
|
||||
void paintText();
|
||||
void paintFromPos(lyx::pos_type & vpos);
|
||||
void paintInset(lyx::pos_type const pos);
|
||||
|
||||
@ -100,7 +101,6 @@ private:
|
||||
ParagraphList & pars_;
|
||||
|
||||
/// The row to paint
|
||||
RowList::iterator const rit_;
|
||||
Row & row_;
|
||||
|
||||
/// Row's paragraph
|
||||
@ -108,8 +108,8 @@ private:
|
||||
Paragraph const & par_;
|
||||
|
||||
// Looks ugly - is
|
||||
double xo_;
|
||||
int yo_;
|
||||
double const xo_;
|
||||
int const yo_; // current baseline
|
||||
double x_;
|
||||
int width_;
|
||||
double separator_;
|
||||
@ -118,48 +118,24 @@ private:
|
||||
};
|
||||
|
||||
|
||||
RowPainter::RowPainter(BufferView const & bv, Painter & pain,
|
||||
LyXText const & text, pit_type pit, RowList::iterator rit, int y)
|
||||
: bv_(bv), pain_(pain), text_(text), pars_(text.paragraphs()),
|
||||
rit_(rit), row_(*rit), pit_(pit), par_(text.paragraphs()[pit]),
|
||||
xo_(text_.xo_), yo_(y), width_(text_.width())
|
||||
RowPainter::RowPainter(PainterInfo & pi,
|
||||
LyXText const & text, pit_type pit, Row & row, int x, int y)
|
||||
: bv_(*pi.base.bv), pain_(pi.pain), text_(text), pars_(text.paragraphs()),
|
||||
row_(row), pit_(pit), par_(text.paragraphs()[pit]),
|
||||
xo_(x), yo_(y), width_(text_.width())
|
||||
{
|
||||
//lyxerr << "RowPainter: x: " << x_ << " xo: " << xo << " yo: " << yo
|
||||
// << " pit->y: " << pit_->y
|
||||
// << " row: " << (par_.size() ? par_.getChar(row_.pos()) : 'X') << endl;
|
||||
|
||||
RowMetrics m = text_.computeRowMetrics(pit, row_);
|
||||
x_ = m.x + xo_;
|
||||
|
||||
//lyxerr << "RowPainter: x: " << x_ << " xo: " << xo_ << " yo: " << yo_ << endl;
|
||||
//row_.dump();
|
||||
|
||||
separator_ = m.separator;
|
||||
hfill_ = m.hfill;
|
||||
label_hfill_ = m.label_hfill;
|
||||
|
||||
// background has already been cleared.
|
||||
if (&text_ == bv_.text())
|
||||
paintBackground();
|
||||
|
||||
// paint the selection background
|
||||
if (bv_.cursor().selection() && &text_ == bv_.cursor().text())
|
||||
paintSelection();
|
||||
|
||||
// vertical lines for appendix
|
||||
paintAppendix();
|
||||
|
||||
// environment depth brackets
|
||||
paintDepthBar();
|
||||
|
||||
// changebar
|
||||
paintChangeBar();
|
||||
|
||||
if (row_.pos() == 0)
|
||||
paintFirst();
|
||||
|
||||
if (row_.endpos() >= par_.size())
|
||||
paintLast();
|
||||
|
||||
// paint text
|
||||
paintText();
|
||||
BOOST_ASSERT(pit >= 0);
|
||||
BOOST_ASSERT(pit < int(text.paragraphs().size()));
|
||||
}
|
||||
|
||||
|
||||
@ -202,9 +178,9 @@ void RowPainter::paintInset(pos_type const pos)
|
||||
PainterInfo pi(const_cast<BufferView *>(&bv_), pain_);
|
||||
pi.base.font = getFont(pos);
|
||||
pi.ltr_pos = (text_.bidi.level(pos) % 2 == 0);
|
||||
theCoords.insets_.add(inset, int(x_), yo_ + row_.baseline());
|
||||
inset->drawSelection(pi, int(x_), yo_ + row_.baseline());
|
||||
inset->draw(pi, int(x_), yo_ + row_.baseline());
|
||||
theCoords.insets_.add(inset, int(x_), yo_);
|
||||
inset->drawSelection(pi, int(x_), yo_);
|
||||
inset->draw(pi, int(x_), yo_);
|
||||
x_ += inset->width();
|
||||
}
|
||||
|
||||
@ -239,7 +215,7 @@ void RowPainter::paintHebrewComposeChar(pos_type & vpos)
|
||||
}
|
||||
|
||||
// Draw nikud
|
||||
pain_.text(int(x_) + dx, yo_ + row_.baseline(), str, font);
|
||||
pain_.text(int(x_) + dx, yo_, str, font);
|
||||
}
|
||||
|
||||
|
||||
@ -269,7 +245,7 @@ void RowPainter::paintArabicComposeChar(pos_type & vpos)
|
||||
}
|
||||
}
|
||||
// Draw nikud
|
||||
pain_.text(int(x_) + dx, yo_ + row_.baseline(), str, font);
|
||||
pain_.text(int(x_) + dx, yo_, str, font);
|
||||
}
|
||||
|
||||
|
||||
@ -324,9 +300,8 @@ void RowPainter::paintChars(pos_type & vpos, bool hebrew, bool arabic)
|
||||
orig_font.setColor(LColor::newtext);
|
||||
|
||||
// Draw text and set the new x position
|
||||
//lyxerr << "paint row: yo_ " << yo_ << " baseline: " << row_.baseline()
|
||||
// << "\n";
|
||||
pain_.text(int(x_), yo_ + row_.baseline(), str, orig_font);
|
||||
//lyxerr << "paint row: yo_ " << yo_ << "\n";
|
||||
pain_.text(int(x_), yo_, str, orig_font);
|
||||
x_ += font_metrics::width(str, orig_font);
|
||||
}
|
||||
|
||||
@ -340,7 +315,7 @@ void RowPainter::paintForeignMark(double orig_x, LyXFont const & orig_font)
|
||||
if (orig_font.language() == bv_.buffer()->params().language)
|
||||
return;
|
||||
|
||||
int const y = yo_ + row_.baseline() + 1;
|
||||
int const y = yo_ + 1;
|
||||
pain_.line(int(orig_x), y, int(x_), y, LColor::language);
|
||||
}
|
||||
|
||||
@ -386,110 +361,6 @@ void RowPainter::paintFromPos(pos_type & vpos)
|
||||
}
|
||||
|
||||
|
||||
void RowPainter::paintBackground()
|
||||
{
|
||||
int const x = int(xo_);
|
||||
int const y = yo_ < 0 ? 0 : yo_;
|
||||
int const h = yo_ < 0 ? row_.height() + yo_ : row_.height();
|
||||
pain_.fillRectangle(x, y, width_, h, text_.backgroundColor());
|
||||
}
|
||||
|
||||
|
||||
void RowPainter::paintSelection()
|
||||
{
|
||||
bool const is_rtl = text_.isRTL(par_);
|
||||
|
||||
// the current selection
|
||||
LCursor const & cur = bv_.cursor();
|
||||
int const starty = text_.cursorY(cur.selBegin());
|
||||
int const endy = text_.cursorY(cur.selEnd());
|
||||
pit_type startpit = cur.selBegin().pit();
|
||||
pit_type endpit = cur.selEnd().pit();
|
||||
RowList::iterator startrow = pars_[startpit].getRow(cur.selBegin().pos());
|
||||
RowList::iterator endrow = pars_[endpit].getRow(cur.selEnd().pos());
|
||||
int const h = row_.height();
|
||||
|
||||
int const row_y = text_.yo_ + par_.y + row_.y_offset();
|
||||
|
||||
bool const sel_starts_here = startpit == pit_ && startrow == rit_;
|
||||
bool const sel_ends_here = endpit == pit_ && endrow == rit_;
|
||||
bool const sel_on_one_row = sel_starts_here && sel_ends_here;
|
||||
|
||||
if (text_.bidi.same_direction()) {
|
||||
if (sel_on_one_row) {
|
||||
int const startx = text_.cursorX(cur.selBegin());
|
||||
int const endx = text_.cursorX(cur.selEnd());
|
||||
int const x1 = is_rtl ? endx : startx;
|
||||
int const x2 = is_rtl ? startx : endx;
|
||||
pain_.fillRectangle(x1, yo_, x2 - x1, h, LColor::selection);
|
||||
} else if (sel_starts_here) {
|
||||
int const startx = text_.cursorX(cur.selBegin());
|
||||
int const x1 = is_rtl ? int(xo_) : startx;
|
||||
int const x2 = is_rtl ? startx : int(xo_) + width_;
|
||||
pain_.fillRectangle(x1, yo_, x2 - x1, h, LColor::selection);
|
||||
} else if (sel_ends_here) {
|
||||
int const endx = text_.cursorX(cur.selEnd());
|
||||
int const x1 = is_rtl ? endx : int(xo_);
|
||||
int const x2 = is_rtl ? int(xo_) + width_ : endx;
|
||||
pain_.fillRectangle(x1, yo_, x2 - x1, h, LColor::selection);
|
||||
} else if (row_y > starty && row_y < endy) {
|
||||
pain_.fillRectangle(int(xo_), yo_, width_, h, LColor::selection);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((startpit != pit_ && startrow != rit_ && !is_rtl)
|
||||
|| (endpit != pit_ && endrow != rit_ && is_rtl))
|
||||
pain_.fillRectangle(int(xo_), yo_,
|
||||
int(x_), h, LColor::selection);
|
||||
|
||||
pos_type const body_pos = par_.beginOfBody();
|
||||
pos_type const end = row_.endpos();
|
||||
double tmpx = x_;
|
||||
|
||||
for (pos_type vpos = row_.pos(); vpos < end; ++vpos) {
|
||||
pos_type pos = text_.bidi.vis2log(vpos);
|
||||
double const old_tmpx = tmpx;
|
||||
if (body_pos > 0 && pos == body_pos - 1) {
|
||||
LyXLayout_ptr const & layout = par_.layout();
|
||||
LyXFont const lfont = getLabelFont();
|
||||
|
||||
tmpx += label_hfill_ + font_metrics::width(layout->labelsep, lfont);
|
||||
|
||||
if (par_.isLineSeparator(body_pos - 1))
|
||||
tmpx -= singleWidth(body_pos - 1);
|
||||
}
|
||||
|
||||
tmpx += singleWidth(pos);
|
||||
|
||||
if (hfillExpansion(par_, row_, pos)) {
|
||||
if (pos >= body_pos)
|
||||
tmpx += hfill_;
|
||||
else
|
||||
tmpx += label_hfill_;
|
||||
} else {
|
||||
if (par_.isSeparator(pos) && pos >= body_pos)
|
||||
tmpx += separator_;
|
||||
}
|
||||
|
||||
if (((startpit != pit_ && startrow != rit_)
|
||||
|| cur.selBegin().pos() <= pos) &&
|
||||
((endpit != pit_ && endrow != rit_)
|
||||
|| pos < cur.selEnd().pos())) {
|
||||
// Here we do not use x_ as xo_ was added to x_.
|
||||
pain_.fillRectangle(int(old_tmpx), yo_,
|
||||
int(tmpx - old_tmpx + 1), h, LColor::selection);
|
||||
}
|
||||
}
|
||||
|
||||
if ((startpit != pit_ && startrow != rit_ && is_rtl) ||
|
||||
(endpit != pit_ && endrow != rit_ && !is_rtl)) {
|
||||
pain_.fillRectangle(int(xo_ + tmpx),
|
||||
yo_, int(width_ - tmpx), h, LColor::selection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RowPainter::paintChangeBar()
|
||||
{
|
||||
pos_type const start = row_.pos();
|
||||
@ -499,10 +370,10 @@ void RowPainter::paintChangeBar()
|
||||
return;
|
||||
|
||||
int const height = text_.isLastRow(pit_, row_)
|
||||
? row_.baseline()
|
||||
: row_.height() + boost::next(rit_)->top_of_text();
|
||||
? row_.ascent()
|
||||
: row_.height();
|
||||
|
||||
pain_.fillRectangle(4, yo_, 5, height, LColor::changebar);
|
||||
pain_.fillRectangle(4, yo_ - row_.ascent(), 5, height, LColor::changebar);
|
||||
}
|
||||
|
||||
|
||||
@ -511,7 +382,7 @@ void RowPainter::paintAppendix()
|
||||
if (!par_.params().appendix())
|
||||
return;
|
||||
|
||||
int y = yo_;
|
||||
int y = yo_ - row_.ascent();
|
||||
|
||||
if (par_.params().startOfAppendix())
|
||||
y += 2 * defaultRowHeight();
|
||||
@ -551,14 +422,15 @@ void RowPainter::paintDepthBar()
|
||||
if (text_.isMainText())
|
||||
x += changebarMargin();
|
||||
|
||||
int const h = yo_ + row_.height() - 1 - (i - next_depth - 1) * 3;
|
||||
int const starty = yo_ - row_.ascent();
|
||||
int const h = row_.height() - 1 - (i - next_depth - 1) * 3;
|
||||
|
||||
pain_.line(x, yo_, x, h, LColor::depthbar);
|
||||
pain_.line(x, starty, x, starty + h, LColor::depthbar);
|
||||
|
||||
if (i > prev_depth)
|
||||
pain_.fillRectangle(x, yo_, w, 2, LColor::depthbar);
|
||||
pain_.fillRectangle(x, starty, w, 2, LColor::depthbar);
|
||||
if (i > next_depth)
|
||||
pain_.fillRectangle(x, h, w, 2, LColor::depthbar);
|
||||
pain_.fillRectangle(x, starty + h, w, 2, LColor::depthbar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,9 +515,10 @@ void RowPainter::paintFirst()
|
||||
} else {
|
||||
spacing_val = buffer.params().spacing().getValue();
|
||||
}
|
||||
#warning Look is this correct?
|
||||
int const labeladdon = int(font_metrics::maxHeight(font) * layout->spacing.getValue() * spacing_val);
|
||||
|
||||
int const maxdesc =
|
||||
int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val)
|
||||
int const maxdesc = int(font_metrics::maxDescent(font) * layout->spacing.getValue() * spacing_val)
|
||||
+ int(layout->parsep) * defaultRowHeight();
|
||||
|
||||
if (is_rtl) {
|
||||
@ -653,10 +526,7 @@ void RowPainter::paintFirst()
|
||||
font_metrics::width(str, font);
|
||||
}
|
||||
|
||||
pain_.text(int(x),
|
||||
yo_ + row_.baseline() -
|
||||
row_.ascent_of_text() - maxdesc,
|
||||
str, font);
|
||||
pain_.text(int(x), yo_ - maxdesc - labeladdon, str, font);
|
||||
}
|
||||
} else {
|
||||
if (is_rtl) {
|
||||
@ -667,7 +537,7 @@ void RowPainter::paintFirst()
|
||||
- font_metrics::width(str, font);
|
||||
}
|
||||
|
||||
pain_.text(int(x), yo_ + row_.baseline(), str, font);
|
||||
pain_.text(int(x), yo_, str, font);
|
||||
}
|
||||
}
|
||||
|
||||
@ -700,9 +570,7 @@ void RowPainter::paintFirst()
|
||||
x = width_ - leftMargin() -
|
||||
font_metrics::width(str, font);
|
||||
}
|
||||
pain_.text(int(x),
|
||||
yo_ + row_.baseline() - row_.ascent_of_text() - maxdesc,
|
||||
str, font);
|
||||
pain_.text(int(x), yo_ - maxdesc, str, font);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -719,7 +587,7 @@ void RowPainter::paintLast()
|
||||
case END_LABEL_FILLED_BOX: {
|
||||
LyXFont const font = getLabelFont();
|
||||
int const size = int(0.75 * font_metrics::maxAscent(font));
|
||||
int const y = yo_ + row_.baseline() - size;
|
||||
int const y = yo_ - size;
|
||||
int x = is_rtl ? nestMargin() + changebarMargin() : width_ - size;
|
||||
|
||||
if (width_ - int(row_.width()) <= size)
|
||||
@ -738,7 +606,7 @@ void RowPainter::paintLast()
|
||||
double const x = is_rtl ?
|
||||
x_ - font_metrics::width(str, font)
|
||||
: - text_.rightMargin(par_) - row_.width();
|
||||
pain_.text(int(x), yo_ + row_.baseline(), str, font);
|
||||
pain_.text(int(x), yo_, str, font);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -794,7 +662,10 @@ void RowPainter::paintText()
|
||||
// if we reach the end of a struck out range, paint it
|
||||
// we also don't paint across things like tables
|
||||
if (running_strikeout && (highly_editable_inset || !is_struckout)) {
|
||||
int const middle = yo_ + (row_.baseline() + row_.top_of_text()) / 2;
|
||||
// FIXME this should take real text height into account, not
|
||||
// the whole row including padding whitespace
|
||||
//int const middle = yo_ + (- row_.ascent() + row_.top_of_text()) / 2;
|
||||
int const middle = yo_ - row_.ascent() / 2;
|
||||
pain_.line(last_strikeout_x, middle, int(x_), middle,
|
||||
LColor::strikeout, Painter::line_solid, Painter::line_thin);
|
||||
running_strikeout = false;
|
||||
@ -810,7 +681,7 @@ void RowPainter::paintText()
|
||||
if (par_.isHfill(pos)) {
|
||||
x_ += 1;
|
||||
|
||||
int const y0 = yo_ + row_.baseline();
|
||||
int const y0 = yo_;
|
||||
int const y1 = y0 - defaultRowHeight() / 2;
|
||||
|
||||
pain_.line(int(x_), y1, int(x_), y0, LColor::added_space);
|
||||
@ -845,7 +716,9 @@ void RowPainter::paintText()
|
||||
|
||||
// if we reach the end of a struck out range, paint it
|
||||
if (running_strikeout) {
|
||||
int const middle = yo_ + (row_.baseline() + row_.top_of_text()) / 2;
|
||||
//top_of_text = font_metrics::maxAscent(font);
|
||||
//int const middle = yo_ - top_of_text() / 2;
|
||||
int const middle = yo_ - row_.ascent() / 2;
|
||||
pain_.line(last_strikeout_x, middle, int(x_), middle,
|
||||
LColor::strikeout, Painter::line_solid, Painter::line_thin);
|
||||
running_strikeout = false;
|
||||
@ -853,53 +726,98 @@ void RowPainter::paintText()
|
||||
}
|
||||
|
||||
|
||||
int paintPars(BufferView const & bv, Painter & pain,
|
||||
LyXText const & text, pit_type pit, pit_type end)
|
||||
void paintPar
|
||||
(PainterInfo & pi, LyXText const & text, pit_type pit, int x, int y)
|
||||
{
|
||||
//lyxerr << " paintRows: pit: " << &*pit << endl;
|
||||
ParagraphList & pars = text.paragraphs();
|
||||
// lyxerr << " paintPar: pit: " << pit << " at y: " << y << endl;
|
||||
static NullPainter nop;
|
||||
static PainterInfo nullpi(pi.base.bv, nop);
|
||||
int const ww = pi.base.bv->workHeight();
|
||||
|
||||
Paragraph & par = text.paragraphs()[pit];
|
||||
|
||||
int y = pars[pit].y + text.yo_ - bv.top_y();
|
||||
|
||||
for (; pit != end; ++pit) {
|
||||
RowList::iterator row = pars[pit].rows.begin();
|
||||
RowList::iterator rend = pars[pit].rows.end();
|
||||
|
||||
// We draw full paragraphs to get the (xo, yo) cache of all
|
||||
// contained insets right. This is needed for properly working
|
||||
// editXY. And maybe not even sufficient.
|
||||
// FIXME: Alfredo, please have a look at the coordinate business
|
||||
// again.
|
||||
for ( ; row != rend; ++row) {
|
||||
RowPainter(bv, pain, text, pit, row, y);
|
||||
y += row->height();
|
||||
}
|
||||
RowList::iterator const rb = par.rows().begin();
|
||||
RowList::iterator const re = par.rows().end();
|
||||
theCoords.pars_[&text][pit] = Point(x, y);
|
||||
|
||||
y -= rb->ascent();
|
||||
for (RowList::iterator rit = rb; rit != re; ++rit) {
|
||||
y += rit->ascent();
|
||||
bool const inside = (y + rit->descent() >= 0
|
||||
&& y - rit->ascent() < ww);
|
||||
RowPainter rp(inside ? pi : nullpi, text, pit, *rit, x, y);
|
||||
|
||||
y += rit->descent();
|
||||
rp.paintAppendix();
|
||||
rp.paintDepthBar();
|
||||
rp.paintChangeBar();
|
||||
if (rit == rb)
|
||||
rp.paintFirst();
|
||||
if (rit + 1 == re)
|
||||
rp.paintLast();
|
||||
rp.paintText();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
void refreshPar(BufferView const & bv, LyXText const & text, pit_type pit)
|
||||
void paintText(BufferView const & bv, ViewMetricsInfo const & vi)
|
||||
{
|
||||
static NullPainter nop;
|
||||
paintPars(bv, nop, text, pit, pit + 1);
|
||||
Painter & pain = bv.painter();
|
||||
LyXText * const text = bv.text();
|
||||
|
||||
// clear background
|
||||
pain.fillRectangle(0, vi.y1, bv.workWidth(), vi.y2 - vi.y1,
|
||||
LColor::background);
|
||||
|
||||
// draw selection
|
||||
PainterInfo pi(const_cast<BufferView *>(&bv), pain);
|
||||
|
||||
text->drawSelection(pi, 0, 0);
|
||||
|
||||
int yy = vi.y1;
|
||||
// draw contents
|
||||
for (pit_type pit = vi.p1; pit <= vi.p2; ++pit) {
|
||||
yy += text->getPar(pit).ascent();
|
||||
paintPar(pi, *bv.text(), pit, 0, yy);
|
||||
yy += text->getPar(pit).descent();
|
||||
}
|
||||
|
||||
|
||||
// paint one paragraph above and one below
|
||||
if (vi.p1 > 0) {
|
||||
text->redoParagraph(vi.p1 - 1);
|
||||
paintPar(pi, *bv.text(), vi.p1 - 1, 0,
|
||||
vi.y1 - text->getPar(vi.p1 - 1).descent());
|
||||
}
|
||||
|
||||
if (vi.p2 < text->paragraphs().size() - 1) {
|
||||
text->redoParagraph(vi.p2 + 1);
|
||||
paintPar(pi, *bv.text(), vi.p2 + 1, 0,
|
||||
vi.y2 + text->getPar(vi.p2 + 1).ascent());
|
||||
}
|
||||
|
||||
// and grey out above (should not happen later)
|
||||
lyxerr << "par ascent: " << text->getPar(vi.p1).ascent() << endl;
|
||||
if (vi.y1 > 0)
|
||||
pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, LColor::bottomarea);
|
||||
|
||||
// and possibly grey out below
|
||||
lyxerr << "par descent: " << text->getPar(vi.p1).ascent() << endl;
|
||||
if (vi.y2 < bv.workHeight())
|
||||
pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea);
|
||||
}
|
||||
|
||||
|
||||
int paintText(BufferView const & bv)
|
||||
void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y)
|
||||
{
|
||||
pit_type pit, end;
|
||||
getParsInRange(bv.text()->paragraphs(), bv.top_y(),
|
||||
bv.top_y() + bv.workHeight(), pit, end);
|
||||
//lyxerr << "top_y: " << bv.top_y() << " y: " << pit->y << endl;
|
||||
return paintPars(bv, bv.painter(), *bv.text(), pit, end);
|
||||
}
|
||||
// lyxerr << " paintTextInset: y: " << y << endl;
|
||||
|
||||
|
||||
void paintTextInset(LyXText const & text, PainterInfo & pi)
|
||||
{
|
||||
paintPars(*pi.base.bv, pi.pain, text, 0, text.paragraphs().size());
|
||||
y -= text.getPar(0).ascent();
|
||||
for (int pit = 0; pit < int(text.paragraphs().size()); ++pit) {
|
||||
y += text.getPar(pit).ascent();
|
||||
paintPar(pi, text, pit, x, y);
|
||||
y += text.getPar(pit).descent();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
*
|
||||
* \author various
|
||||
* \author John Levon
|
||||
* \author André Pönitz
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
@ -18,36 +19,23 @@
|
||||
class LyXText;
|
||||
class BufferView;
|
||||
class PainterInfo;
|
||||
class ViewMetricsInfo;
|
||||
|
||||
/// paint the rows of the main text, return last drawn y value
|
||||
int paintText(BufferView const & bv);
|
||||
|
||||
/// refresh a par of the main text
|
||||
void refreshPar(BufferView const & bv, LyXText const & text,
|
||||
lyx::pit_type pit);
|
||||
/// paint visible paragraph of main text
|
||||
void paintText(BufferView const & bv, ViewMetricsInfo const & vi);
|
||||
|
||||
/// paint the rows of a text inset
|
||||
void paintTextInset(LyXText const & text, PainterInfo & pi);
|
||||
void paintTextInset(LyXText const & text, PainterInfo & pi, int x, int y);
|
||||
|
||||
/// some space for drawing the 'nested' markers (in pixel)
|
||||
inline int nestMargin()
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
inline int nestMargin() { return 15; }
|
||||
|
||||
/// margin for changebar
|
||||
inline int changebarMargin()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
inline int changebarMargin() { return 10; }
|
||||
|
||||
/// right margin
|
||||
inline int rightMargin()
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
inline int rightMargin() { return 30; }
|
||||
|
||||
|
||||
#endif // ROWPAINTER_H
|
||||
|
413
src/text.C
413
src/text.C
@ -23,6 +23,7 @@
|
||||
#include "bufferparams.h"
|
||||
#include "BufferView.h"
|
||||
#include "cursor.h"
|
||||
#include "coordcache.h"
|
||||
#include "CutAndPaste.h"
|
||||
#include "debug.h"
|
||||
#include "dispatchresult.h"
|
||||
@ -50,6 +51,7 @@
|
||||
|
||||
#include "frontends/font_metrics.h"
|
||||
#include "frontends/LyXView.h"
|
||||
#include "frontends/Painter.h"
|
||||
|
||||
#include "insets/insettext.h"
|
||||
#include "insets/insetbibitem.h"
|
||||
@ -105,17 +107,6 @@ int numberOfSeparators(Paragraph const & par, Row const & row)
|
||||
}
|
||||
|
||||
|
||||
unsigned int maxParagraphWidth(ParagraphList const & plist)
|
||||
{
|
||||
unsigned int width = 0;
|
||||
ParagraphList::const_iterator pit = plist.begin();
|
||||
ParagraphList::const_iterator end = plist.end();
|
||||
for (; pit != end; ++pit)
|
||||
width = std::max(width, pit->width);
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
int numberOfLabelHfills(Paragraph const & par, Row const & row)
|
||||
{
|
||||
pos_type last = row.endpos() - 1;
|
||||
@ -407,26 +398,15 @@ double LyXText::spacing(Paragraph const & par) const
|
||||
}
|
||||
|
||||
|
||||
void LyXText::updateParPositions()
|
||||
{
|
||||
pit_type pit = 0;
|
||||
pit_type end = pars_.size();
|
||||
for (height_ = 0; pit != end; ++pit) {
|
||||
pars_[pit].y = height_;
|
||||
height_ += pars_[pit].height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int LyXText::width() const
|
||||
{
|
||||
return width_;
|
||||
return dim_.wid;
|
||||
}
|
||||
|
||||
|
||||
int LyXText::height() const
|
||||
{
|
||||
return height_;
|
||||
return dim_.height();
|
||||
}
|
||||
|
||||
|
||||
@ -449,8 +429,7 @@ int LyXText::singleWidth(Paragraph const & par,
|
||||
&& font.language()->lang() == "arabic") {
|
||||
if (Encodings::IsComposeChar_arabic(c))
|
||||
return 0;
|
||||
else
|
||||
c = par.transformChar(c, pos);
|
||||
c = par.transformChar(c, pos);
|
||||
} else if (font.language()->lang() == "hebrew" &&
|
||||
Encodings::IsComposeChar_hebrew(c))
|
||||
return 0;
|
||||
@ -469,13 +448,20 @@ int LyXText::singleWidth(Paragraph const & par,
|
||||
|
||||
int LyXText::leftMargin(pit_type pit) const
|
||||
{
|
||||
BOOST_ASSERT(pit >= 0);
|
||||
BOOST_ASSERT(pit < int(pars_.size()));
|
||||
return leftMargin(pit, pars_[pit].size());
|
||||
}
|
||||
|
||||
|
||||
int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
|
||||
{
|
||||
BOOST_ASSERT(pit >= 0);
|
||||
BOOST_ASSERT(pit < int(pars_.size()));
|
||||
Paragraph const & par = pars_[pit];
|
||||
BOOST_ASSERT(pos >= 0);
|
||||
BOOST_ASSERT(pos <= par.size());
|
||||
//lyxerr << "LyXText::leftMargin: pit: " << pit << " pos: " << pos << endl;
|
||||
LyXTextClass const & tclass =
|
||||
bv()->buffer()->params().getLyXTextClass();
|
||||
LyXLayout_ptr const & layout = par.layout();
|
||||
@ -484,7 +470,7 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
|
||||
|
||||
int l_margin = 0;
|
||||
|
||||
if (xo_ == 0)
|
||||
if (isMainText())
|
||||
l_margin += changebarMargin();
|
||||
|
||||
l_margin += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont());
|
||||
@ -570,8 +556,8 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
|
||||
#if 0
|
||||
// ok, a terrible hack. The left margin depends on the widest
|
||||
// row in this paragraph.
|
||||
RowList::iterator rit = par.rows.begin();
|
||||
RowList::iterator end = par.rows.end();
|
||||
RowList::iterator rit = par.rows().begin();
|
||||
RowList::iterator end = par.rows().end();
|
||||
#ifdef WITH_WARNINGS
|
||||
#warning This is wrong.
|
||||
#endif
|
||||
@ -707,7 +693,7 @@ void LyXText::rowBreakPoint(pit_type const pit, Row & row) const
|
||||
// pixel width since last breakpoint
|
||||
int chunkwidth = 0;
|
||||
|
||||
FontIterator fi = FontIterator(*this, pit, pos);
|
||||
FontIterator fi = FontIterator(*this, par, pos);
|
||||
pos_type point = end;
|
||||
pos_type i = pos;
|
||||
for ( ; i < end; ++i, ++fi) {
|
||||
@ -799,7 +785,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const
|
||||
pos_type i = row.pos();
|
||||
|
||||
if (i < end) {
|
||||
FontIterator fi = FontIterator(*this, pit, i);
|
||||
FontIterator fi = FontIterator(*this, par, i);
|
||||
for ( ; i < end; ++i, ++fi) {
|
||||
if (body_pos > 0 && i == body_pos) {
|
||||
w += font_metrics::width(labelsep, getLabelFont(par));
|
||||
@ -914,7 +900,7 @@ void LyXText::setHeightOfRow(pit_type const pit, Row & row)
|
||||
++maxasc;
|
||||
++maxdesc;
|
||||
|
||||
row.ascent_of_text(maxasc);
|
||||
row.ascent(maxasc);
|
||||
|
||||
// is it a top line?
|
||||
if (row.pos() == 0) {
|
||||
@ -1013,10 +999,9 @@ void LyXText::setHeightOfRow(pit_type const pit, Row & row)
|
||||
// incalculate the layout spaces
|
||||
maxasc += int(layoutasc * 2 / (2 + pars_[pit].getDepth()));
|
||||
maxdesc += int(layoutdesc * 2 / (2 + pars_[pit].getDepth()));
|
||||
|
||||
row.height(maxasc + maxdesc + labeladdon);
|
||||
row.baseline(maxasc + labeladdon);
|
||||
row.top_of_text(row.baseline() - font_metrics::maxAscent(font));
|
||||
|
||||
row.ascent(maxasc + labeladdon);
|
||||
row.descent(maxdesc);
|
||||
}
|
||||
|
||||
|
||||
@ -1093,8 +1078,6 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout)
|
||||
pars_[next_par].erase(0);
|
||||
|
||||
updateCounters();
|
||||
redoParagraph(cpit);
|
||||
redoParagraph(next_par);
|
||||
|
||||
// This check is necessary. Otherwise the new empty paragraph will
|
||||
// be deleted automatically. And it is more friendly for the user!
|
||||
@ -1105,16 +1088,6 @@ void LyXText::breakParagraph(LCursor & cur, char keep_layout)
|
||||
}
|
||||
|
||||
|
||||
// convenience function
|
||||
void LyXText::redoParagraph(LCursor & cur)
|
||||
{
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
cur.clearSelection();
|
||||
redoParagraph(cur.pit());
|
||||
setCursorIntern(cur, cur.pit(), cur.pos());
|
||||
}
|
||||
|
||||
|
||||
// insert a character, moves all the following breaks in the
|
||||
// same Paragraph one to the right and make a rebreak
|
||||
void LyXText::insertChar(LCursor & cur, char c)
|
||||
@ -1211,7 +1184,6 @@ void LyXText::insertChar(LCursor & cur, char c)
|
||||
|
||||
current_font = rawtmpfont;
|
||||
real_current_font = realtmpfont;
|
||||
redoParagraph(cur);
|
||||
setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
|
||||
charInserted();
|
||||
}
|
||||
@ -1231,12 +1203,13 @@ void LyXText::charInserted()
|
||||
}
|
||||
|
||||
|
||||
RowMetrics LyXText::computeRowMetrics(pit_type const pit, Row const & row) const
|
||||
RowMetrics
|
||||
LyXText::computeRowMetrics(pit_type const pit, Row const & row) const
|
||||
{
|
||||
RowMetrics result;
|
||||
Paragraph const & par = pars_[pit];
|
||||
|
||||
double w = width_ - row.width();
|
||||
double w = dim_.wid - row.width();
|
||||
|
||||
bool const is_rtl = isRTL(par);
|
||||
if (is_rtl)
|
||||
@ -1425,7 +1398,6 @@ void LyXText::acceptChange(LCursor & cur)
|
||||
pars_[startc.pit()].acceptChange(startc.pos(), endc.pos());
|
||||
finishUndo();
|
||||
cur.clearSelection();
|
||||
redoParagraph(startc.pit());
|
||||
setCursorIntern(cur, startc.pit(), 0);
|
||||
}
|
||||
#ifdef WITH_WARNINGS
|
||||
@ -1447,7 +1419,6 @@ void LyXText::rejectChange(LCursor & cur)
|
||||
pars_[startc.pit()].rejectChange(startc.pos(), endc.pos());
|
||||
finishUndo();
|
||||
cur.clearSelection();
|
||||
redoParagraph(startc.pit());
|
||||
setCursorIntern(cur, startc.pit(), 0);
|
||||
}
|
||||
#ifdef WITH_WARNINGS
|
||||
@ -1597,8 +1568,6 @@ void LyXText::backspace(LCursor & cur)
|
||||
|
||||
if (cur.pit() != 0) {
|
||||
cursorLeft(cur);
|
||||
// the layout things can change the height of a row !
|
||||
redoParagraph(cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1656,7 +1625,6 @@ void LyXText::backspace(LCursor & cur)
|
||||
if (cur.pos() == cur.lastpos())
|
||||
setCurrentFont(cur);
|
||||
|
||||
redoParagraph(cur);
|
||||
setCursor(cur, cur.pit(), cur.pos(), false, cur.boundary());
|
||||
}
|
||||
|
||||
@ -1672,20 +1640,14 @@ Paragraph & LyXText::getPar(pit_type par) const
|
||||
|
||||
Row const & LyXText::firstRow() const
|
||||
{
|
||||
return *paragraphs().front().rows.begin();
|
||||
return *paragraphs().front().rows().begin();
|
||||
}
|
||||
|
||||
|
||||
void LyXText::redoParagraphInternal(pit_type const pit)
|
||||
void LyXText::redoParagraph(pit_type const pit)
|
||||
{
|
||||
// remove rows of paragraph, keep track of height changes
|
||||
Paragraph & par = pars_[pit];
|
||||
height_ -= par.height;
|
||||
|
||||
// clear old data
|
||||
par.rows.clear();
|
||||
par.height = 0;
|
||||
par.width = 0;
|
||||
|
||||
// redo insets
|
||||
InsetList::iterator ii = par.insetlist.begin();
|
||||
@ -1698,6 +1660,9 @@ void LyXText::redoParagraphInternal(pit_type const pit)
|
||||
}
|
||||
|
||||
// rebreak the paragraph
|
||||
par.rows().clear();
|
||||
Dimension dim;
|
||||
|
||||
par.setBeginOfBody();
|
||||
pos_type z = 0;
|
||||
do {
|
||||
@ -1705,38 +1670,16 @@ void LyXText::redoParagraphInternal(pit_type const pit)
|
||||
rowBreakPoint(pit, row);
|
||||
setRowWidth(pit, row);
|
||||
setHeightOfRow(pit, row);
|
||||
row.y_offset(par.height);
|
||||
par.rows.push_back(row);
|
||||
par.width = std::max(par.width, row.width());
|
||||
par.height += row.height();
|
||||
par.rows().push_back(row);
|
||||
dim.wid = std::max(dim.wid, row.width());
|
||||
dim.des += row.height();
|
||||
z = row.endpos();
|
||||
} while (z < par.size());
|
||||
|
||||
height_ += par.height;
|
||||
//lyxerr << "redoParagraph: " << par.rows.size() << " rows\n";
|
||||
}
|
||||
|
||||
|
||||
void LyXText::redoParagraphs(pit_type pit, pit_type end)
|
||||
{
|
||||
for (; pit != end; ++pit)
|
||||
redoParagraphInternal(pit);
|
||||
updateParPositions();
|
||||
updateCounters();
|
||||
}
|
||||
|
||||
|
||||
void LyXText::redoParagraph(pit_type pit)
|
||||
{
|
||||
redoParagraphInternal(pit);
|
||||
updateParPositions();
|
||||
}
|
||||
|
||||
|
||||
void LyXText::fullRebreak()
|
||||
{
|
||||
redoParagraphs(0, paragraphs().size());
|
||||
bv()->cursor().resetAnchor();
|
||||
dim.asc += par.rows()[0].ascent();
|
||||
dim.des -= par.rows()[0].ascent();
|
||||
par.dim_ = dim;
|
||||
//lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
|
||||
}
|
||||
|
||||
|
||||
@ -1746,36 +1689,183 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
|
||||
if (mi.base.textwidth)
|
||||
maxwidth_ = mi.base.textwidth;
|
||||
//lyxerr << "LyXText::metrics: width: " << mi.base.textwidth
|
||||
//<< " maxWidth: " << maxwidth << "\nfont: " << mi.base.font
|
||||
//<< endl;
|
||||
// << " maxWidth: " << maxwidth_ << "\nfont: " << mi.base.font << endl;
|
||||
|
||||
// Rebuild row cache. This recomputes height as well.
|
||||
redoParagraphs(0, paragraphs().size());
|
||||
unsigned int h = 0;
|
||||
unsigned int w = 0;
|
||||
for (pit_type pit = 0, n = paragraphs().size(); pit != n; ++pit) {
|
||||
redoParagraph(pit);
|
||||
Paragraph & par = paragraphs()[pit];
|
||||
h += par.height();
|
||||
if (w < par.width())
|
||||
w = par.width();
|
||||
}
|
||||
|
||||
width_ = maxParagraphWidth(paragraphs());
|
||||
dim.wid = w;
|
||||
dim.asc = pars_[0].ascent();
|
||||
dim.des = h - dim.asc;
|
||||
|
||||
// final dimension
|
||||
dim.asc = firstRow().ascent_of_text();
|
||||
dim.des = height_ - dim.asc;
|
||||
dim.wid = width_;
|
||||
dim_ = dim;
|
||||
}
|
||||
|
||||
|
||||
// only used for inset right now. should also be used for main text
|
||||
void LyXText::draw(PainterInfo & pi, int x, int y) const
|
||||
{
|
||||
xo_ = x;
|
||||
yo_ = y;
|
||||
paintTextInset(*this, pi);
|
||||
paintTextInset(*this, pi, x, y);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// only used for inset right now. should also be used for main text
|
||||
void LyXText::drawSelection(PainterInfo &, int, int) const
|
||||
void LyXText::drawSelection(PainterInfo & pi, int x , int) const
|
||||
{
|
||||
//lyxerr << "LyXText::drawSelection at " << x << " " << y << endl;
|
||||
}
|
||||
LCursor & cur = pi.base.bv->cursor();
|
||||
if (!cur.selection())
|
||||
return;
|
||||
if (!ptr_cmp(cur.text(), this))
|
||||
return;
|
||||
|
||||
lyxerr << "draw selection at " << x << endl;
|
||||
|
||||
// is there a better way of getting these two iterators?
|
||||
DocIterator beg = cur;
|
||||
DocIterator end = cur;
|
||||
|
||||
beg.top() = cur.selBegin();
|
||||
end.top() = cur.selEnd();
|
||||
|
||||
// the selection doesn't touch the visible screen
|
||||
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_BELOW
|
||||
|| bv_funcs::status(pi.base.bv, end) == bv_funcs::CUR_ABOVE)
|
||||
return;
|
||||
|
||||
Paragraph const & par1 = pars_[beg.pit()];
|
||||
Paragraph const & par2 = pars_[end.pit()];
|
||||
|
||||
Row const & row1 = par1.getRow(beg.pos());
|
||||
Row const & row2 = par2.getRow(end.pos());
|
||||
|
||||
int y1,x1,x2;
|
||||
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_ABOVE) {
|
||||
y1 = 0;
|
||||
x1 = 0;
|
||||
x2 = 0;
|
||||
} else {
|
||||
y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
|
||||
int const startx = cursorX(beg.top());
|
||||
x1 = isRTL(par1) ? startx : 0;
|
||||
x2 = isRTL(par1) ? 0 + dim_.wid : startx;
|
||||
}
|
||||
|
||||
int y2,X1,X2;
|
||||
if (bv_funcs::status(pi.base.bv, end) == bv_funcs::CUR_BELOW) {
|
||||
y2 = pi.base.bv->workHeight();
|
||||
X1 = 0;
|
||||
X2 = 0;
|
||||
} else {
|
||||
y2 = bv_funcs::getPos(end).y_ + row2.descent();
|
||||
int const endx = cursorX(end.top());
|
||||
X1 = isRTL(par2) ? 0 : endx;
|
||||
X2 = isRTL(par2) ? endx : 0 + dim_.wid;
|
||||
}
|
||||
|
||||
lyxerr << " y1: " << y1 << " y2: " << y2
|
||||
<< " xo: " << xo_ << " wid: " << dim_.wid
|
||||
<< endl;
|
||||
|
||||
// paint big rectangle in one go
|
||||
pi.pain.fillRectangle(x, y1, dim_.wid, y2 - y1, LColor::selection);
|
||||
|
||||
// reset background at begin of first selected line
|
||||
pi.pain.fillRectangle(x + x1, y1, x2 - x1, row1.height(),
|
||||
LColor::background);
|
||||
|
||||
// reset background at end of last selected line
|
||||
pi.pain.fillRectangle(x + X1, y2 - row2.height(),
|
||||
X2 - X1, row2.height(), LColor::background);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void LyXText::drawSelection(PainterInfo & pi, int x, int) const
|
||||
{
|
||||
LCursor & cur = pi.base.bv->cursor();
|
||||
if (!cur.selection())
|
||||
return;
|
||||
if (!ptr_cmp(cur.text(), this))
|
||||
return;
|
||||
|
||||
lyxerr << "draw selection at " << x << endl;
|
||||
|
||||
// is there a better way of getting these two iterators?
|
||||
DocIterator beg = cur;
|
||||
DocIterator end = cur;
|
||||
|
||||
beg.top() = cur.selBegin();
|
||||
end.top() = cur.selEnd();
|
||||
|
||||
// the selection doesn't touch the visible screen
|
||||
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_BELOW
|
||||
|| bv_funcs::status(pi.base.bv, end) == bv_funcs::CUR_ABOVE)
|
||||
return;
|
||||
|
||||
Paragraph const & par1 = pars_[beg.pit()];
|
||||
Paragraph const & par2 = pars_[end.pit()];
|
||||
|
||||
bool const above = (bv_funcs::status(pi.base.bv, beg)
|
||||
== bv_funcs::CUR_ABOVE);
|
||||
bool const below = (bv_funcs::status(pi.base.bv, end)
|
||||
== bv_funcs::CUR_BELOW);
|
||||
int y1,y2,x1,x2;
|
||||
if (above) {
|
||||
y1 = 0;
|
||||
y2 = 0;
|
||||
x1 = 0;
|
||||
x2 = dim_.wid;
|
||||
} else {
|
||||
Row const & row1 = par1.getRow(beg.pos());
|
||||
y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
|
||||
y2 = y1 + row1.height();
|
||||
int const startx = cursorX(beg.top());
|
||||
x1 = !isRTL(par1) ? startx : 0;
|
||||
x2 = !isRTL(par1) ? 0 + dim_.wid : startx;
|
||||
}
|
||||
|
||||
int Y1,Y2,X1,X2;
|
||||
if (below) {
|
||||
Y1 = pi.base.bv->workHeight();
|
||||
Y2 = pi.base.bv->workHeight();
|
||||
X1 = 0;
|
||||
X2 = dim_.wid;
|
||||
} else {
|
||||
Row const & row2 = par2.getRow(end.pos());
|
||||
Y1 = bv_funcs::getPos(end).y_ - row2.ascent();
|
||||
Y2 = Y1 + row2.height();
|
||||
int const endx = cursorX(end.top());
|
||||
X1 = !isRTL(par2) ? 0 : endx;
|
||||
X2 = !isRTL(par2) ? endx : 0 + dim_.wid;
|
||||
}
|
||||
|
||||
if (!above && !below && &par1.getRow(beg.pos())
|
||||
== &par2.getRow(end.pos()))
|
||||
{
|
||||
// paint only one rectangle
|
||||
pi.pain.fillRectangle(x + x1, y1, X2 - x1, y2 - y1,
|
||||
LColor::selection);
|
||||
return;
|
||||
}
|
||||
|
||||
// paint upper rectangle
|
||||
pi.pain.fillRectangle(x + x1, y1, x2 - x1, y2 - y1,
|
||||
LColor::selection);
|
||||
// paint bottom rectangle
|
||||
pi.pain.fillRectangle(x + X1, Y1, X2 - X1, Y2 - Y1,
|
||||
LColor::selection);
|
||||
// paint center rectangle
|
||||
pi.pain.fillRectangle(x, y2, dim_.wid,
|
||||
Y1 - y2, LColor::selection);
|
||||
}
|
||||
|
||||
bool LyXText::isLastRow(pit_type pit, Row const & row) const
|
||||
{
|
||||
@ -1902,13 +1992,13 @@ bool LyXText::read(Buffer const & buf, LyXLex & lex)
|
||||
|
||||
int LyXText::ascent() const
|
||||
{
|
||||
return firstRow().ascent_of_text();
|
||||
return dim_.asc;
|
||||
}
|
||||
|
||||
|
||||
int LyXText::descent() const
|
||||
{
|
||||
return height_ - firstRow().ascent_of_text();
|
||||
return dim_.des;
|
||||
}
|
||||
|
||||
|
||||
@ -1916,10 +2006,10 @@ int LyXText::cursorX(CursorSlice const & cur) const
|
||||
{
|
||||
pit_type const pit = cur.pit();
|
||||
Paragraph const & par = pars_[pit];
|
||||
if (par.rows.empty())
|
||||
return xo_;
|
||||
if (par.rows().empty())
|
||||
return 0;
|
||||
|
||||
Row const & row = *par.getRow(cur.pos());
|
||||
Row const & row = par.getRow(cur.pos());
|
||||
|
||||
pos_type pos = cur.pos();
|
||||
pos_type cursor_vpos = 0;
|
||||
@ -1971,15 +2061,21 @@ int LyXText::cursorX(CursorSlice const & cur) const
|
||||
} else
|
||||
x += singleWidth(par, pos);
|
||||
}
|
||||
return xo_ + int(x);
|
||||
return int(x);
|
||||
}
|
||||
|
||||
|
||||
int LyXText::cursorY(CursorSlice const & cur) const
|
||||
{
|
||||
Paragraph const & par = getPar(cur.pit());
|
||||
Row const & row = *par.getRow(cur.pos());
|
||||
return yo_ + par.y + row.y_offset() + row.baseline();
|
||||
int h = 0;
|
||||
h -= pars_[0].rows()[0].ascent();
|
||||
for (pit_type pit = 0; pit < cur.pit(); ++pit)
|
||||
h += pars_[pit].height();
|
||||
for (size_t rit = 0, rend = par.pos2row(cur.pos()); rit != rend; ++rit)
|
||||
h += par.rows()[rit].height();
|
||||
h += par.rows()[par.pos2row(cur.pos())].ascent();
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
@ -2051,8 +2147,8 @@ string LyXText::currentState(LCursor & cur)
|
||||
os << _(", Paragraph: ") << cur.pit();
|
||||
os << _(", Id: ") << par.id();
|
||||
os << _(", Position: ") << cur.pos();
|
||||
Row & row = cur.textRow();
|
||||
os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos());
|
||||
// Row & row = cur.textRow();
|
||||
// os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos());
|
||||
#endif
|
||||
return os.str();
|
||||
}
|
||||
@ -2096,25 +2192,66 @@ string LyXText::getPossibleLabel(LCursor & cur) const
|
||||
}
|
||||
|
||||
|
||||
// Manhattan distance to nearest corner
|
||||
int LyXText::dist(int x, int y) const
|
||||
//pos_type LyXText::x2pos(pit_type pit, int row, int x) const
|
||||
//{
|
||||
// int lastx = 0;
|
||||
// int currx = 0;
|
||||
// Paragraph const & par = pars_[pit];
|
||||
// Row const & r = par.rows()[row];
|
||||
// int pos = r.pos();
|
||||
// for (; currx < x && pos < r.endpos(); ++pos) {
|
||||
// lastx = currx;
|
||||
// currx += singleWidth(par, pos);
|
||||
// }
|
||||
// if (abs(lastx - x) < abs(currx - x) && pos != r.pos())
|
||||
// --pos;
|
||||
// return pos;
|
||||
//}
|
||||
|
||||
|
||||
pos_type LyXText::x2pos(pit_type pit, int row, int x) const
|
||||
{
|
||||
int xx = 0;
|
||||
int yy = 0;
|
||||
|
||||
if (x < xo_)
|
||||
xx = xo_ - x;
|
||||
else if (x > xo_ + int(width_))
|
||||
xx = x - xo_ - width_;
|
||||
|
||||
if (y < yo_ - ascent())
|
||||
yy = yo_ - ascent() - y;
|
||||
else if (y > yo_ + descent())
|
||||
yy = y - yo_ - descent();
|
||||
|
||||
lyxerr << " xo_=" << xo_ << " yo_=" << yo_
|
||||
<< " width_=" << width_ << " ascent=" << ascent()
|
||||
<< " descent=" << descent()
|
||||
<< " dist=" << xx+yy <<endl;
|
||||
return xx + yy;
|
||||
bool bound = false;
|
||||
Row const & r = pars_[pit].rows()[row];
|
||||
return r.pos() + getColumnNearX(pit, r, x, bound);
|
||||
}
|
||||
|
||||
|
||||
//int LyXText::pos2x(pit_type pit, pos_type pos) const
|
||||
//{
|
||||
// Paragraph const & par = pars_[pit];
|
||||
// Row const & r = par.rows()[row];
|
||||
// int x = 0;
|
||||
// pos -= r.pos();
|
||||
//}
|
||||
|
||||
|
||||
// x,y are screen coordinates
|
||||
// sets cursor only within this LyXText
|
||||
void LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y)
|
||||
{
|
||||
pit_type pit = getPitNearY(y);
|
||||
int yy = theCoords.get(this, pit).y_ - pars_[pit].ascent();
|
||||
lyxerr << "setCursorFromCoordinates: x: " << x << " y: " << y
|
||||
<< " pit: " << pit << " yy: " << yy << endl;
|
||||
|
||||
Paragraph const & par = pars_[pit];
|
||||
int r = 0;
|
||||
BOOST_ASSERT(par.rows().size());
|
||||
for (; r < int(par.rows().size()) - 1; ++r) {
|
||||
Row const & row = par.rows()[r];
|
||||
if (int(yy + row.height()) > y)
|
||||
break;
|
||||
yy += row.height();
|
||||
}
|
||||
|
||||
Row const & row = par.rows()[r];
|
||||
|
||||
lyxerr << "setCursorFromCoordinates: row " << r
|
||||
<< " from pos: " << row.pos() << endl;
|
||||
|
||||
bool bound = false;
|
||||
int xx = x;
|
||||
pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
|
||||
setCursor(cur, pit, pos, true, bound);
|
||||
}
|
||||
|
252
src/text2.C
252
src/text2.C
@ -72,9 +72,9 @@ using std::string;
|
||||
|
||||
|
||||
LyXText::LyXText(BufferView * bv)
|
||||
: width_(0), maxwidth_(bv ? bv->workWidth() : 100), height_(0),
|
||||
: maxwidth_(bv ? bv->workWidth() : 100),
|
||||
background_color_(LColor::background),
|
||||
bv_owner(bv), xo_(0), yo_(0)
|
||||
bv_owner(bv)
|
||||
{}
|
||||
|
||||
|
||||
@ -83,15 +83,15 @@ void LyXText::init(BufferView * bv)
|
||||
BOOST_ASSERT(bv);
|
||||
bv_owner = bv;
|
||||
maxwidth_ = bv->workWidth();
|
||||
width_ = maxwidth_;
|
||||
height_ = 0;
|
||||
dim_.wid = maxwidth_;
|
||||
dim_.asc = 10;
|
||||
dim_.des = 10;
|
||||
|
||||
pit_type const end = paragraphs().size();
|
||||
for (pit_type pit = 0; pit != end; ++pit)
|
||||
pars_[pit].rows.clear();
|
||||
pars_[pit].rows().clear();
|
||||
|
||||
current_font = getFont(pars_[0], 0);
|
||||
redoParagraphs(0, end);
|
||||
updateCounters();
|
||||
}
|
||||
|
||||
@ -102,40 +102,35 @@ bool LyXText::isMainText() const
|
||||
}
|
||||
|
||||
|
||||
// takes absolute x,y coordinates
|
||||
//takes screen x,y coordinates
|
||||
InsetBase * LyXText::checkInsetHit(int x, int y) const
|
||||
{
|
||||
pit_type pit;
|
||||
pit_type end;
|
||||
pit_type pit = getPitNearY(y);
|
||||
BOOST_ASSERT(pit != -1);
|
||||
|
||||
getParsInRange(paragraphs(),
|
||||
bv()->top_y() - yo_,
|
||||
bv()->top_y() - yo_ + bv()->workHeight(),
|
||||
pit, end);
|
||||
Paragraph const & par = pars_[pit];
|
||||
|
||||
// convert to screen-absolute y coordinate
|
||||
y -= bv()->top_y();
|
||||
lyxerr << "checkInsetHit: x: " << x << " y: " << y << endl;
|
||||
lyxerr << " pit: " << pit << " end: " << end << endl;
|
||||
for (; pit != end; ++pit) {
|
||||
InsetList::const_iterator iit = pars_[pit].insetlist.begin();
|
||||
InsetList::const_iterator iend = pars_[pit].insetlist.end();
|
||||
for (; iit != iend; ++iit) {
|
||||
InsetBase * inset = iit->inset;
|
||||
lyxerr << " pit: " << pit << endl;
|
||||
InsetList::const_iterator iit = par.insetlist.begin();
|
||||
InsetList::const_iterator iend = par.insetlist.end();
|
||||
for (; iit != iend; ++iit) {
|
||||
InsetBase * inset = iit->inset;
|
||||
#if 1
|
||||
lyxerr << "examining inset " << inset << endl;
|
||||
if (theCoords.insets_.has(inset))
|
||||
lyxerr
|
||||
<< " xo: " << inset->xo() << "..." << inset->xo() + inset->width()
|
||||
<< " yo: " << inset->yo() - inset->ascent() << "..."
|
||||
<< inset->yo() + inset->descent() << endl;
|
||||
else
|
||||
lyxerr << " inset has no cached position";
|
||||
lyxerr << "examining inset " << inset << endl;
|
||||
if (theCoords.insets_.has(inset))
|
||||
lyxerr
|
||||
<< " xo: " << inset->xo() << "..."
|
||||
<< inset->xo() + inset->width()
|
||||
<< " yo: " << inset->yo() - inset->ascent()
|
||||
<< "..."
|
||||
<< inset->yo() + inset->descent() << endl;
|
||||
else
|
||||
lyxerr << " inset has no cached position" << endl;
|
||||
#endif
|
||||
if (inset->covers(x, y)) {
|
||||
lyxerr << "Hit inset: " << inset << endl;
|
||||
return inset;
|
||||
}
|
||||
if (inset->covers(x, y)) {
|
||||
lyxerr << "Hit inset: " << inset << endl;
|
||||
return inset;
|
||||
}
|
||||
}
|
||||
lyxerr << "No inset hit. " << endl;
|
||||
@ -341,7 +336,6 @@ void LyXText::setLayout(LCursor & cur, string const & layout)
|
||||
pit_type start = cur.selBegin().pit();
|
||||
pit_type end = cur.selEnd().pit() + 1;
|
||||
pit_type endpit = setLayout(start, end, layout);
|
||||
redoParagraphs(start, endpit);
|
||||
updateCounters();
|
||||
}
|
||||
|
||||
@ -408,14 +402,15 @@ void LyXText::changeDepth(LCursor & cur, DEPTH_CHANGE type)
|
||||
max_depth = pars_[beg - 1].getMaxDepthAfter();
|
||||
|
||||
for (pit_type pit = beg; pit != end; ++pit) {
|
||||
if (::changeDepthAllowed(type, pars_[pit], max_depth)) {
|
||||
int const depth = pars_[pit].params().depth();
|
||||
Paragraph & par = pars_[pit];
|
||||
if (::changeDepthAllowed(type, par, max_depth)) {
|
||||
int const depth = par.params().depth();
|
||||
if (type == INC_DEPTH)
|
||||
pars_[pit].params().depth(depth + 1);
|
||||
par.params().depth(depth + 1);
|
||||
else
|
||||
pars_[pit].params().depth(depth - 1);
|
||||
par.params().depth(depth - 1);
|
||||
}
|
||||
max_depth = pars_[pit].getMaxDepthAfter();
|
||||
max_depth = par.getMaxDepthAfter();
|
||||
}
|
||||
// this handles the counter labels, and also fixes up
|
||||
// depth values for follow-on (child) paragraphs
|
||||
@ -454,9 +449,6 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall)
|
||||
// Ok, we have a selection.
|
||||
recordUndoSelection(cur);
|
||||
|
||||
pit_type const beg = cur.selBegin().pit();
|
||||
pit_type const end = cur.selEnd().pit();
|
||||
|
||||
DocIterator dit = cur.selectionBegin();
|
||||
DocIterator ditend = cur.selectionEnd();
|
||||
|
||||
@ -471,8 +463,6 @@ void LyXText::setFont(LCursor & cur, LyXFont const & font, bool toggleall)
|
||||
setCharFont(dit.pit(), dit.pos(), f);
|
||||
}
|
||||
}
|
||||
|
||||
redoParagraphs(beg, end + 1);
|
||||
}
|
||||
|
||||
|
||||
@ -491,6 +481,7 @@ void LyXText::cursorEnd(LCursor & cur)
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
// if not on the last row of the par, put the cursor before
|
||||
// the final space
|
||||
// FIXME: does this final space exist?
|
||||
pos_type const end = cur.textRow().endpos();
|
||||
setCursor(cur, cur.pit(), end == cur.lastpos() ? end : end - 1);
|
||||
}
|
||||
@ -602,8 +593,6 @@ void LyXText::setParagraph(LCursor & cur,
|
||||
par.setLabelWidthString(labelwidthstring);
|
||||
params.noindent(noindent);
|
||||
}
|
||||
|
||||
redoParagraphs(cur.selBegin().pit(), undopit);
|
||||
}
|
||||
|
||||
|
||||
@ -897,12 +886,9 @@ void LyXText::updateCounters()
|
||||
if (oldLabel != newLabel) {
|
||||
//lyxerr[Debug::DEBUG] << "changing labels: old: " << oldLabel << " new: "
|
||||
// << newLabel << endl;
|
||||
redoParagraphInternal(pit);
|
||||
update_pos = true;
|
||||
}
|
||||
}
|
||||
if (update_pos)
|
||||
updateParPositions();
|
||||
}
|
||||
|
||||
|
||||
@ -912,7 +898,6 @@ void LyXText::insertInset(LCursor & cur, InsetBase * inset)
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
BOOST_ASSERT(inset);
|
||||
cur.paragraph().insertInset(cur.pos(), inset);
|
||||
redoParagraph(cur);
|
||||
}
|
||||
|
||||
|
||||
@ -920,7 +905,6 @@ void LyXText::insertInset(LCursor & cur, InsetBase * inset)
|
||||
void LyXText::insertStringAsLines(LCursor & cur, string const & str)
|
||||
{
|
||||
pit_type pit = cur.pit();
|
||||
pit_type endpit = cur.pit() + 1;
|
||||
pos_type pos = cur.pos();
|
||||
recordUndo(cur);
|
||||
|
||||
@ -928,7 +912,6 @@ void LyXText::insertStringAsLines(LCursor & cur, string const & str)
|
||||
cur.clearSelection();
|
||||
cur.buffer().insertStringAsLines(pars_, pit, pos, current_font, str);
|
||||
|
||||
redoParagraphs(cur.pit(), endpit);
|
||||
cur.resetAnchor();
|
||||
setCursor(cur, cur.pit(), pos);
|
||||
cur.setSelection();
|
||||
@ -975,19 +958,12 @@ void LyXText::setCursor(CursorSlice & cur, pit_type par,
|
||||
pos_type pos, bool boundary)
|
||||
{
|
||||
BOOST_ASSERT(par != int(paragraphs().size()));
|
||||
|
||||
cur.pit() = par;
|
||||
cur.pos() = pos;
|
||||
cur.boundary() = boundary;
|
||||
|
||||
// no rows, no fun...
|
||||
if (paragraphs().begin()->rows.empty())
|
||||
return;
|
||||
|
||||
// now some strict checking
|
||||
Paragraph & para = getPar(par);
|
||||
Row const & row = *para.getRow(pos);
|
||||
pos_type const end = row.endpos();
|
||||
|
||||
// None of these should happen, but we're scaredy-cats
|
||||
if (pos < 0) {
|
||||
@ -998,24 +974,6 @@ void LyXText::setCursor(CursorSlice & cur, pit_type par,
|
||||
if (pos > para.size()) {
|
||||
lyxerr << "dont like 1, pos: " << pos
|
||||
<< " size: " << para.size()
|
||||
<< " row.pos():" << row.pos()
|
||||
<< " par: " << par << endl;
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
if (pos > end) {
|
||||
lyxerr << "dont like 2, pos: " << pos
|
||||
<< " size: " << para.size()
|
||||
<< " row.pos():" << row.pos()
|
||||
<< " par: " << par << endl;
|
||||
// This shouldn't happen.
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
|
||||
if (pos < row.pos()) {
|
||||
lyxerr << "dont like 3 please report pos:" << pos
|
||||
<< " size: " << para.size()
|
||||
<< " row.pos():" << row.pos()
|
||||
<< " par: " << par << endl;
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
@ -1026,7 +984,7 @@ void LyXText::setCursorIntern(LCursor & cur,
|
||||
pit_type par, pos_type pos, bool setfont, bool boundary)
|
||||
{
|
||||
setCursor(cur.top(), par, pos, boundary);
|
||||
cur.x_target() = cursorX(cur.top());
|
||||
cur.setTargetX();
|
||||
if (setfont)
|
||||
setCurrentFont(cur);
|
||||
}
|
||||
@ -1077,7 +1035,8 @@ void LyXText::setCurrentFont(LCursor & cur)
|
||||
pos_type LyXText::getColumnNearX(pit_type const pit,
|
||||
Row const & row, int & x, bool & boundary) const
|
||||
{
|
||||
x -= xo_;
|
||||
int const xo = theCoords.get(this, pit).x_;
|
||||
x -= xo;
|
||||
RowMetrics const r = computeRowMetrics(pit, row);
|
||||
Paragraph const & par = pars_[pit];
|
||||
|
||||
@ -1099,7 +1058,7 @@ pos_type LyXText::getColumnNearX(pit_type const pit,
|
||||
|
||||
// check for empty row
|
||||
if (vc == end) {
|
||||
x = int(tmpx) + xo_;
|
||||
x = int(tmpx) + xo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1169,55 +1128,59 @@ pos_type LyXText::getColumnNearX(pit_type const pit,
|
||||
c = end - 1;
|
||||
}
|
||||
|
||||
x = int(tmpx) + xo_;
|
||||
x = int(tmpx) + xo;
|
||||
return c - row.pos();
|
||||
}
|
||||
|
||||
|
||||
// y is relative to this LyXText's top
|
||||
// this is only used in the two functions below
|
||||
Row const & LyXText::getRowNearY(int y, pit_type & pit) const
|
||||
// y is screen coordinate
|
||||
pit_type LyXText::getPitNearY(int y) const
|
||||
{
|
||||
BOOST_ASSERT(!paragraphs().empty());
|
||||
BOOST_ASSERT(!paragraphs().begin()->rows.empty());
|
||||
pit_type const pend = paragraphs().size() - 1;
|
||||
pit = 0;
|
||||
while (int(pars_[pit].y + pars_[pit].height) < y && pit != pend)
|
||||
++pit;
|
||||
BOOST_ASSERT(theCoords.pars_.find(this) != theCoords.pars_.end());
|
||||
CoordCache::InnerParPosCache const & cc = theCoords.pars_[this];
|
||||
lyxerr << "LyXText::getPitNearY: y: " << y << " cache size: "
|
||||
<< cc.size() << endl;
|
||||
|
||||
RowList::iterator rit = pars_[pit].rows.end();
|
||||
RowList::iterator const rbegin = pars_[pit].rows.begin();
|
||||
do {
|
||||
--rit;
|
||||
} while (rit != rbegin && int(pars_[pit].y + rit->y_offset()) > y);
|
||||
// look for highest numbered paragraph with y coordinate less than given y
|
||||
pit_type pit = 0;
|
||||
int yy = -1;
|
||||
CoordCache::InnerParPosCache::const_iterator it = cc.begin();
|
||||
CoordCache::InnerParPosCache::const_iterator et = cc.end();
|
||||
for (; it != et; ++it) {
|
||||
lyxerr << " examining: pit: " << it->first << " y: "
|
||||
<< it->second.y_ << endl;
|
||||
if (it->first >= pit && int(it->second.y_) - int(pars_[it->first].ascent()) <= y) {
|
||||
pit = it->first;
|
||||
yy = it->second.y_;
|
||||
}
|
||||
}
|
||||
|
||||
lyxerr << " found best y: " << yy << " for pit: " << pit << endl;
|
||||
return pit;
|
||||
}
|
||||
|
||||
|
||||
Row const & LyXText::getRowNearY(int y, pit_type pit) const
|
||||
{
|
||||
Paragraph const & par = pars_[pit];
|
||||
int yy = theCoords.get(this, pit).y_ - par.ascent();
|
||||
BOOST_ASSERT(!par.rows().empty());
|
||||
RowList::const_iterator rit = par.rows().begin();
|
||||
RowList::const_iterator const rlast = boost::prior(par.rows().end());
|
||||
for (; rit != rlast; yy += rit->height(), ++rit)
|
||||
if (yy + rit->height() > y)
|
||||
break;
|
||||
return *rit;
|
||||
}
|
||||
|
||||
|
||||
// x,y are absolute coordinates
|
||||
// sets cursor only within this LyXText
|
||||
void LyXText::setCursorFromCoordinates(LCursor & cur, int x, int y)
|
||||
{
|
||||
x -= xo_;
|
||||
y -= yo_;
|
||||
pit_type pit;
|
||||
Row const & row = getRowNearY(y, pit);
|
||||
lyxerr[Debug::DEBUG] << "setCursorFromCoordinates:: hit row at: "
|
||||
<< row.pos() << endl;
|
||||
bool bound = false;
|
||||
int xx = x + xo_; // getRowNearX get absolute x coords
|
||||
pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
|
||||
setCursor(cur, pit, pos, true, bound);
|
||||
}
|
||||
|
||||
|
||||
// x,y are absolute screen coordinates
|
||||
// sets cursor recursively descending into nested editable insets
|
||||
InsetBase * LyXText::editXY(LCursor & cur, int x, int y) const
|
||||
{
|
||||
pit_type pit;
|
||||
Row const & row = getRowNearY(y - yo_, pit);
|
||||
pit_type pit = getPitNearY(y);
|
||||
BOOST_ASSERT(pit != -1);
|
||||
Row const & row = getRowNearY(y, pit);
|
||||
bool bound = false;
|
||||
|
||||
int xx = x; // is modified by getColumnNearX
|
||||
@ -1225,13 +1188,18 @@ InsetBase * LyXText::editXY(LCursor & cur, int x, int y) const
|
||||
cur.pit() = pit;
|
||||
cur.pos() = pos;
|
||||
cur.boundary() = bound;
|
||||
cur.x_target() = x;
|
||||
|
||||
// try to descend into nested insets
|
||||
InsetBase * inset = checkInsetHit(x, y);
|
||||
lyxerr << "inset " << inset << " hit at x: " << x << " y: " << y << endl;
|
||||
if (!inset)
|
||||
if (!inset) {
|
||||
//either we deconst editXY or better we move current_font
|
||||
//and real_current_font to LCursor
|
||||
const_cast<LyXText *>(this)->setCurrentFont(cur);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// This should be just before or just behind the
|
||||
// cursor position set above.
|
||||
BOOST_ASSERT((pos != 0 && inset == pars_[pit].getInset(pos - 1))
|
||||
@ -1240,7 +1208,10 @@ InsetBase * LyXText::editXY(LCursor & cur, int x, int y) const
|
||||
// this inset.
|
||||
if (inset == pars_[pit].getInset(pos - 1))
|
||||
--cur.pos();
|
||||
return inset->editXY(cur, x, y);
|
||||
inset = inset->editXY(cur, x, y);
|
||||
if (cur.top().text() == this)
|
||||
const_cast<LyXText *>(this)->setCurrentFont(cur);
|
||||
return inset;
|
||||
}
|
||||
|
||||
|
||||
@ -1302,31 +1273,50 @@ void LyXText::cursorRight(LCursor & cur)
|
||||
|
||||
void LyXText::cursorUp(LCursor & cur)
|
||||
{
|
||||
Row const & row = cur.textRow();
|
||||
int x = cur.x_target();
|
||||
int y = cursorY(cur.top()) - row.baseline() - 1;
|
||||
setCursorFromCoordinates(cur, x, y);
|
||||
Paragraph const & par = cur.paragraph();
|
||||
int const row = par.pos2row(cur.pos());
|
||||
int const x = cur.targetX();
|
||||
|
||||
if (!cur.selection()) {
|
||||
InsetBase * inset_hit = checkInsetHit(cur.x_target(), y);
|
||||
if (inset_hit && isHighlyEditableInset(inset_hit))
|
||||
inset_hit->editXY(cur, cur.x_target(), y);
|
||||
int const y = bv_funcs::getPos(cur).y_;
|
||||
editXY(cur, x, y - par.rows()[row].ascent() - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (row > 0) {
|
||||
setCursor(cur, cur.pit(), x2pos(cur.pit(), row - 1, x));
|
||||
} else if (cur.pit() > 0) {
|
||||
--cur.pit();
|
||||
setCursor(cur, cur.pit(), x2pos(cur.pit(), cur.paragraph().rows().size() - 1, x));
|
||||
|
||||
}
|
||||
|
||||
cur.x_target() = x;
|
||||
}
|
||||
|
||||
|
||||
void LyXText::cursorDown(LCursor & cur)
|
||||
{
|
||||
Row const & row = cur.textRow();
|
||||
int x = cur.x_target();
|
||||
int y = cursorY(cur.top()) - row.baseline() + row.height() + 1;
|
||||
setCursorFromCoordinates(cur, x, y);
|
||||
|
||||
|
||||
Paragraph const & par = cur.paragraph();
|
||||
int const row = par.pos2row(cur.pos());
|
||||
int const x = cur.targetX();
|
||||
|
||||
if (!cur.selection()) {
|
||||
InsetBase * inset_hit = checkInsetHit(cur.x_target(), y);
|
||||
if (inset_hit && isHighlyEditableInset(inset_hit))
|
||||
inset_hit->editXY(cur, cur.x_target(), y);
|
||||
int const y = bv_funcs::getPos(cur).y_;
|
||||
editXY(cur, x, y + par.rows()[row].descent() + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (row + 1 < int(par.rows().size())) {
|
||||
setCursor(cur, cur.pit(), x2pos(cur.pit(), row + 1, x));
|
||||
} else if (cur.pit() + 1 < int(paragraphs().size())) {
|
||||
++cur.pit();
|
||||
setCursor(cur, cur.pit(), x2pos(cur.pit(), 0, x));
|
||||
}
|
||||
|
||||
cur.x_target() = x;
|
||||
}
|
||||
|
||||
|
||||
|
115
src/text3.C
115
src/text3.C
@ -143,15 +143,17 @@ namespace {
|
||||
BOOST_ASSERT(old_pos == cur.pos());
|
||||
cur.nextInset()->edit(cur, true);
|
||||
cur.dispatch(FuncRequest(LFUN_MATH_MUTATE, "simple"));
|
||||
// don't do that also for LFUN_MATH_MODE unless you want end up with
|
||||
// always changing to mathrm when opening an inlined inset
|
||||
// -- I really hate "LyXfunc overloading"...
|
||||
// don't do that also for LFUN_MATH_MODE
|
||||
// unless you want end up with always changing
|
||||
// to mathrm when opening an inlined inset --
|
||||
// I really hate "LyXfunc overloading"...
|
||||
if (display)
|
||||
cur.dispatch(FuncRequest(LFUN_MATH_DISPLAY));
|
||||
cur.dispatch(FuncRequest(LFUN_INSERT_MATH, cmd.argument));
|
||||
} else {
|
||||
// create a macro if we see "\\newcommand" somewhere, and an ordinary
|
||||
// formula otherwise
|
||||
// create a macro if we see "\\newcommand"
|
||||
// somewhere, and an ordinary formula
|
||||
// otherwise
|
||||
cutSelection(cur, true, true);
|
||||
if (sel.find("\\newcommand") == string::npos
|
||||
&& sel.find("\\def") == string::npos)
|
||||
@ -261,8 +263,9 @@ void LyXText::cursorPrevious(LCursor & cur)
|
||||
lyx::pit_type cpar = cur.pit();
|
||||
|
||||
int x = cur.x_target();
|
||||
int y = cur.bv().top_y();
|
||||
setCursorFromCoordinates(cur, x, y);
|
||||
|
||||
setCursorFromCoordinates(cur, x, 0);
|
||||
cursorUp(cur);
|
||||
|
||||
if (cpar == cur.pit() && cpos == cur.pos()) {
|
||||
// we have a row which is taller than the workarea. The
|
||||
@ -281,8 +284,8 @@ void LyXText::cursorNext(LCursor & cur)
|
||||
lyx::pit_type cpar = cur.pit();
|
||||
|
||||
int x = cur.x_target();
|
||||
int y = cur.bv().top_y() + cur.bv().workHeight();
|
||||
setCursorFromCoordinates(cur, x, y);
|
||||
setCursorFromCoordinates(cur, x, cur.bv().workHeight() - 1);
|
||||
cursorDown(cur);
|
||||
|
||||
if (cpar == cur.pit() && cpos == cur.pos()) {
|
||||
// we have a row which is taller than the workarea. The
|
||||
@ -327,6 +330,15 @@ void doInsertInset(LCursor & cur, LyXText * text,
|
||||
cur.bv().owner()->dispatch(FuncRequest(LFUN_PASTE));
|
||||
}
|
||||
|
||||
|
||||
void update(LCursor & cur)
|
||||
{
|
||||
//we don't call update(true, false) directly to save a metrics call
|
||||
if (cur.bv().fitCursor())
|
||||
cur.bv().update(false, true);
|
||||
}
|
||||
|
||||
|
||||
} // anon namespace
|
||||
|
||||
|
||||
@ -366,7 +378,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
if (pars_[tmp].params().startOfAppendix()) {
|
||||
recUndo(tmp);
|
||||
pars_[tmp].params().startOfAppendix(false);
|
||||
redoParagraph(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -376,7 +387,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
|
||||
// we can set the refreshing parameters now
|
||||
updateCounters();
|
||||
redoParagraph(cur);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -431,6 +441,17 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_BEGINNINGBUFSEL:
|
||||
if (cur.size() == 1) {
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorTop(cur);
|
||||
finishChange(cur, true);
|
||||
} else {
|
||||
cur.undispatched();
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_ENDBUF:
|
||||
if (cur.size() == 1) {
|
||||
if (!cur.mark())
|
||||
@ -441,6 +462,17 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
cur.undispatched();
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_ENDBUFSEL:
|
||||
if (cur.size() == 1) {
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorBottom(cur);
|
||||
finishChange(cur, true);
|
||||
} else {
|
||||
cur.undispatched();
|
||||
}
|
||||
break;
|
||||
|
||||
case LFUN_RIGHT:
|
||||
moving = true;
|
||||
@ -475,6 +507,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
case LFUN_UP:
|
||||
moving = true;
|
||||
case LFUN_UPSEL:
|
||||
update(cur);
|
||||
//lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl;
|
||||
cur.selHandle(cmd.action == LFUN_UPSEL);
|
||||
cursorUp(cur);
|
||||
@ -487,6 +520,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
case LFUN_DOWN:
|
||||
moving = true;
|
||||
case LFUN_DOWNSEL:
|
||||
update(cur);
|
||||
//lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl;
|
||||
cur.selHandle(cmd.action == LFUN_DOWNSEL);
|
||||
cursorDown(cur);
|
||||
@ -511,6 +545,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_PRIORSEL:
|
||||
update(cur);
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorPrevious(cur);
|
||||
@ -518,6 +553,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_NEXTSEL:
|
||||
update(cur);
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorNext(cur);
|
||||
@ -525,6 +561,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_HOMESEL:
|
||||
update(cur);
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorHome(cur);
|
||||
@ -532,6 +569,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_ENDSEL:
|
||||
update(cur);
|
||||
if (!cur.selection())
|
||||
cur.resetAnchor();
|
||||
cursorEnd(cur);
|
||||
@ -581,6 +619,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_PRIOR:
|
||||
update(cur);
|
||||
moving = true;
|
||||
if (!cur.mark())
|
||||
cur.clearSelection();
|
||||
@ -594,6 +633,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
|
||||
case LFUN_NEXT:
|
||||
update(cur);
|
||||
moving = true;
|
||||
if (!cur.mark())
|
||||
cur.clearSelection();
|
||||
@ -748,10 +788,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
lyxerr << _("Unknown spacing argument: ")
|
||||
<< cmd.argument << endl;
|
||||
}
|
||||
if (cur_spacing != new_spacing || cur_value != new_value) {
|
||||
if (cur_spacing != new_spacing || cur_value != new_value)
|
||||
par.params().spacing(Spacing(new_spacing, new_value));
|
||||
redoParagraph(cur);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -843,7 +881,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
|
||||
case LFUN_TRANSPOSE_CHARS:
|
||||
recordUndo(cur);
|
||||
redoParagraph(cur);
|
||||
break;
|
||||
|
||||
case LFUN_PASTE:
|
||||
@ -1091,7 +1128,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
setCursorFromCoordinates(cur, cmd.x, cmd.y);
|
||||
cur.resetAnchor();
|
||||
finishUndo();
|
||||
cur.x_target() = cursorX(cur.top());
|
||||
cur.setTargetX();
|
||||
|
||||
// Has the cursor just left the inset?
|
||||
if (bv->cursor().inMathed() && !cur.inMathed())
|
||||
@ -1101,8 +1138,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
bv->cursor() = cur;
|
||||
|
||||
// Don't allow selection after a big jump.
|
||||
if (bv->fitCursor())
|
||||
selection_possible = false;
|
||||
//if (bv->fitCursor())
|
||||
// selection_possible = false;
|
||||
|
||||
// Insert primary selection with middle mouse
|
||||
// if there is a local selection in the current buffer,
|
||||
@ -1134,23 +1171,36 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd)
|
||||
// ignore motions deeper nested than the real anchor
|
||||
LCursor & bvcur = cur.bv().cursor();
|
||||
if (bvcur.anchor_.hasPart(cur)) {
|
||||
CursorSlice old = cur.top();
|
||||
setCursorFromCoordinates(cur, cmd.x, cmd.y);
|
||||
CursorSlice old = bvcur.top();
|
||||
|
||||
int const wh = bv->workHeight();
|
||||
int const y = std::max(0, std::min(wh - 1, cmd.y));
|
||||
|
||||
setCursorFromCoordinates(cur, cmd.x, y);
|
||||
cur.x_target() = cmd.x;
|
||||
if (cmd.y >= wh)
|
||||
cursorDown(cur);
|
||||
else if (cmd.y < 0)
|
||||
cursorUp(cur);
|
||||
// This is to allow jumping over large insets
|
||||
// FIXME: shouldn't be top-text-specific
|
||||
if (isMainText() && cur.top() == old) {
|
||||
if (cmd.y - bv->top_y() >= bv->workHeight())
|
||||
if (cur.top() == old) {
|
||||
if (cmd.y >= wh)
|
||||
cursorDown(cur);
|
||||
else if (cmd.y - bv->top_y() < 0)
|
||||
else if (cmd.y < 0)
|
||||
cursorUp(cur);
|
||||
}
|
||||
|
||||
// don't set anchor_
|
||||
bv->cursor().setCursor(cur);
|
||||
bv->cursor().selection() = true;
|
||||
lyxerr << "MOTION: " << bv->cursor() << endl;
|
||||
}
|
||||
if (cur.top() == old)
|
||||
cur.noUpdate();
|
||||
else {
|
||||
// don't set anchor_
|
||||
bvcur.setCursor(cur);
|
||||
bvcur.selection() = true;
|
||||
lyxerr << "MOTION: " << bv->cursor() << endl;
|
||||
}
|
||||
|
||||
} else
|
||||
cur.undispatched();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1910,12 +1960,11 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd,
|
||||
case LFUN_PARAGRAPH_APPLY:
|
||||
case LFUN_ESCAPE:
|
||||
case LFUN_KEYMAP_TOGGLE:
|
||||
// these are handled in our dispatch()
|
||||
enable = true;
|
||||
break;
|
||||
|
||||
case LFUN_ENDBUF:
|
||||
case LFUN_BEGINNINGBUF:
|
||||
case LFUN_BEGINNINGBUFSEL:
|
||||
case LFUN_ENDBUFSEL:
|
||||
// these are handled in our dispatch()
|
||||
enable = true;
|
||||
break;
|
||||
|
||||
|
@ -55,7 +55,6 @@ void recordUndo(Undo::undo_kind kind,
|
||||
{
|
||||
if (first_pit > last_pit)
|
||||
std::swap(first_pit, last_pit);
|
||||
|
||||
// create the position information of the Undo entry
|
||||
Undo undo;
|
||||
undo.kind = kind;
|
||||
@ -105,6 +104,7 @@ void recordUndo(Undo::undo_kind kind,
|
||||
undo_finished = false;
|
||||
}
|
||||
|
||||
|
||||
void recordUndo(Undo::undo_kind kind,
|
||||
LCursor & cur, pit_type first_pit, pit_type last_pit,
|
||||
limited_stack<Undo> & stack)
|
||||
@ -281,8 +281,8 @@ void recordUndo(LCursor & cur, Undo::undo_kind kind,
|
||||
}
|
||||
|
||||
|
||||
void recordUndoFullDocument(LCursor &)
|
||||
void recordUndoFullDocument(LCursor & cur)
|
||||
{
|
||||
//recordUndo(Undo::ATOMIC,
|
||||
// cur, 0, cur.bv().text()->paragraphs().size() - 1);
|
||||
recordUndo(Undo::ATOMIC, cur, 0,
|
||||
cur.bv().text()->paragraphs().size() - 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user