From 37e164c6f9e792e51ceac0ad58885ee5b3758330 Mon Sep 17 00:00:00 2001 From: Asger Ottar Alstrup Date: Sun, 22 Oct 2006 11:46:36 +0000 Subject: [PATCH] - rework update handling, make cursor movement faster, fixing lots of navigation problems. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15470 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView.h | 22 +------- src/UpdateFlags.h | 28 ++++++++++ src/cursor.C | 15 +++--- src/cursor.h | 6 +-- src/dispatchresult.h | 12 +++-- src/frontends/controllers/ControlDocument.C | 1 + .../controllers/ControlSpellchecker.C | 1 + src/insets/insetbase.C | 2 +- src/insets/insettabular.C | 2 +- src/lyxfunc.C | 35 ++++++------ src/text3.C | 54 ++++++++----------- 11 files changed, 90 insertions(+), 88 deletions(-) create mode 100644 src/UpdateFlags.h diff --git a/src/BufferView.h b/src/BufferView.h index 5b74b4908a..75f5da0453 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -18,7 +18,7 @@ #include "coordcache.h" #include "cursor.h" #include "metricsinfo.h" - +#include "UpdateFlags.h" #include "support/types.h" #include @@ -41,26 +41,6 @@ class LyXText; class ParIterator; class ViewMetricsInfo; -namespace Update { - enum flags { - FitCursor = 1, - Force = 2, - SinglePar = 4, - MultiParSel = 8 - }; - -inline flags operator|(flags const f, flags const g) -{ - return static_cast(int(f) | int(g)); -} - -inline flags operator&(flags const f, flags const g) -{ - return static_cast(int(f) & int(g)); -} - -} // namespace - /// Scrollbar Parameters struct ScrollbarParameters { diff --git a/src/UpdateFlags.h b/src/UpdateFlags.h new file mode 100644 index 0000000000..3c8da08853 --- /dev/null +++ b/src/UpdateFlags.h @@ -0,0 +1,28 @@ +#ifndef UPDATE_FLAGS_H +#define UPDATE_FLAGS_H + +namespace lyx { + +namespace Update { + enum flags { + None = 0, + FitCursor = 1, + Force = 2, + SinglePar = 4, + MultiParSel = 8 + }; + +inline flags operator|(flags const f, flags const g) +{ + return static_cast(int(f) | int(g)); +} + +inline flags operator&(flags const f, flags const g) +{ + return static_cast(int(f) & int(g)); +} + +} // namespace + +} // namespace lyx +#endif diff --git a/src/cursor.C b/src/cursor.C index 69095b37ee..e63050cf7d 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -285,7 +285,7 @@ void LCursor::dispatch(FuncRequest const & cmd0) // The common case is 'LFUN handled, need update', so make the // LFUN handler's life easier by assuming this as default value. // The handler can reset the update and val flags if necessary. - disp_.update(true); + disp_.update(Update::FitCursor | Update::Force); disp_.dispatched(true); inset().dispatch(*this, cmd); if (disp_.dispatched()) @@ -296,7 +296,7 @@ void LCursor::dispatch(FuncRequest const & cmd0) if (!disp_.dispatched()) { lyxerr[Debug::DEBUG] << "RESTORING OLD CURSOR!" << endl; operator=(safe); - disp_.update(false); + disp_.update(Update::None); disp_.dispatched(false); } } @@ -527,14 +527,15 @@ void LCursor::info(odocstream & os) const } -void LCursor::selHandle(bool sel) +bool LCursor::selHandle(bool sel) { //lyxerr << "LCursor::selHandle" << endl; if (sel == selection()) - return; + return false; resetAnchor(); selection() = sel; + return true; } @@ -1212,15 +1213,15 @@ void LCursor::dispatched() } -void LCursor::needsUpdate() +void LCursor::updateFlags(Update::flags f) { - disp_.update(true); + disp_.update(f); } void LCursor::noUpdate() { - disp_.update(false); + disp_.update(Update::None); } diff --git a/src/cursor.h b/src/cursor.h index 1f22fc07d9..31ac8f4b64 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -86,7 +86,7 @@ public: /// access start of selection DocIterator selectionEnd() const; /// - void selHandle(bool selecting); + bool selHandle(bool selecting); // docstring selectionAsString(bool label) const; /// @@ -158,8 +158,8 @@ public: void undispatched(); /// the event was already dispatched void dispatched(); - /// call update() when done - void needsUpdate(); + /// Set which update should be done + void updateFlags(Update::flags f); /** * don't call update() when done * diff --git a/src/dispatchresult.h b/src/dispatchresult.h index d96fb92651..7b53ec1c85 100644 --- a/src/dispatchresult.h +++ b/src/dispatchresult.h @@ -13,28 +13,30 @@ #ifndef DISPATCH_RESULT_H #define DISPATCH_RESULT_H +#include "UpdateFlags.h" + namespace lyx { /// Maybe this can go entirely class DispatchResult { public: /// - DispatchResult() : dispatched_(false), update_(false) {} + DispatchResult() : dispatched_(false), update_(Update::None) {} /// - DispatchResult(bool disp, bool upd) : dispatched_(disp), update_(upd) {} + DispatchResult(bool disp, Update::flags f) : dispatched_(disp), update_(f) {} // bool dispatched() const { return dispatched_; } /// void dispatched(bool disp) { dispatched_ = disp; } /// - bool update() const { return update_; } + Update::flags update() const { return update_; } /// - void update(bool up) { update_ = up; } + void update(Update::flags f) { update_ = f; } private: /// was the event fully dispatched? bool dispatched_; /// do we need to redraw the screen afterwards? - bool update_; + Update::flags update_; }; diff --git a/src/frontends/controllers/ControlDocument.C b/src/frontends/controllers/ControlDocument.C index 97a9c20950..95d8e1ac4e 100644 --- a/src/frontends/controllers/ControlDocument.C +++ b/src/frontends/controllers/ControlDocument.C @@ -140,6 +140,7 @@ void ControlDocument::dispatchParams() "assign branch")); } // update the bufferview + // If we used an LFUN, we would not need that kernel().bufferview()->update(); } diff --git a/src/frontends/controllers/ControlSpellchecker.C b/src/frontends/controllers/ControlSpellchecker.C index 3a3a9118dc..3052fffead 100644 --- a/src/frontends/controllers/ControlSpellchecker.C +++ b/src/frontends/controllers/ControlSpellchecker.C @@ -306,6 +306,7 @@ void ControlSpellchecker::replace(string const & replacement) BufferView & bufferview = *kernel().bufferview(); cap::replaceSelectionWithString(bufferview.cursor(), replacement, true); kernel().buffer().markDirty(); + // If we used an LFUN, we would not need that bufferview.update(); // fix up the count --count_; diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index fb9a1b5fb7..249d6ddf3e 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -125,7 +125,7 @@ InsetBase::Code InsetBase::translate(std::string const & name) void InsetBase::dispatch(LCursor & cur, FuncRequest & cmd) { - cur.needsUpdate(); + cur.updateFlags(Update::Force | Update::FitCursor); cur.dispatched(); doDispatch(cur, cmd); } diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 4e9c51993d..6fbbb1c706 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -1251,7 +1251,7 @@ void InsetTabular::resetPos(LCursor & cur) const scx_ = 0; } - cur.needsUpdate(); + cur.updateFlags(Update::Force | Update::FitCursor); InsetTabularMailer(*this).updateDialog(&bv); } diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 2e24f7f156..771d801917 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -729,9 +729,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // redraw the screen at the end (first of the two drawing steps). //This is done unless explicitely requested otherwise - bool update = true; - // also do the second redrawing step. Only done if requested. - bool updateforce = false; + Update::flags updateFlags = Update::FitCursor; FuncStatus const flag = getStatus(cmd); if (!flag.enabled()) { @@ -819,12 +817,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd) lyx_view_->message(str + _(" done.")); } else writeAs(lyx_view_->buffer()); - update = false; + updateFlags = Update::None; break; case LFUN_BUFFER_WRITE_AS: writeAs(lyx_view_->buffer(), argument); - update = false; + updateFlags = Update::None; break; case LFUN_BUFFER_RELOAD: { @@ -1425,7 +1423,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } // ideally, the update flag should be set by the insets, // but this is not possible currently - updateforce = true; + updateFlags = Update::Force | Update::FitCursor; break; } @@ -1449,7 +1447,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) it->dispatch(tmpcur, fr); } } - updateforce = true; + updateFlags = Update::Force | Update::FitCursor; break; } @@ -1558,7 +1556,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) buffer->errors("Class Switch"); updateLabels(*buffer); - updateforce = true; + updateFlags = Update::Force | Update::FitCursor; break; } @@ -1589,10 +1587,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) default: { view()->cursor().dispatch(cmd); - update = false; - updateforce |= view()->cursor().result().update(); + updateFlags = view()->cursor().result().update(); if (!view()->cursor().result().dispatched()) - updateforce |= view()->dispatch(cmd); + if (view()->dispatch(cmd)) + updateFlags = Update::Force | Update::FitCursor; break; } } @@ -1601,13 +1599,16 @@ 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 (updateforce) - view()->update(Update::FitCursor | Update::Force); - else if (update) - view()->update(Update::FitCursor); + bool needSecondUpdate = false; + if (updateFlags != Update::None) + view()->update(updateFlags); + else + needSecondUpdate = view()->fitCursor(); - view()->buffer()->changed(); - lyx_view_->updateStatusBar(); + if (needSecondUpdate || updateFlags != Update::None) { + view()->buffer()->changed(); + lyx_view_->updateStatusBar(); + } // if we executed a mutating lfun, mark the buffer as dirty if (flag.enabled() diff --git a/src/text3.C b/src/text3.C index 4dc9fb87e5..9c61359588 100644 --- a/src/text3.C +++ b/src/text3.C @@ -283,14 +283,6 @@ bool doInsertInset(LCursor & cur, LyXText * text, } -void update(LCursor & cur) -{ - //we don't call update(true, false) directly to save a metrics call - if (cur.bv().fitCursor()) - cur.bv().update(Update::Force); -} - - } // anon namespace @@ -404,7 +396,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_BUFFER_BEGIN: case LFUN_BUFFER_BEGIN_SELECT: - cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT); if (cur.depth() == 1) { needsUpdate |= cursorTop(cur); } else { @@ -414,7 +406,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_BUFFER_END: case LFUN_BUFFER_END_SELECT: - cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT); if (cur.depth() == 1) { needsUpdate |= cursorBottom(cur); } else { @@ -426,7 +418,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CHAR_FORWARD_SELECT: //lyxerr << BOOST_CURRENT_FUNCTION // << " LFUN_CHAR_FORWARD[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); if (isRTL(cur.paragraph())) needsUpdate |= cursorLeft(cur); else @@ -442,7 +434,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CHAR_BACKWARD: case LFUN_CHAR_BACKWARD_SELECT: //lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); if (isRTL(cur.paragraph())) needsUpdate |= cursorRight(cur); else @@ -457,11 +449,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_UP: case LFUN_UP_SELECT: - update(cur); //lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_UP_SELECT); needsUpdate |= cursorUp(cur); + if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { cur.undispatched(); @@ -471,10 +463,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_DOWN: case LFUN_DOWN_SELECT: - update(cur); //lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_DOWN_SELECT); needsUpdate |= cursorDown(cur); + if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -485,20 +477,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_UP_SELECT: - cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); needsUpdate |= cursorUpParagraph(cur); break; case LFUN_PARAGRAPH_DOWN: case LFUN_PARAGRAPH_DOWN_SELECT: - cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); needsUpdate |= cursorDownParagraph(cur); break; case LFUN_SCREEN_UP: case LFUN_SCREEN_UP_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT); if (cur.pit() == 0 && cur.textRow().pos() == 0) { cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_UP); @@ -509,8 +500,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_SCREEN_DOWN: case LFUN_SCREEN_DOWN_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT); if (cur.pit() == cur.lastpit() && cur.textRow().endpos() == cur.lastpos()) { cur.undispatched(); @@ -522,21 +512,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_LINE_BEGIN: case LFUN_LINE_BEGIN_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT); needsUpdate |= cursorHome(cur); break; case LFUN_LINE_END: case LFUN_LINE_END_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); needsUpdate |= cursorEnd(cur); break; case LFUN_WORD_FORWARD: case LFUN_WORD_FORWARD_SELECT: - cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT); if (isRTL(cur.paragraph())) needsUpdate |= cursorLeftOneWord(cur); else @@ -545,7 +533,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_WORD_BACKWARD: case LFUN_WORD_BACKWARD_SELECT: - cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT); if (isRTL(cur.paragraph())) needsUpdate |= cursorRightOneWord(cur); else @@ -1473,15 +1461,15 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; } + needsUpdate |= (cur.pos() != cur.lastpos()) && cur.selection(); if (singleParUpdate) // Inserting characters does not change par height if (cur.bottom().paragraph().dim().height() == olddim.height()) { // if so, update _only_ this paragraph - cur.bv().update(Update::SinglePar | - Update::FitCursor | - Update::MultiParSel); - cur.noUpdate(); + cur.updateFlags(Update::SinglePar | + Update::FitCursor | + Update::MultiParSel); return; } else needsUpdate = true; @@ -1492,7 +1480,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) && !cur.selection()) cur.noUpdate(); else - cur.needsUpdate(); + cur.updateFlags(Update::Force | Update::FitCursor); } -- 2.39.2