int const h = tm.parMetrics(anchor_ref_).height();
offset_ref_ = int((bar * t.paragraphs().size() - anchor_ref_) * h);
updateMetrics(false);
+ buffer_.changed();
}
intl_->keyMapPrim();
}
}
-
+
intl_->getTransManager().translateAndInsert(c, t, cur);
}
break;
}
+ case LFUN_SCREEN_UP:
+ case LFUN_SCREEN_DOWN:
+ flag.enabled(true);
+ break;
+
+ // FIXME: LFUN_SCREEN_DOWN_SELECT should be removed from
+ // everywhere else before this can enabled:
+ case LFUN_SCREEN_UP_SELECT:
+ case LFUN_SCREEN_DOWN_SELECT:
+ flag.enabled(false);
+ break;
+
default:
flag.enabled(false);
}
break;
}
+ case LFUN_SCREEN_UP:
+ case LFUN_SCREEN_DOWN: {
+ Point p = bv_funcs::getPos(*this, cur, cur.boundary());
+ if (p.y_ < 0 || p.y_ > height_) {
+ // The cursor is off-screen so recenter before proceeding.
+ center();
+ updateMetrics(false);
+ //FIXME: updateMetrics() does not update paragraph position
+ // This is done at draw() time. So we need a redraw!
+ buffer_.changed();
+ p = bv_funcs::getPos(*this, cur, cur.boundary());
+ }
+ scroll(cmd.action == LFUN_SCREEN_UP? - height_ : height_);
+ cur.reset(buffer_.inset());
+ text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
+ //FIXME: what to do with cur.x_target()?
+ finishUndo();
+ // The metrics are already up to date. see scroll()
+ updateFlags = Update::None;
+ break;
+ }
+
+ case LFUN_SCREEN_UP_SELECT:
+ case LFUN_SCREEN_DOWN_SELECT: {
+ cur.selHandle(true);
+ size_t initial_depth = cur.depth();
+ Point const p = bv_funcs::getPos(*this, cur, cur.boundary());
+ scroll(cmd.action == LFUN_SCREEN_UP_SELECT? - height_ : height_);
+ // FIXME: We need to verify if the cursor stayed within an inset...
+ //cur.reset(buffer_.inset());
+ text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_);
+ finishUndo();
+ while (cur.depth() > initial_depth) {
+ cur.forwardInset();
+ }
+ // FIXME: we need to do a redraw again because of the selection
+ buffer_.changed();
+ updateFlags = Update::Force | Update::FitCursor;
+ break;
+ }
+
default:
updateFlags = Update::None;
}
Inset const * BufferView::getCoveringInset(Text const & text, int x, int y)
{
- pit_type pit = text_metrics_[&text].getPitNearY(y);
- BOOST_ASSERT(pit != -1);
- Paragraph const & par = text.getPar(pit);
-
- LYXERR(Debug::DEBUG)
- << BOOST_CURRENT_FUNCTION
- << ": x: " << x
- << " y: " << y
- << " pit: " << pit
- << endl;
- InsetList::const_iterator iit = par.insetlist.begin();
- InsetList::const_iterator iend = par.insetlist.end();
- for (; iit != iend; ++iit) {
- Inset * const inset = iit->inset;
- if (inset->covers(*this, x, y)) {
- if (!inset->descendable())
- // No need to go further down if the inset is not
- // descendable.
- return inset;
-
- size_t cell_number = inset->nargs();
- // Check all the inner cell.
- for (size_t i = 0; i != cell_number; ++i) {
- Text const * inner_text = inset->getText(i);
- if (inner_text) {
- // Try deeper.
- Inset const * inset_deeper =
- getCoveringInset(*inner_text, x, y);
- if (inset_deeper)
- return inset_deeper;
- }
- }
-
- LYXERR(Debug::DEBUG)
- << BOOST_CURRENT_FUNCTION
- << ": Hit inset: " << inset << endl;
- return inset;
+ TextMetrics & tm = text_metrics_[&text];
+ Inset * inset = tm.checkInsetHit(x, y);
+ if (!inset)
+ return 0;
+
+ if (!inset->descendable())
+ // No need to go further down if the inset is not
+ // descendable.
+ return inset;
+
+ size_t cell_number = inset->nargs();
+ // Check all the inner cell.
+ for (size_t i = 0; i != cell_number; ++i) {
+ Text const * inner_text = inset->getText(i);
+ if (inner_text) {
+ // Try deeper.
+ Inset const * inset_deeper =
+ getCoveringInset(*inner_text, x, y);
+ if (inset_deeper)
+ return inset_deeper;
}
}
- LYXERR(Debug::DEBUG)
- << BOOST_CURRENT_FUNCTION
- << ": No inset hit. " << endl;
- return 0;
+
+ return inset;
}
// Highlighted the newly hovered inset (if any).
need_redraw |= inset->setMouseHover(true);
last_inset_ = inset;
+ if (!need_redraw)
+ return false;
// if last metrics update was in singlepar mode, WorkArea::redraw() will
// not expose the button for redraw. We adjust here the metrics dimension
// to enable a full redraw.
- // FIXME: It is possible to redraw only the area around the button!
- if (need_redraw
- && metrics_info_.update_strategy == SingleParUpdate) {
- // FIXME: It should be possible to redraw only the area around
- // the button by doing this:
- //
- //metrics_info_.singlepar = false;
- //metrics_info_.y1 = ymin of button;
- //metrics_info_.y2 = ymax of button;
- //
- // Unfortunately, BufferView::draw() does not distinguish
- // between background updates and text updates. So we use the hammer
- // solution for now. We could also avoid the updateMetrics() below
- // by using the first and last pit of the CoordCache. Have a look
- // at Text::getPitNearY() to see what I mean.
- //
- //metrics_info_.pit1 = first pit of CoordCache;
- //metrics_info_.pit2 = last pit of CoordCache;
- //metrics_info_.singlepar = false;
- //metrics_info_.y1 = 0;
- //metrics_info_.y2 = height_;
- //
- updateMetrics(false);
+ if (metrics_info_.update_strategy == SingleParUpdate) {
+ // Build temporary cursor.
+ TextMetrics & tm = text_metrics_[&buffer_.text()];
+ tm.editXY(cur, cmd.x, cmd.y);
+ // collect cursor paragraph iter bounds
+ std::pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();
+ std::pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
+ int y1 = firstpm.second->position() - firstpm.second->ascent();
+ int y2 = lastpm.second->position() + lastpm.second->descent();
+ metrics_info_ = ViewMetricsInfo(firstpm.first, lastpm.first, y1, y2,
+ FullScreenUpdate, buffer_.text().paragraphs().size());
}
// This event (moving without mouse click) is not passed further.
// This should be changed if it is further utilized.
- return need_redraw;
+ return true;
}
// Build temporary cursor.
}
-void BufferView::scroll(int /*lines*/)
+void BufferView::scroll(int y)
{
-// Text const * t = buffer_.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);
-//
+ if (y > 0)
+ scrollDown(y);
+ else if (y < 0)
+ scrollUp(-y);
+}
+
+
+void BufferView::scrollDown(int offset)
+{
+ Text * text = &buffer_.text();
+ TextMetrics & tm = text_metrics_[text];
+ int ymax = height_ + offset;
+ while (true) {
+ std::pair<pit_type, ParagraphMetrics const *> last = tm.last();
+ int bottom_pos = last.second->position() + last.second->descent();
+ if (last.first == text->paragraphs().size() - 1) {
+ if (bottom_pos <= height_)
+ return;
+ offset = min(offset, bottom_pos - height_);
+ break;
+ }
+ if (bottom_pos > ymax)
+ break;
+ tm.newParMetricsDown();
+ }
+ offset_ref_ += offset;
+ updateMetrics(false);
+ buffer_.changed();
+}
+
+
+void BufferView::scrollUp(int offset)
+{
+ Text * text = &buffer_.text();
+ TextMetrics & tm = text_metrics_[text];
+ int ymin = - offset;
+ while (true) {
+ std::pair<pit_type, ParagraphMetrics const *> first = tm.first();
+ int top_pos = first.second->position() - first.second->ascent();
+ if (first.first == 0) {
+ if (top_pos >= 0)
+ return;
+ offset = min(offset, - top_pos);
+ break;
+ }
+ if (top_pos < ymin)
+ break;
+ tm.newParMetricsUp();
+ }
+ offset_ref_ -= offset;
+ updateMetrics(false);
+ buffer_.changed();
}
{
BOOST_ASSERT(&cur.bv() == this);
- // this event will clear selection so we save selection for
+ // this event will clear selection so we save selection for
// persistent selection
cap::saveSelection(cursor());
if (!singlepar) {
// Clear out the position cache in case of full screen redraw,
coord_cache_.clear();
-
+
// Clear out paragraph metrics to avoid having invalid metrics
// in the cache from paragraphs not relayouted below
// The complete text metrics will be redone.
el = buf.errorList("Parse");
recordUndo(cursor_);
cap::pasteParagraphList(cursor_, buf.paragraphs(),
- buf.params().getTextClass_ptr(), el);
+ buf.params().getTextClassPtr(), el);
res = _("Document %1$s inserted.");
} else
res = _("Could not insert document %1$s");
// and grey out above (should not happen later)
// lyxerr << "par ascent: " << text.getPar(metrics_info_.p1).ascent() << endl;
- if (metrics_info_.y1 > 0
+ if (metrics_info_.y1 > 0
&& metrics_info_.update_strategy == FullScreenUpdate)
pain.fillRectangle(0, 0, width_, metrics_info_.y1, Color::bottomarea);
// and possibly grey out below
// lyxerr << "par descent: " << text.getPar(metrics_info_.p1).ascent() << endl;
- if (metrics_info_.y2 < height_
+ if (metrics_info_.y2 < height_
&& metrics_info_.update_strategy == FullScreenUpdate)
pain.fillRectangle(0, metrics_info_.y2, width_,
height_ - metrics_info_.y2, Color::bottomarea);