From 6774c17368a3474f11c1e011cf1ce482e42f4867 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Mon, 17 Dec 2001 14:25:04 +0000 Subject: [PATCH] fix to checkInsetHit() from John git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3227 a592a061-630c-0410-9148-cb99ea01b6c8 --- po/POTFILES.in | 1 - src/BufferView.C | 5 +- src/BufferView.h | 3 +- src/BufferView_pimpl.C | 120 +++++++++++++++++++++++++---------------- src/BufferView_pimpl.h | 21 ++++++-- src/ChangeLog | 10 ++++ src/Makefile.am | 1 + src/box.h | 43 +++++++++++++++ src/insets/insettext.C | 4 +- 9 files changed, 151 insertions(+), 57 deletions(-) create mode 100644 src/box.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 43f1bf43df..17e2f1d40c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -9,7 +9,6 @@ src/converter.C src/CutAndPaste.C src/debug.C src/exporter.C -src/ext_l10n.h src/figure_form.C src/figureForm.C src/FontLoader.C diff --git a/src/BufferView.C b/src/BufferView.C index 6ed3ed8fa4..1e8a987d60 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -113,10 +113,9 @@ void BufferView::scrollCB(double value) } -Inset * BufferView::checkInsetHit(LyXText * text, int & x, int & y, - unsigned int button) +Inset * BufferView::checkInsetHit(LyXText * text, int & x, int & y) { - return pimpl_->checkInsetHit(text, x, y, button); + return pimpl_->checkInsetHit(text, x, y); } diff --git a/src/BufferView.h b/src/BufferView.h index ff0a3ffbfe..50518247c4 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -73,8 +73,7 @@ public: /// void updateScrollbar(); /// - Inset * checkInsetHit(LyXText *, int & x, int & y, - unsigned int button); + Inset * checkInsetHit(LyXText *, int & x, int & y); /// void redoCurrentBuffer(); /// diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 49a805cf63..ca6784f1ee 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -579,7 +579,7 @@ void BufferView::Pimpl::workAreaButtonPress(int xpos, int ypos, { if (!buffer_ || !screen_.get()) return; - Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos, button); + Inset * inset_hit = checkInsetHit(bv_->text, xpos, ypos); // ok ok, this is a hack. if (button == 4 || button == 5) { @@ -755,7 +755,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, // If we hit an inset, we have the inset coordinates in these // and inset_hit points to the inset. If we do not hit an // inset, inset_hit is 0, and inset_x == x, inset_y == y. - Inset * inset_hit = checkInsetHit(bv_->text, x, y, button); + Inset * inset_hit = checkInsetHit(bv_->text, x, y); if (bv_->theLockingInset()) { // We are in inset locking mode. @@ -862,63 +862,91 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, } -/* - * Returns an inset if inset was hit. 0 otherwise. - * If hit, the coordinates are changed relative to the inset. - * Otherwise coordinates are not changed, and false is returned. - */ -Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y, - unsigned int /* button */) +Box BufferView::Pimpl::insetDimensions(LyXText const & text, LyXCursor const & cursor) const +{ + Paragraph /*const*/ & par = *cursor.par(); + pos_type const pos = cursor.pos(); + + lyx::Assert(par.getInset(pos)); + + Inset const & inset(*par.getInset(pos)); + + LyXFont const & font = text.getFont(buffer_, &par, pos); + + int const width = inset.width(bv_, font); + int const inset_x = font.isVisibleRightToLeft() + ? (cursor.x() - width) : cursor.x(); + + return Box( + inset_x + inset.scroll(), + inset_x + width, + cursor.y() - inset.ascent(bv_, font), + cursor.y() + inset.descent(bv_, font)); +} + + +Inset * BufferView::Pimpl::checkInset(LyXText const & text, LyXCursor const & cursor, int & x, int & y) const +{ + pos_type const pos(cursor.pos()); + Paragraph /*const*/ & par(*cursor.par()); + + if (pos >= par.size() || !par.isInset(pos)) { + return 0; + } + + Inset /*const*/ * inset = par.getInset(pos); + + if (!isEditableInset(inset)) { + return 0; + } + + Box b(insetDimensions(text, cursor)); + + if (!b.contained(x, y)) { + return 0; + } + + text.setCursor(bv_, &par, pos, true); + + x -= b.x1; + // The origin of an inset is on the baseline + y -= (text.cursor.y()); + + return inset; +} + + +Inset * BufferView::Pimpl::checkInsetHit(LyXText * text, int & x, int & y) { if (!screen_.get()) return 0; int y_tmp = y + text->first; - + LyXCursor cursor; text->setCursorFromCoordinates(bv_, cursor, x, y_tmp); - text->setCursor(bv_, cursor, cursor.par(),cursor.pos(),true); + + Inset * inset(checkInset(*text, cursor, x, y_tmp)); - lyx::pos_type pos; + if (inset) { + y = y_tmp; + return inset; + } - if (cursor.pos() < cursor.par()->size() - && cursor.par()->isInset(cursor.pos()) - && isEditableInset(cursor.par()->getInset(cursor.pos()))) - { - pos = cursor.pos(); - } else if ((cursor.pos() - 1 >= 0) - && cursor.par()->isInset(cursor.pos() - 1) - && isEditableInset(cursor.par()->getInset(cursor.pos() - 1))) - { - pos = cursor.pos() - 1; - // if the inset takes a full row, then the cursor.y() - // at the end of the inset will be wrong. So step the cursor - // back one - text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true); - } else { + // look at previous position + + if (cursor.pos() == 0) { return 0; } - // Check whether the inset really was hit - Inset * inset = cursor.par()->getInset(pos); - LyXFont const & font = text->getFont(buffer_, cursor.par(), pos); - int const width = inset->width(bv_, font); - int const inset_x = font.isVisibleRightToLeft() - ? cursor.x() - width : cursor.x(); - int const start_x = inset_x + inset->scroll(); - int const end_x = inset_x + width; - int const start_y = cursor.y() - inset->ascent(bv_, font); - int const end_y = cursor.y() + inset->descent(bv_, font); - - if (x > start_x && x < end_x && y_tmp > start_y && y < end_y) { - text->setCursor(bv_, cursor.par(), pos, true); - x = x - start_x; - // The origin of an inset is on the baseline - y = y_tmp - (text->cursor.y()); - return inset; - } + // move back one + text->setCursor(bv_, cursor, cursor.par(), cursor.pos() - 1, true); - return 0; + inset = checkInset(*text, cursor, x, y_tmp); + if (inset) { + y = y_tmp; + } + return inset; } diff --git a/src/BufferView_pimpl.h b/src/BufferView_pimpl.h index 320c7d18a7..27c4961b06 100644 --- a/src/BufferView_pimpl.h +++ b/src/BufferView_pimpl.h @@ -10,6 +10,7 @@ #include "commandtags.h" #include "frontends/Timeout.h" #include "WorkArea.h" +#include "box.h" #include "insets/insetspecialchar.h" #include "support/types.h" @@ -54,9 +55,12 @@ struct BufferView::Pimpl : public SigC::Object { void updateScrollbar(); /// void scrollCB(double value); - /// - Inset * checkInsetHit(LyXText *, int & x, int & y, - unsigned int button); + /** + * Returns an inset if inset was hit, or 0 if not. + * + * If hit, the coordinates are changed relative to the inset. + */ + Inset * checkInsetHit(LyXText *, int & x, int & y); /// int scrollUp(long time); /// @@ -126,6 +130,17 @@ struct BufferView::Pimpl : public SigC::Object { /// bool Dispatch(kb_action action, string const & argument); private: + /** + * Return the on-screen dimensions of the inset at the cursor. + * Pre-condition: the cursor must be at an inset. + */ + Box insetDimensions(LyXText const & text, LyXCursor const & cursor) const; + /** + * check if the given co-ordinates are inside an inset at the given cursor, + * if one exists. If so, the inset is returned, and the co-ordinates are + * made relative. Otherwise, 0 is returned. + */ + Inset * checkInset(LyXText const & text, LyXCursor const & cursor, int & x, int & y) const; /// friend class BufferView; /// open and lock an updatable inset diff --git a/src/ChangeLog b/src/ChangeLog index c9d72bd5c0..5ff880c490 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2001-12-15 John Levon + + * BufferView.h: + * BufferView.C: + * BufferView_pimpl.h: + * BufferView_pimpl.C: cleanup and fix of checkInsetHit(). + + * Makefile.am: + * box.h: new start of class for above + 2001-12-15 John Levon * lyxfunc.C: ignore space-only minibuffer dispatches. diff --git a/src/Makefile.am b/src/Makefile.am index 6c2b90aa49..f6ad0b87fa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,6 +89,7 @@ lyx_SOURCES = \ WorkArea.h \ XFormsView.C \ XFormsView.h \ + box.h \ broken_headers.h \ buffer.C \ buffer.h \ diff --git a/src/box.h b/src/box.h new file mode 100644 index 0000000000..1d8b6483bc --- /dev/null +++ b/src/box.h @@ -0,0 +1,43 @@ +/** + * \file box.h + * Copyright 2001 the LyX Team + * Read the file COPYING + * + * \author John Levon + */ + +#ifndef BOX_H +#define BOX_H + +#include + +#include "debug.h" + +/** + * A simple class representing rectangular regions. + * It is expected that the box be constructed in + * normalised form, that is to say : x1,y1 is top-left, + * x2,y2 is bottom-right. + */ +struct Box { + unsigned int x1; + unsigned int x2; + unsigned int y1; + unsigned int y2; + + Box(unsigned int x1_, unsigned int x2_, + unsigned int y1_, unsigned int y2_) : + x1(x1_), x2(x2_), y1(y1_), y2(y2_) {} + + /** + * Returns true if the given co-ordinates are within + * the box. Check is exclusive (point on a border + * returns false). + */ + bool contained(unsigned int x, unsigned int y) { + return (x1 < x && x2 > x && + y1 < y && y2 > y); + } +}; + +#endif // BOX_H diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 15afebff95..e94607736a 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -914,7 +914,7 @@ void InsetText::insetButtonPress(BufferView * bv, int x, int y, int button) int tmp_x = x - drawTextXOffset; int tmp_y = y + insetAscent - getLyXText(bv)->first; - Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y, button); + Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y); hideInsetCursor(bv); if (the_locking_inset) { @@ -1958,7 +1958,7 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, x -= drawTextXOffset; int dummyx = x; int dummyy = y + insetAscent; - Inset * inset = bv->checkInsetHit(getLyXText(bv), dummyx, dummyy, button); + Inset * inset = bv->checkInsetHit(getLyXText(bv), dummyx, dummyy); if (inset) { if (x < 0) -- 2.39.2