#include "language.h"
#include "debug.h"
#include "rowpainter.h"
+#include "insets/updatableinset.h"
+#include "mathed/formulabase.h"
+#include "lyx_gui.h"
// Splash screen-specific stuff
#include "lyxfont.h"
#include <boost/bind.hpp>
#include <boost/signals/trackable.hpp>
+using namespace lyx::support;
+
using std::min;
using std::max;
using std::endl;
+namespace grfx = lyx::graphics;
+
namespace {
class SplashScreen : boost::noncopyable, boost::signals::trackable {
{
}
-// FIXME: GUII these cursor methods need to decide
-// whether the workarea is focused or not
-void LyXScreen::showCursor(LyXText const * text, BufferView const * bv)
+void LyXScreen::showCursor(BufferView & bv)
{
+ // this is needed to make sure we copy back the right
+ // pixmap on the hide for the Qt frontend
+ lyx_gui::sync_events();
+
if (cursor_visible_)
return;
- workarea().getPainter().start();
+ if (!bv.available())
+ return;
Cursor_Shape shape = BAR_SHAPE;
- BufferParams const & bp(bv->buffer()->params);
- LyXFont const & realfont(text->real_current_font);
-
- if (realfont.language() != bp.language
- || realfont.isVisibleRightToLeft()
- != bp.language->RightToLeft()) {
- shape = (realfont.isVisibleRightToLeft())
- ? REVERSED_L_SHAPE : L_SHAPE;
+
+ LyXText const & text = *bv.getLyXText();
+ LyXFont const & realfont(text.real_current_font);
+ BufferParams const & bp(bv.buffer()->params);
+ bool const samelang = realfont.language() == bp.language;
+ bool const isrtl = realfont.isVisibleRightToLeft();
+
+ if (!samelang || isrtl != bp.language->RightToLeft()) {
+ shape = L_SHAPE;
+ if (isrtl)
+ shape = REVERSED_L_SHAPE;
}
- showManualCursor(text, text->cursor.x(), text->cursor.y(),
- font_metrics::maxAscent(realfont),
- font_metrics::maxDescent(realfont),
- shape);
+ int ascent = font_metrics::maxAscent(realfont);
+ int descent = font_metrics::maxDescent(realfont);
+ int h = ascent + descent;
+ int x = 0;
+ int y = 0;
+ int const top_y = bv.text->top_y();
+
+ if (bv.theLockingInset()) {
+ // Would be nice to clean this up to make some understandable sense...
+ UpdatableInset * inset = bv.theLockingInset();
+ inset->getCursor(bv, x, y);
+
+ // Non-obvious. The reason we have to have these
+ // extra checks is that the ->getCursor() calls rely
+ // on the inset's own knowledge of its screen position.
+ // If we scroll up or down in a big enough increment, the
+ // inset->draw() is not called: this doesn't update
+ // inset.top_baseline, so getCursor() returns an old value.
+ // Ugly as you like.
+ int bx, by;
+ inset->getCursorPos(&bv, bx, by);
+ by += inset->insetInInsetY() + bv.text->cursor.iy();
+ if (by < top_y)
+ return;
+ if (by > top_y + workarea().workHeight())
+ return;
+ } else {
+ x = bv.text->cursor.x();
+ y = bv.text->cursor.y();
+ y -= top_y;
+ }
- workarea().getPainter().end();
+ y -= ascent;
+
+ // if it doesn't fit entirely on the screen, don't try to show it
+ if (y < 0 || y + h > workarea().workHeight())
+ return;
+
+ cursor_visible_ = true;
+ showCursor(x, y, h, shape);
+}
+
+
+void LyXScreen::hideCursor()
+{
+ if (!cursor_visible_)
+ return;
+
+ cursor_visible_ = false;
+ removeCursor();
+}
+
+
+void LyXScreen::toggleCursor(BufferView & bv)
+{
+ if (cursor_visible_)
+ hideCursor();
+ else
+ showCursor(bv);
}
}
-void LyXScreen::cursorToggle(BufferView * bv) const
+unsigned int LyXScreen::topCursorVisible(LyXText * text)
{
- if (cursor_visible_)
- bv->hideCursor();
- else
- bv->showCursor();
-}
-
-
-unsigned int LyXScreen::topCursorVisible(LyXCursor const & cursor, int top_y)
-{
- int const vheight = workarea().workHeight();
+ LyXCursor const & cursor = text->cursor;
+ int top_y = text->top_y();
int newtop = top_y;
+ int const vheight = workarea().workHeight();
- RowList::iterator row = cursor.row();
+ RowList::iterator row = text->cursorRow();
#warning SUPER HACK DISABLED (Lgb)
#if 0
+ row->height()
- row->baseline() - vheight;
} else {
- // scroll down
- newtop = cursor.y()
- - vheight / 2; /* the scroll region must be so big!! */
+ // scroll down, the scroll region must be so big!!
+ newtop = cursor.y() - vheight / 2;
}
} else if (static_cast<int>((cursor.y()) - row->baseline()) <
bool LyXScreen::fitCursor(LyXText * text, BufferView * bv)
{
// Is a change necessary?
- int const newtop = topCursorVisible(text->cursor, text->top_y());
+ int const newtop = topCursorVisible(text);
bool const result = (newtop != text->top_y());
if (result) {
draw(text, bv, newtop);
int const bottom = min(
max(static_cast<int>(text->selection.end.y()
- - text->selection.end.row()->baseline()
- + text->selection.end.row()->height()),
+ - text->getRow(text->selection.end)->baseline()
+ + text->getRow(text->selection.end)->height()),
text->top_y()),
static_cast<int>(text->top_y() + workarea().workHeight()));
int const top = min(
max(static_cast<int>(text->selection.start.y() -
- text->selection.start.row()->baseline()),
+ text->getRow(text->selection.start)->baseline()),
text->top_y()),
static_cast<int>(text->top_y() + workarea().workHeight()));
return;
int const top_tmp = text->toggle_cursor.y()
- - text->toggle_cursor.row()->baseline();
+ - text->getRow(text->toggle_cursor)->baseline();
int const bottom_tmp = text->toggle_end_cursor.y()
- - text->toggle_end_cursor.row()->baseline()
- + text->toggle_end_cursor.row()->height();
+ - text->getRow(text->toggle_end_cursor)->baseline()
+ + text->getRow(text->toggle_end_cursor)->height();
int const offset = yo < 0 ? yo : 0;
int const bottom = min(max(bottom_tmp, text->top_y()),
expose(0, 0, workarea().workWidth(), workarea().workHeight());
workarea().getPainter().end();
-
- if (cursor_visible_) {
- cursor_visible_ = false;
- bv->showCursor();
- }
}
int y = y_text - topy;
// y1 is now the real beginning of row on the screen
+ hideCursor();
+
RowList::iterator const rend = text->rows().end();
while (rit != rend && y < y2) {
- RowPainter rp(*bv, *text, rit);
- rp.paint(y + yo, xo, y + topy);
+ paintRows(*bv, *text, rit, y + yo, xo, y + topy);
y += rit->height();
++rit;
}
if (y - row->height() > workarea().workHeight())
return;
- RowPainter rp(*bv, *text, row);
- rp.paint(y, xo, y + text->top_y());
+ hideCursor();
+
+ paintRows(*bv, *text, row, y, xo, y + text->top_y());
}