Fix cursor navigation in math.

* metricsinfo.h:
  - ScreenUpdateStrategy: new enum describing the screen update strategy (replace singlepar boolean).

* UpdateFlags.h:
  new Update::Decoration flag.

* BufferView.C
  - update(): takes Decoration flag into account (CoordCache is not cleared out). Fills in metrics_info_.update_strategy

* mathed/InsetMathNest.C: adjust the cursor flags to new strategy.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16774 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Abdelrazak Younes 2007-01-20 01:23:07 +00:00
parent 5ed7e7a03c
commit d6cc04e762
5 changed files with 54 additions and 60 deletions

View File

@ -351,15 +351,30 @@ bool BufferView::update(Update::flags flags)
// Case when no explicit update is requested. // Case when no explicit update is requested.
if (!flags) { if (!flags) {
// no need to redraw anything. // no need to redraw anything.
metrics_info_.update_strategy = NoScreenUpdate;
return false; return false;
} }
if (flags == Update::FitCursor) { if (flags == Update::Decoration) {
metrics_info_.update_strategy = DecorationUpdate;
return true;
}
if (flags == Update::FitCursor
|| flags == (Update::Decoration | Update::FitCursor)) {
bool const fit_cursor = fitCursor(); bool const fit_cursor = fitCursor();
if (fit_cursor)
updateMetrics(false);
// tell the frontend to update the screen if needed. // tell the frontend to update the screen if needed.
return fit_cursor; if (fit_cursor) {
updateMetrics(false);
return true;
}
if (flags & Update::Decoration) {
metrics_info_.update_strategy = DecorationUpdate;
return true;
}
// no screen update is needed.
metrics_info_.update_strategy = NoScreenUpdate;
return false;
} }
bool full_metrics = flags & Update::Force; bool full_metrics = flags & Update::Force;
@ -1084,7 +1099,8 @@ bool BufferView::workAreaDispatch(FuncRequest const & cmd0)
// not expose the button for redraw. We adjust here the metrics dimension // not expose the button for redraw. We adjust here the metrics dimension
// to enable a full redraw. // to enable a full redraw.
// FIXME: It is possible to redraw only the area around the button! // FIXME: It is possible to redraw only the area around the button!
if (need_redraw && metrics_info_.singlepar) { if (need_redraw
&& metrics_info_.update_strategy == SingleParUpdate) {
// FIXME: It should be possible to redraw only the area around // FIXME: It should be possible to redraw only the area around
// the button by doing this: // the button by doing this:
// //
@ -1454,7 +1470,8 @@ void BufferView::updateMetrics(bool singlepar)
<< "size: " << size << "size: " << size
<< endl; << endl;
metrics_info_ = ViewMetricsInfo(pit1, pit2, y1, y2, singlepar, size); metrics_info_ = ViewMetricsInfo(pit1, pit2, y1, y2,
singlepar? SingleParUpdate: FullScreenUpdate, size);
if (lyxerr.debugging(Debug::WORKAREA)) { if (lyxerr.debugging(Debug::WORKAREA)) {
lyxerr[Debug::WORKAREA] << "BufferView::updateMetrics" << endl; lyxerr[Debug::WORKAREA] << "BufferView::updateMetrics" << endl;

View File

@ -20,7 +20,8 @@ namespace Update {
FitCursor = 1, FitCursor = 1,
Force = 2, Force = 2,
SinglePar = 4, SinglePar = 4,
MultiParSel = 8 MultiParSel = 8,
Decoration = 16
}; };
inline flags operator|(flags const f, flags const g) inline flags operator|(flags const f, flags const g)

View File

@ -499,11 +499,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
break; break;
case LFUN_CHAR_FORWARD: case LFUN_CHAR_FORWARD:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_CHAR_FORWARD_SELECT: case LFUN_CHAR_FORWARD_SELECT:
cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT);
cur.autocorrect() = false; cur.autocorrect() = false;
@ -522,11 +518,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
break; break;
case LFUN_CHAR_BACKWARD: case LFUN_CHAR_BACKWARD:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_CHAR_BACKWARD_SELECT: case LFUN_CHAR_BACKWARD_SELECT:
cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT);
cur.autocorrect() = false; cur.autocorrect() = false;
@ -546,11 +538,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
break; break;
case LFUN_UP: case LFUN_UP:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_UP_SELECT: case LFUN_UP_SELECT:
// FIXME Tried to use clearTargetX and macroModeClose, crashed on cur.up() // FIXME Tried to use clearTargetX and macroModeClose, crashed on cur.up()
if (cur.inMacroMode()) { if (cur.inMacroMode()) {
@ -568,11 +556,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
break; break;
case LFUN_DOWN: case LFUN_DOWN:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_DOWN_SELECT: case LFUN_DOWN_SELECT:
if (cur.inMacroMode()) { if (cur.inMacroMode()) {
cur.macroModeClose(); cur.macroModeClose();
@ -601,22 +585,14 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_UP:
case LFUN_PARAGRAPH_DOWN: case LFUN_PARAGRAPH_DOWN:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_PARAGRAPH_UP_SELECT: case LFUN_PARAGRAPH_UP_SELECT:
case LFUN_PARAGRAPH_DOWN_SELECT: case LFUN_PARAGRAPH_DOWN_SELECT:
break; break;
case LFUN_LINE_BEGIN: case LFUN_LINE_BEGIN:
case LFUN_WORD_BACKWARD: case LFUN_WORD_BACKWARD:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_LINE_BEGIN_SELECT: case LFUN_LINE_BEGIN_SELECT:
case LFUN_WORD_BACKWARD_SELECT: case LFUN_WORD_BACKWARD_SELECT:
cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT || cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT ||
@ -638,11 +614,7 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_WORD_FORWARD: case LFUN_WORD_FORWARD:
case LFUN_LINE_END: case LFUN_LINE_END:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
case LFUN_WORD_FORWARD_SELECT: case LFUN_WORD_FORWARD_SELECT:
case LFUN_LINE_END_SELECT: case LFUN_LINE_END_SELECT:
cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT || cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT ||
@ -676,20 +648,12 @@ void InsetMathNest::doDispatch(LCursor & cur, FuncRequest & cmd)
break; break;
case LFUN_CELL_FORWARD: case LFUN_CELL_FORWARD:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
cur.inset().idxNext(cur); cur.inset().idxNext(cur);
break; break;
case LFUN_CELL_BACKWARD: case LFUN_CELL_BACKWARD:
// FIXME: we have to enable full redraw here because of the cur.updateFlags(Update::Decoration | Update::FitCursor);
// visual box corners that define the inset. If we know for
// sure that we stay within the same cell we can optimize for
// that using:
//cur.updateFlags(Update::FitCursor);
cur.inset().idxPrev(cur); cur.inset().idxPrev(cur);
break; break;
@ -1184,7 +1148,7 @@ void InsetMathNest::lfunMousePress(LCursor & cur, FuncRequest & cmd)
bv.mouseSetCursor(cur); bv.mouseSetCursor(cur);
// FIXME: we have to enable full redraw here because of the // FIXME: we have to enable full redraw here because of the
// visual box corners that define the inset. // visual box corners that define the inset.
//cur.noUpdate(); cur.updateFlags(Update::Decoration | Update::FitCursor);
} else if (cmd.button() == mouse_button::button2) { } else if (cmd.button() == mouse_button::button2) {
MathArray ar; MathArray ar;
if (cur.selection()) { if (cur.selection()) {

View File

@ -100,22 +100,31 @@ public:
class TextMetricsInfo {}; class TextMetricsInfo {};
enum ScreenUpdateStrategy {
NoScreenUpdate,
SingleParUpdate,
FullScreenUpdate,
DecorationUpdate
};
class ViewMetricsInfo class ViewMetricsInfo
{ {
public: public:
ViewMetricsInfo() ViewMetricsInfo()
: p1(0), p2(0), y1(0), y2(0), singlepar(false), size(0) : p1(0), p2(0), y1(0), y2(0),
update_strategy(NoScreenUpdate), size(0)
{} {}
ViewMetricsInfo(pit_type p1, pit_type p2, int y1, int y2, ViewMetricsInfo(pit_type p1, pit_type p2, int y1, int y2,
bool singlepar, pit_type size) ScreenUpdateStrategy updatestrategy, pit_type size)
: p1(p1), p2(p2), y1(y1), y2(y2), singlepar(singlepar), size(size) : p1(p1), p2(p2), y1(y1), y2(y2),
update_strategy(update_strategy), size(size)
{} {}
pit_type p1; pit_type p1;
pit_type p2; pit_type p2;
int y1; int y1;
int y2; int y2;
bool singlepar; ScreenUpdateStrategy update_strategy;
pit_type size; pit_type size;
}; };

View File

@ -977,7 +977,10 @@ void paintText(BufferView & bv,
PainterInfo pi(const_cast<BufferView *>(&bv), pain); PainterInfo pi(const_cast<BufferView *>(&bv), pain);
// Should the whole screen, including insets, be refreshed? // Should the whole screen, including insets, be refreshed?
bool repaintAll = select || !vi.singlepar; // FIXME: We should also distinguish DecorationUpdate to avoid text
// drawing if possible. This is not possible to do easily right now
// because of the single backing pixmap.
bool repaintAll = select || vi.update_strategy != SingleParUpdate;
if (repaintAll) { if (repaintAll) {
// Clear background (if not delegated to rows) // Clear background (if not delegated to rows)
@ -1000,12 +1003,12 @@ void paintText(BufferView & bv,
// and grey out above (should not happen later) // and grey out above (should not happen later)
// lyxerr << "par ascent: " << text.getPar(vi.p1).ascent() << endl; // lyxerr << "par ascent: " << text.getPar(vi.p1).ascent() << endl;
if (vi.y1 > 0 && !vi.singlepar) if (vi.y1 > 0 && vi.update_strategy != SingleParUpdate)
pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, LColor::bottomarea); pain.fillRectangle(0, 0, bv.workWidth(), vi.y1, LColor::bottomarea);
// and possibly grey out below // and possibly grey out below
// lyxerr << "par descent: " << text.getPar(vi.p1).ascent() << endl; // lyxerr << "par descent: " << text.getPar(vi.p1).ascent() << endl;
if (vi.y2 < bv.workHeight() && !vi.singlepar) if (vi.y2 < bv.workHeight() && vi.update_strategy != SingleParUpdate)
pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea); pain.fillRectangle(0, vi.y2, bv.workWidth(), bv.workHeight() - vi.y2, LColor::bottomarea);
} }