mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-05 13:26:21 +00:00
Smooth, controllable scrolling in the Qt frontend.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8178 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
35f1ab544b
commit
8a3f21cd29
@ -1,3 +1,14 @@
|
||||
2003-12-01 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* QContentPane.[Ch] (SyntheticMouseEvent): a new, helper struct.
|
||||
(QContentPane): store an instance of SyntheticMouseEvent and
|
||||
add a slot, generateSyntheticMouseEvent, that is invoked by the
|
||||
SyntheticMouseEvent::timeout.
|
||||
(mouseMoveEvent): initialize synthetic_mouse_event_ when the
|
||||
mouse button is depressed and the cursor is outside of the work area.
|
||||
(generateSyntheticMouseEvent): if the scrollbar value is different
|
||||
from the cached value, then dispatch a 'synthetic' mouse event.
|
||||
|
||||
2003-12-01 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
|
||||
|
||||
* QVSpace.C: remove VSPACE::NONE, remove restore button.
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "QWorkArea.h"
|
||||
#include "QContentPane.h"
|
||||
#include "QLyXKeySym.h"
|
||||
@ -18,9 +20,6 @@
|
||||
#include <qtimer.h>
|
||||
#include <qapplication.h>
|
||||
|
||||
#include "funcrequest.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/// return the LyX key state from Qt's
|
||||
@ -74,10 +73,20 @@ mouse_button::state q_motion_state(Qt::ButtonState state)
|
||||
} // namespace anon
|
||||
|
||||
|
||||
SyntheticMouseEvent::SyntheticMouseEvent()
|
||||
: timeout(200), restart_timeout(true),
|
||||
x_old(-1), y_old(-1), scrollbar_value_old(-1.0)
|
||||
{}
|
||||
|
||||
|
||||
QContentPane::QContentPane(QWorkArea * parent)
|
||||
: QWidget(parent, "content_pane", WRepaintNoErase),
|
||||
track_scrollbar_(true), wa_(parent)
|
||||
{
|
||||
synthetic_mouse_event_.timeout.timeout.connect(
|
||||
boost::bind(&QContentPane::generateSyntheticMouseEvent,
|
||||
this));
|
||||
|
||||
setFocusPolicy(QWidget::WheelFocus);
|
||||
setFocus();
|
||||
setCursor(ibeamCursor);
|
||||
@ -85,7 +94,25 @@ QContentPane::QContentPane(QWorkArea * parent)
|
||||
// stupid moc strikes again
|
||||
connect(wa_->scrollbar_, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(scrollBarChanged(int)));
|
||||
}
|
||||
|
||||
|
||||
void QContentPane::generateSyntheticMouseEvent()
|
||||
{
|
||||
// Set things off to generate the _next_ 'pseudo' event.
|
||||
if (synthetic_mouse_event_.restart_timeout)
|
||||
synthetic_mouse_event_.timeout.start();
|
||||
|
||||
// Has anything changed on-screen since the last timeout signal
|
||||
// was received?
|
||||
double const scrollbar_value = wa_->scrollbar_->value();
|
||||
if (scrollbar_value != synthetic_mouse_event_.scrollbar_value_old) {
|
||||
// Yes it has. Store the params used to check this.
|
||||
synthetic_mouse_event_.scrollbar_value_old = scrollbar_value;
|
||||
|
||||
// ... and dispatch the event to the LyX core.
|
||||
wa_->dispatch(synthetic_mouse_event_.cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -115,6 +142,9 @@ void QContentPane::mousePressEvent(QMouseEvent * e)
|
||||
|
||||
void QContentPane::mouseReleaseEvent(QMouseEvent * e)
|
||||
{
|
||||
if (synthetic_mouse_event_.timeout.running())
|
||||
synthetic_mouse_event_.timeout.stop();
|
||||
|
||||
FuncRequest const cmd(LFUN_MOUSE_RELEASE, e->x(), e->y(),
|
||||
q_button_state(e->button()));
|
||||
wa_->dispatch(cmd);
|
||||
@ -125,7 +155,53 @@ void QContentPane::mouseMoveEvent(QMouseEvent * e)
|
||||
{
|
||||
FuncRequest const cmd(LFUN_MOUSE_MOTION, e->x(), e->y(),
|
||||
q_motion_state(e->state()));
|
||||
wa_->dispatch(cmd);
|
||||
|
||||
// If we're above or below the work area...
|
||||
if (e->y() <= 0 || e->y() >= height()) {
|
||||
// Store the event, to be handled when the timeout expires.
|
||||
synthetic_mouse_event_.cmd = cmd;
|
||||
|
||||
if (synthetic_mouse_event_.timeout.running())
|
||||
// Discard the event. Note that it _may_ be handled
|
||||
// when the timeout expires if
|
||||
// synthetic_mouse_event_.cmd has not been overwritten.
|
||||
// Ie, when the timeout expires, we handle the
|
||||
// most recent event but discard all others that
|
||||
// occurred after the one used to start the timeout
|
||||
// in the first place.
|
||||
return;
|
||||
else {
|
||||
synthetic_mouse_event_.restart_timeout = true;
|
||||
synthetic_mouse_event_.timeout.start();
|
||||
// Fall through to handle this event...
|
||||
}
|
||||
|
||||
} else if (synthetic_mouse_event_.timeout.running()) {
|
||||
// Store the event, to be possibly handled when the timeout
|
||||
// expires.
|
||||
// Once the timeout has expired, normal control is returned
|
||||
// to mouseMoveEvent (restart_timeout = false).
|
||||
// This results in a much smoother 'feel' when moving the
|
||||
// mouse back into the work area.
|
||||
synthetic_mouse_event_.cmd = cmd;
|
||||
synthetic_mouse_event_.restart_timeout = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Has anything changed on-screen since the last QMouseEvent
|
||||
// was received?
|
||||
double const scrollbar_value = wa_->scrollbar_->value();
|
||||
if (e->x() != synthetic_mouse_event_.x_old ||
|
||||
e->y() != synthetic_mouse_event_.y_old ||
|
||||
scrollbar_value != synthetic_mouse_event_.scrollbar_value_old) {
|
||||
// Yes it has. Store the params used to check this.
|
||||
synthetic_mouse_event_.x_old = e->x();
|
||||
synthetic_mouse_event_.y_old = e->y();
|
||||
synthetic_mouse_event_.scrollbar_value_old = scrollbar_value;
|
||||
|
||||
// ... and dispatch the event to the LyX core.
|
||||
wa_->dispatch(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -200,4 +276,3 @@ void QContentPane::trackScrollbar(bool track_on)
|
||||
{
|
||||
track_scrollbar_ = track_on;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,13 @@
|
||||
#ifndef QCONTENTPANE_H
|
||||
#define QCONTENTPANE_H
|
||||
|
||||
#ifdef emit
|
||||
#undef emit
|
||||
#endif
|
||||
|
||||
#include "funcrequest.h"
|
||||
#include "frontends/Timeout.h"
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <qpixmap.h>
|
||||
|
||||
@ -40,6 +47,27 @@ struct double_click {
|
||||
};
|
||||
|
||||
|
||||
/** Qt only emits mouse events when the mouse is being moved, but
|
||||
* we want to generate 'pseudo' mouse events when the mouse button is
|
||||
* pressed and the mouse cursor is below the bottom, or above the top
|
||||
* of the work area. In this way, we'll be able to continue scrolling
|
||||
* (and selecting) the text.
|
||||
*
|
||||
* This struct stores all the parameters needed to make this happen.
|
||||
*/
|
||||
struct SyntheticMouseEvent
|
||||
{
|
||||
SyntheticMouseEvent();
|
||||
|
||||
FuncRequest cmd;
|
||||
Timeout timeout;
|
||||
bool restart_timeout;
|
||||
int x_old;
|
||||
int y_old;
|
||||
double scrollbar_value_old;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Widget for actually drawing the document on
|
||||
*/
|
||||
@ -76,6 +104,10 @@ public slots:
|
||||
|
||||
void scrollBarChanged(int);
|
||||
private:
|
||||
/// The slot connected to SyntheticMouseEvent::timeout.
|
||||
void generateSyntheticMouseEvent();
|
||||
SyntheticMouseEvent synthetic_mouse_event_;
|
||||
|
||||
///
|
||||
bool track_scrollbar_;
|
||||
/// owning widget
|
||||
|
Loading…
Reference in New Issue
Block a user