On Monday 01 November 2004 14:19, Chris Cannam wrote:
> I think the problem with all this is that we probably shouldn't be using
> the mouse move events to handle scrolling at all, because of course we
> want autoscroll to happen whether the mouse is moving or not -- we
> should probably just make it depend on the mouse position.
That's also my conclusion after 3 days of trying to improve the current
version (main annoyance being that once auto-scrolling starts, it occurs no
matter how you move the mouse).
Anyway, I have to dash off so this is just a quick reply, but what you
describe looks quite a lot like the drag auto scroll which QScrollView
already implements. Problem being that it's behind private methods and is
triggered on drag events, not mouse moves. However, could you give a try to
the attached piece of code ? Don't mind the bottom widget stuff, I reused a
test I did for the horiz. scrollbar hack we have. The only relevant bits are
the contentsMouse(Press|Release|Move)Event() methods. Try click and drag in
the canvas, see how it behaves. Perhaps with some tweaks it could be made to
behave like you describe.
--
Guillaume.
http://www.telegraph-road.org
#include <qpixmap.h>
#include <qlabel.h>
#define private protected
#include <qcanvas.h>
#undef private
#include <qapplication.h>
#include <qmainwindow.h>
#include <qvbox.h>
#include <qframe.h>
#include <qlayout.h>
#include <iostream>
class MyScrollView : public QCanvasView
{
public:
MyScrollView(QCanvas*, QWidget *parent, const char* name = 0, WFlags f = 0);
void stuffCanvas();
void setBottomFixedWidget(QWidget*);
protected:
virtual void polish();
virtual void setHBarGeometry(QScrollBar &hbar, int x, int y, int w, int h);
virtual void contentsMouseDoubleClickEvent(QMouseEvent *e);
virtual void contentsMouseMoveEvent(QMouseEvent *e);
virtual void contentsMousePressEvent(QMouseEvent *e);
virtual void contentsMouseReleaseEvent(QMouseEvent *e);
void updateBottomWidgetGeometry();
virtual void resizeEvent(QResizeEvent*);
QWidget* m_bottomWidget;
int m_labelNumber;
int m_prevX;
int m_prevY;
};
MyScrollView::MyScrollView(QCanvas* c, QWidget *parent, const char* name, WFlags f)
: QCanvasView(c, parent, name, f),
m_bottomWidget(0),
m_labelNumber(0),
m_prevX(0),
m_prevY(0)
{
stuffCanvas();
canvas()->update();
setDragAutoScroll(true);
setAcceptDrops(true);
}
void MyScrollView::stuffCanvas()
{
QCanvasRectangle* r = new QCanvasRectangle(10, 10, 100, 100, canvas());
r->setPen(red);
r->setBrush(red);
r->show();
}
void MyScrollView::setBottomFixedWidget(QWidget* w)
{
m_bottomWidget = w;
m_bottomWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
updateBottomWidgetGeometry();
}
void MyScrollView::resizeEvent(QResizeEvent* e)
{
QCanvasView::resizeEvent(e);
if (!horizontalScrollBar()->isVisible())
updateBottomWidgetGeometry();
}
void MyScrollView::polish()
{
updateBottomWidgetGeometry();
}
void MyScrollView::setHBarGeometry(QScrollBar &hbar, int x, int y, int w, int h)
{
QCanvasView::setHBarGeometry(hbar, x, y, w, h);
updateBottomWidgetGeometry();
}
void MyScrollView::contentsMousePressEvent(QMouseEvent* e)
{
startDragAutoScroll();
}
void MyScrollView::contentsMouseReleaseEvent(QMouseEvent* e)
{
stopDragAutoScroll();
}
void MyScrollView::contentsMouseDoubleClickEvent(QMouseEvent*)
{
std::cerr << "MyScrollView::contentsMouseDoubleClickEvent : " << m_labelNumber << std::endl;
QLabel* l = new QLabel(QString("Label %1").arg(m_labelNumber++), m_bottomWidget);
l->show();
updateBottomWidgetGeometry();
// m_bottomWidget->updateGeometry();
// m_bottomWidget->layout()->invalidate();
}
void MyScrollView::contentsMouseMoveEvent(QMouseEvent *e)
{
std::cerr << "move x: " << e->x()
<< " - y : " << e->y()
<< " - xDelta : " << e->x() - m_prevX
<< " - yDelta : " << e->y() - m_prevY
<< std::endl;
m_prevX = e->x();
m_prevY = e->y();
doDragAutoScroll();
}
void MyScrollView::updateBottomWidgetGeometry()
{
if (!m_bottomWidget) return;
int bottomWidgetHeight = m_bottomWidget->sizeHint().height();
std::cerr << "MyScrollView::updateBottomWidgetGeometry() : bottomWidgetHeight = "
<< bottomWidgetHeight << std::endl;
setMargins(0, 0, 0, bottomWidgetHeight);
QRect r = frameRect();
int hScrollBarHeight = 0;
if (horizontalScrollBar()->isVisible())
hScrollBarHeight = horizontalScrollBar()->height();
int vScrollBarWidth = 0;
if (verticalScrollBar()->isVisible())
vScrollBarWidth = verticalScrollBar()->width();
m_bottomWidget->setGeometry(r.x(),
r.y() + r.height() - bottomWidgetHeight - hScrollBarHeight,
r.width() - vScrollBarWidth,
bottomWidgetHeight);
}
int main(int argc, char** argv)
{
QApplication app(argc,argv);
QMainWindow *mainWin = new QMainWindow;
QCanvas *canvas = new QCanvas(5000,5000);
MyScrollView* sv = new MyScrollView(canvas, mainWin);
mainWin->setCentralWidget(sv);
QVBox* vbox = new QVBox(mainWin, "noscrollvbox");
vbox->setFrameShape(QFrame::Box);
sv->setBottomFixedWidget(vbox);
new QLabel("No Scroll1", vbox, "noscrollqlabel1");
new QLabel("No Scroll2", vbox, "noscrollqlabel2");
qApp->setMainWidget(mainWin);
mainWin->show();
QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
return app.exec();
}