void BufferView::Pimpl::updateScrollbar()
{
- /* If the text is smaller than the working area, the scrollbar
- * maximum must be the working area height. No scrolling will
- * be possible */
if (!bv_->text) {
+ lyxerr[Debug::GUI] << "no text in updateScrollbar" << endl;
workarea_.setScrollbar(0, 1.0);
return;
}
long const text_height = bv_->text->height;
long const work_height = workarea_.height();
- if (text_height <= work_height) {
- workarea_.setScrollbarBounds(0.0, 0.0);
- current_scrollbar_value = bv_->text->first_y;
- workarea_.setScrollbar(current_scrollbar_value, 1.0);
- return;
- }
-
double const lineh = bv_->text->defaultHeight();
double const slider_size =
(text_height == 0) ? 1.0 : 1.0 / double(text_height);
- static long old_text_height;
- static double old_lineh;
- static double old_slider_size;
+ lyxerr[Debug::GUI] << "text_height now " << text_height << endl;
+ lyxerr[Debug::GUI] << "work_height " << work_height << endl;
- if (text_height != old_text_height) {
- workarea_.setScrollbarBounds(0.0,
- text_height - work_height);
- old_text_height = text_height;
- }
- if (lineh != old_lineh) {
- workarea_.setScrollbarIncrements(lineh);
- old_lineh = lineh;
- }
- if (current_scrollbar_value != bv_->text->first_y
- || slider_size != old_slider_size) {
+ /* If the text is smaller than the working area, the scrollbar
+ * maximum must be the working area height. No scrolling will
+ * be possible */
+ if (text_height <= work_height) {
+ lyxerr[Debug::GUI] << "doc smaller than workarea !" << endl;
+ workarea_.setScrollbarBounds(0.0, 0.0);
current_scrollbar_value = bv_->text->first_y;
- workarea_.setScrollbar(current_scrollbar_value, slider_size);
- old_slider_size = slider_size;
+ workarea_.setScrollbar(current_scrollbar_value, 1.0);
+ return;
}
+
+ workarea_.setScrollbarBounds(0.0, text_height - work_height);
+ workarea_.setScrollbarIncrements(lineh);
+ current_scrollbar_value = bv_->text->first_y;
+ workarea_.setScrollbar(current_scrollbar_value, slider_size);
}
// Callback for scrollbar slider
void BufferView::Pimpl::scrollCB(double value)
{
+ lyxerr[Debug::GUI] << "scrollCB of " << value << endl;
+
if (!buffer_) return;
current_scrollbar_value = long(value);
cursor.par(), cursor.pos());
int width = bv_->theLockingInset()->width(bv_, font);
int inset_x = font.isVisibleRightToLeft()
- ? cursor.x() - width : cursor.x();
+ ? cursor.ix() - width : cursor.ix();
int start_x = inset_x + bv_->theLockingInset()->scroll();
bv_->theLockingInset()->
insetMotionNotify(bv_,
x - start_x,
- y - cursor.y() + bv_->text->first_y,
+ y - cursor.iy() + bv_->text->first_y,
state);
return;
}
return;
screen_->hideCursor();
-
+#if 0
+ int y_before = bv_->text->cursor.y();
+#endif
+ Row * cursorrow = bv_->text->cursor.row();
bv_->text->setCursorFromCoordinates(bv_, x, y + bv_->text->first_y);
+#if 0
+ // sorry for this but I have a strange error that the y value jumps at
+ // a certain point. This seems like an error in my xforms library or
+ // in some other local environment, but I would like to leave this here
+ // for the moment until I can remove this (Jug 20020418)
+ if (y_before < bv_->text->cursor.y())
+ lyxerr << y_before << ":" << bv_->text->cursor.y() << endl;
+#endif
+ // This is to allow jumping over large insets
+ if (cursorrow == bv_->text->cursor.row()) {
+ if (y >= int(workarea_.height())) {
+ bv_->text->cursorDown(bv_, false);
+ } else if (y < 0) {
+ bv_->text->cursorUp(bv_, false);
+ }
+ }
if (!bv_->text->selection.set())
update(bv_->text, BufferView::UPDATE); // Maybe an empty line was deleted
paste_internally = true;
}
+ int const screen_first = bv_->text->first_y;
+
if (bv_->theLockingInset()) {
// We are in inset locking mode
selection_possible = true;
screen_->hideCursor();
- int const screen_first = bv_->text->first_y;
-
// Clear the selection
screen_->toggleSelection(bv_->text, bv_);
bv_->text->clearSelection();
selection_possible = false;
owner_->updateLayoutChoice();
owner_->message(inset->editMessage());
- // IMO the inset has to be first in edit-mode and then we send the
- // button press. (Jug 20020222)
- inset->edit(bv_); //, xpos, ypos, button);
+ //inset->edit(bv_, xpos, ypos, button);
+ // We just have to lock the inset before calling a PressEvent on it!
+ // we don't need the edit() call here! (Jug20020329)
+ if (!bv_->lockInset(inset)) {
+ lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
+ }
inset->insetButtonPress(bv_, xpos, ypos, button);
return;
}
+ // I'm not sure we should continue here if we hit an inset (Jug20020403)
// Right click on a footnote flag opens float menu
if (button == 3) {
inset->insetButtonRelease(bv_, x, y, button);
} else {
inset_hit->insetButtonRelease(bv_, x, y, button);
+ // IMO this is a grosshack! Inset's should be changed so that
+ // they call the actions they have to do with the insetButtonRel.
+ // function and not in the edit(). This should be changed
+ // (Jug 20020329)
inset_hit->edit(bv_, x, y, button);
}
return;
int const width = inset.width(bv_, font);
int const inset_x = font.isVisibleRightToLeft()
- ? (cursor.x() - width) : cursor.x();
+ ? (cursor.ix() - width) : cursor.ix();
return Box(
inset_x + inset.scroll(),
inset_x + width,
- cursor.y() - inset.ascent(bv_, font),
- cursor.y() + inset.descent(bv_, font));
+ cursor.iy() - inset.ascent(bv_, font),
+ cursor.iy() + inset.descent(bv_, font));
}
x -= b.x1;
// The origin of an inset is on the baseline
- y -= (text.cursor.y());
+ y -= text.cursor.iy();
return inset;
}
void BufferView::Pimpl::cursorPrevious(LyXText * text)
{
- if (!text->cursor.row()->previous())
+ if (!text->cursor.row()->previous()) {
+ if (text->first_y > 0) {
+ int new_y = bv_->text->first_y - workarea_.height();
+ screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
+ updateScrollbar();
+ }
return;
+ }
int y = text->first_y;
Row * cursorrow = text->cursor.row();
- text->setCursorFromCoordinates(bv_, bv_->text->cursor.x_fix(), y);
+ text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y);
finishUndo();
- // This is to allow jumping over large insets
- if ((cursorrow == text->cursor.row()))
- text->cursorUp(bv_);
-
- if (text->inset_owner ||
- text->cursor.row()->height() < workarea_.height())
- screen_->draw(bv_->text, bv_,
- text->cursor.y()
- - text->cursor.row()->baseline()
- + text->cursor.row()->height()
- - workarea_.height() + 1);
+
+ int new_y;
+ if (cursorrow == bv_->text->cursor.row()) {
+ // we have a row which is higher than the workarea so we leave the
+ // cursor on the start of the row and move only the draw up as soon
+ // as we move the cursor or do something while inside the row (it may
+ // span several workarea-heights) we'll move to the top again, but this
+ // is better than just jump down and only display part of the row.
+ new_y = bv_->text->first_y - workarea_.height();
+ } else {
+ if (text->inset_owner) {
+ new_y = bv_->text->cursor.iy()
+ + bv_->theLockingInset()->insetInInsetY() + y
+ + text->cursor.row()->height()
+ - workarea_.height() + 1;
+ } else {
+ new_y = text->cursor.y()
+ - text->cursor.row()->baseline()
+ + text->cursor.row()->height()
+ - workarea_.height() + 1;
+ }
+ }
+ screen_->draw(bv_->text, bv_, new_y < 0 ? 0 : new_y);
+ if (text->cursor.row()->previous()) {
+ LyXCursor cur;
+ text->setCursor(bv_, cur, text->cursor.row()->previous()->par(),
+ text->cursor.row()->previous()->pos(), false);
+ if (cur.y() > text->first_y) {
+ text->cursorUp(bv_, true);
+ }
+ }
updateScrollbar();
}
void BufferView::Pimpl::cursorNext(LyXText * text)
{
- if (!text->cursor.row()->next())
+ if (!text->cursor.row()->next()) {
+ int y = text->cursor.y() - text->cursor.row()->baseline() +
+ text->cursor.row()->height();
+ if (y > int(text->first_y + workarea_.height())) {
+ screen_->draw(bv_->text, bv_,
+ bv_->text->first_y + workarea_.height());
+ updateScrollbar();
+ }
return;
+ }
int y = text->first_y + workarea_.height();
-// if (text->inset_owner)
-// y += bv_->text->first;
+ if (text->inset_owner && !text->first_y) {
+ y -= (bv_->text->cursor.iy()
+ - bv_->text->first_y
+ + bv_->theLockingInset()->insetInInsetY());
+ }
text->getRowNearY(y);
Row * cursorrow = text->cursor.row();
text->setCursorFromCoordinates(bv_, text->cursor.x_fix(), y); // + workarea_->height());
finishUndo();
- // This is to allow jumping over large insets
- if ((cursorrow == bv_->text->cursor.row()))
- text->cursorDown(bv_);
-
- if (text->inset_owner ||
- text->cursor.row()->height() < workarea_.height())
- screen_->draw(bv_->text, bv_, text->cursor.y() -
- text->cursor.row()->baseline());
+ int new_y;
+ if (cursorrow == bv_->text->cursor.row()) {
+ // we have a row which is higher than the workarea so we leave the
+ // cursor on the start of the row and move only the draw down as soon
+ // as we move the cursor or do something while inside the row (it may
+ // span several workarea-heights) we'll move to the top again, but this
+ // is better than just jump down and only display part of the row.
+ new_y = bv_->text->first_y + workarea_.height();
+ } else {
+ if (text->inset_owner) {
+ new_y = bv_->text->cursor.iy()
+ + bv_->theLockingInset()->insetInInsetY()
+ + y - text->cursor.row()->baseline();
+ } else {
+ new_y = text->cursor.y() - text->cursor.row()->baseline();
+ }
+ }
+ screen_->draw(bv_->text, bv_, new_y);
+ if (text->cursor.row()->next()) {
+ LyXCursor cur;
+ text->setCursor(bv_, cur, text->cursor.row()->next()->par(),
+ text->cursor.row()->next()->pos(), false);
+ if (cur.y() < int(text->first_y + workarea_.height())) {
+ text->cursorDown(bv_, true);
+ }
+ }
updateScrollbar();
}
inline
-void BufferView::Pimpl::moveCursorUpdate(bool selecting)
+void BufferView::Pimpl::moveCursorUpdate(bool selecting, bool fitcur)
{
LyXText * lt = bv_->getLyXText();
updateInset(lt->inset_owner, false);
}
if (lt->bv_owner) {
- update(lt, BufferView::SELECT|BufferView::FITCUR);
+ if (fitcur)
+ update(lt, BufferView::SELECT|BufferView::FITCUR);
+ else
+ update(lt, BufferView::SELECT);
showCursor();
}
break;
}
- if (current_layout != layout) {
- LyXText * lt = bv_->getLyXText();
+ bool change_layout = (current_layout != layout);
+ LyXText * lt = bv_->getLyXText();
+ if (!change_layout && lt->selection.set() &&
+ lt->selection.start.par() != lt->selection.end.par())
+ {
+ Paragraph * spar = lt->selection.start.par();
+ Paragraph * epar = lt->selection.end.par()->next();
+ while(spar != epar) {
+ if (spar->layout() != current_layout) {
+ change_layout = true;
+ break;
+ }
+ }
+ }
+ if (change_layout) {
hideCursor();
current_layout = layout;
update(lt,
update(lt, BufferView::UPDATE);
cursorPrevious(lt);
finishUndo();
- moveCursorUpdate(false);
+ moveCursorUpdate(false, false);
owner_->showState();
}
break;
update(lt, BufferView::UPDATE);
cursorNext(lt);
finishUndo();
- moveCursorUpdate(false);
+ moveCursorUpdate(false, false);
owner_->showState();
}
break;
update(lt,
BufferView::SELECT|BufferView::FITCUR);
- lt->cursorUp(bv_);
+ lt->cursorUp(bv_, true);
finishUndo();
moveCursorUpdate(true);
owner_->showState();
update(lt,
BufferView::SELECT|BufferView::FITCUR);
- lt->cursorDown(bv_);
+ lt->cursorDown(bv_, true);
finishUndo();
moveCursorUpdate(true);
owner_->showState();