|
|
|
|
|
|
|
/*
|
|
|
|
Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define DEBUG_KP_VIEW_SCROLLABLE_CONTAINER 0
|
|
|
|
|
|
|
|
#include <kpviewscrollablecontainer.h>
|
|
|
|
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpen.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
|
|
|
|
#include <kpdefs.h>
|
|
|
|
#include <kppixmapfx.h>
|
|
|
|
#include <kpview.h>
|
|
|
|
#include <kpwidgetmapper.h>
|
|
|
|
|
|
|
|
|
|
|
|
// (Pulled from out of Thurston's hat)
|
|
|
|
static const int DragScrollLeftTopMargin = 0;
|
|
|
|
static const int DragScrollRightBottomMargin = 16; // scrollbarish
|
|
|
|
static const int DragScrollInterval = 1000 / 10;
|
|
|
|
static const int DragScrollInitialInterval = DragScrollInterval * 2;
|
|
|
|
static const int DragScrollNumPixels = 5;
|
|
|
|
static const int DragDistanceFromRectMaxFor1stMultiplier = 50;
|
|
|
|
static const int DragDistanceFromRectMaxFor2ndMultiplier = 100;
|
|
|
|
|
|
|
|
static const int GripSize = 7;
|
|
|
|
static const int GripHandleSize = 7;
|
|
|
|
|
|
|
|
|
|
|
|
kpGrip::kpGrip (GripType type,
|
|
|
|
TQWidget *parent, const char *name)
|
|
|
|
: TQWidget (parent, name),
|
|
|
|
m_type (type),
|
|
|
|
m_startPoint (KP_INVALID_POINT),
|
|
|
|
m_currentPoint (KP_INVALID_POINT),
|
|
|
|
m_shouldReleaseMouseButtons (false)
|
|
|
|
{
|
|
|
|
setCursor (cursorForType (m_type));
|
|
|
|
|
|
|
|
setMouseTracking (true); // mouseMoveEvent's even when no mousebtn down
|
|
|
|
|
|
|
|
updatePixmap ();
|
|
|
|
}
|
|
|
|
|
|
|
|
kpGrip::~kpGrip ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
kpGrip::GripType kpGrip::type () const
|
|
|
|
{
|
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public static
|
|
|
|
const TQCursor &kpGrip::cursorForType (GripType type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Bottom:
|
|
|
|
return TQt::sizeVerCursor;
|
|
|
|
break; // one day you'll forget
|
|
|
|
|
|
|
|
case Right:
|
|
|
|
return TQt::sizeHorCursor;
|
|
|
|
break; // one day you'll forget
|
|
|
|
|
|
|
|
case BottomRight:
|
|
|
|
return TQt::sizeFDiagCursor;
|
|
|
|
break; // one day you'll forget
|
|
|
|
}
|
|
|
|
|
|
|
|
return TQt::arrowCursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQRect kpGrip::hotRect (bool toGlobal) const
|
|
|
|
{
|
|
|
|
TQRect ret;
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case Bottom:
|
|
|
|
{
|
|
|
|
const int handleX = (width () - GripHandleSize) / 2;
|
|
|
|
ret = TQRect (handleX, 0,
|
|
|
|
GripHandleSize, height ());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Right:
|
|
|
|
{
|
|
|
|
const int handleY = (height () - GripHandleSize) / 2;
|
|
|
|
ret = TQRect (0, handleY,
|
|
|
|
width (), GripHandleSize);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BottomRight:
|
|
|
|
// pixmap all opaque
|
|
|
|
ret = rect ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return TQRect ();
|
|
|
|
}
|
|
|
|
|
|
|
|
return (toGlobal ? TQRect (mapToGlobal (ret.topLeft ()),
|
|
|
|
mapToGlobal (ret.bottomRight ()))
|
|
|
|
: ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
bool kpGrip::isDrawing () const
|
|
|
|
{
|
|
|
|
return (m_startPoint != KP_INVALID_POINT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQString kpGrip::haventBegunDrawUserMessage () const
|
|
|
|
{
|
|
|
|
return i18n ("Left drag the handle to resize the image.");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQString kpGrip::userMessage () const
|
|
|
|
{
|
|
|
|
return m_userMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
void kpGrip::setUserMessage (const TQString &message)
|
|
|
|
{
|
|
|
|
// Don't do NOP checking here since another grip might have changed
|
|
|
|
// the message so an apparent NOP for this grip is not a NOP in the
|
|
|
|
// global sense (kpViewScrollableContainer::slotGripStatusMessageChanged()).
|
|
|
|
|
|
|
|
m_userMessage = message;
|
|
|
|
emit statusMessageChanged (message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpGrip::updatePixmap ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::updatePixmap() rect=" << rect () << endl;
|
|
|
|
#endif
|
|
|
|
if (width () <= 0 || height () <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQPixmap pixmap (width (), height ());
|
|
|
|
pixmap.fill (colorGroup ().highlight ());
|
|
|
|
kpPixmapFX::ensureTransparentAt (&pixmap, pixmap.rect ());
|
|
|
|
const TQRect hr = hotRect ();
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "\thotRect=" << hr << endl;
|
|
|
|
#endif
|
|
|
|
if (hr.isValid ())
|
|
|
|
kpPixmapFX::ensureOpaqueAt (&pixmap, hr);
|
|
|
|
|
|
|
|
setBackgroundPixmap (pixmap);
|
|
|
|
if (pixmap.mask ())
|
|
|
|
setMask (*pixmap.mask ());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpGrip::cancel ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::cancel()" << endl;
|
|
|
|
#endif
|
|
|
|
if (m_currentPoint == KP_INVALID_POINT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_startPoint = KP_INVALID_POINT;
|
|
|
|
m_currentPoint = KP_INVALID_POINT;
|
|
|
|
|
|
|
|
setUserMessage (i18n ("Resize Image: Let go of all the mouse buttons."));
|
|
|
|
setCursor (TQt::arrowCursor);
|
|
|
|
m_shouldReleaseMouseButtons = true;
|
|
|
|
|
|
|
|
releaseKeyboard ();
|
|
|
|
emit cancelledDraw ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::keyReleaseEvent (TQKeyEvent *e)
|
|
|
|
{
|
|
|
|
if (m_startPoint != KP_INVALID_POINT &&
|
|
|
|
e->key () == TQt::Key_Escape)
|
|
|
|
{
|
|
|
|
cancel ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::mousePressEvent (TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
if (m_startPoint == KP_INVALID_POINT &&
|
|
|
|
(e->stateAfter () & TQt::MouseButtonMask) == TQt::LeftButton)
|
|
|
|
{
|
|
|
|
m_startPoint = e->pos ();
|
|
|
|
m_currentPoint = e->pos ();
|
|
|
|
emit beganDraw ();
|
|
|
|
grabKeyboard ();
|
|
|
|
|
|
|
|
setUserMessage (i18n ("Resize Image: Right click to cancel."));
|
|
|
|
setCursor (cursorForType (m_type));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_startPoint != KP_INVALID_POINT)
|
|
|
|
cancel ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQPoint kpGrip::viewDeltaPoint () const
|
|
|
|
{
|
|
|
|
if (m_startPoint == KP_INVALID_POINT)
|
|
|
|
return KP_INVALID_POINT;
|
|
|
|
|
|
|
|
const TQPoint point = mapFromGlobal (TQCursor::pos ());
|
|
|
|
|
|
|
|
// TODO: this is getting out of sync with m_currentPoint
|
|
|
|
|
|
|
|
return TQPoint (((m_type & Right) ? point.x () - m_startPoint.x () : 0),
|
|
|
|
((m_type & Bottom) ? point.y () - m_startPoint.y () : 0));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
void kpGrip::mouseMovedTo (const TQPoint &point, bool dueToDragScroll)
|
|
|
|
{
|
|
|
|
if (m_startPoint == KP_INVALID_POINT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_currentPoint = point;
|
|
|
|
|
|
|
|
emit continuedDraw (((m_type & Right) ? point.x () - m_startPoint.x () : 0),
|
|
|
|
((m_type & Bottom) ? point.y () - m_startPoint.y () : 0),
|
|
|
|
dueToDragScroll);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::mouseMoveEvent (TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::mouseMoveEvent() m_startPoint=" << m_startPoint
|
|
|
|
<< " stateAfter=" << e->stateAfter ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_startPoint == KP_INVALID_POINT)
|
|
|
|
{
|
|
|
|
if ((e->stateAfter () & TQt::MouseButtonMask) == 0)
|
|
|
|
setUserMessage (haventBegunDrawUserMessage ());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mouseMovedTo (e->pos (), false/*not due to drag scroll*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::mouseReleaseEvent (TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::mouseReleaseEvent() m_startPoint=" << m_startPoint
|
|
|
|
<< " stateAfter=" << e->stateAfter ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_startPoint != KP_INVALID_POINT)
|
|
|
|
{
|
|
|
|
const int dx = m_currentPoint.x () - m_startPoint.x (),
|
|
|
|
dy = m_currentPoint.y () - m_startPoint.y ();
|
|
|
|
|
|
|
|
m_currentPoint = KP_INVALID_POINT;
|
|
|
|
m_startPoint = KP_INVALID_POINT;
|
|
|
|
|
|
|
|
releaseKeyboard ();
|
|
|
|
emit endedDraw ((m_type & Right) ? dx : 0,
|
|
|
|
(m_type & Bottom) ? dy : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((e->stateAfter () & TQt::MouseButtonMask) == 0)
|
|
|
|
{
|
|
|
|
m_shouldReleaseMouseButtons = false;
|
|
|
|
setUserMessage (TQString());
|
|
|
|
setCursor (cursorForType (m_type));
|
|
|
|
|
|
|
|
releaseKeyboard ();
|
|
|
|
emit releasedAllButtons ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::resizeEvent (TQResizeEvent *)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::resizeEvent()" << endl;
|
|
|
|
#endif
|
|
|
|
updatePixmap ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::enterEvent (TQEvent * /*e*/)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::enterEvent()"
|
|
|
|
<< " m_startPoint=" << m_startPoint
|
|
|
|
<< " shouldReleaseMouseButtons="
|
|
|
|
<< m_shouldReleaseMouseButtons << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_startPoint == KP_INVALID_POINT &&
|
|
|
|
!m_shouldReleaseMouseButtons)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "\tsending message" << endl;
|
|
|
|
#endif
|
|
|
|
setUserMessage (haventBegunDrawUserMessage ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::leaveEvent (TQEvent * /*e*/)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpGrip::leaveEvent()"
|
|
|
|
<< " m_startPoint=" << m_startPoint
|
|
|
|
<< " shouldReleaseMouseButtons="
|
|
|
|
<< m_shouldReleaseMouseButtons << endl;
|
|
|
|
#endif
|
|
|
|
if (m_startPoint == KP_INVALID_POINT &&
|
|
|
|
!m_shouldReleaseMouseButtons)
|
|
|
|
{
|
|
|
|
setUserMessage (TQString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQWidget]
|
|
|
|
void kpGrip::paintEvent (TQPaintEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0
|
|
|
|
kdDebug () << "kpGrip::paintEvent(" << e->rect () << ")" << endl;
|
|
|
|
#endif
|
|
|
|
TQWidget::paintEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Are we checking for m_view == 0 often enough?
|
|
|
|
kpViewScrollableContainer::kpViewScrollableContainer (kpMainWindow *parent,
|
|
|
|
const char *name)
|
|
|
|
: TQScrollView ((TQWidget *) parent, name, TQt::WStaticContents | TQt::WNoAutoErase),
|
|
|
|
m_mainWindow (parent),
|
|
|
|
m_contentsXSoon (-1), m_contentsYSoon (-1),
|
|
|
|
m_view (0),
|
|
|
|
m_bottomGrip (new kpGrip (kpGrip::Bottom, viewport (), "Bottom Grip")),
|
|
|
|
m_rightGrip (new kpGrip (kpGrip::Right, viewport (), "Right Grip")),
|
|
|
|
m_bottomRightGrip (new kpGrip (kpGrip::BottomRight, viewport (), "BottomRight Grip")),
|
|
|
|
m_docResizingGrip (0),
|
|
|
|
m_dragScrollTimer (new TQTimer (this)),
|
|
|
|
m_zoomLevel (100),
|
|
|
|
m_scrollTimerRunOnce (false),
|
|
|
|
m_resizeRoundedLastViewX (-1), m_resizeRoundedLastViewY (-1),
|
|
|
|
m_resizeRoundedLastViewDX (0), m_resizeRoundedLastViewDY (0),
|
|
|
|
m_haveMovedFromOriginalDocSize (false)
|
|
|
|
|
|
|
|
{
|
|
|
|
m_bottomGrip->setFixedHeight (GripSize);
|
|
|
|
m_bottomGrip->hide ();
|
|
|
|
addChild (m_bottomGrip);
|
|
|
|
connectGripSignals (m_bottomGrip);
|
|
|
|
|
|
|
|
m_rightGrip->setFixedWidth (GripSize);
|
|
|
|
m_rightGrip->hide ();
|
|
|
|
addChild (m_rightGrip);
|
|
|
|
connectGripSignals (m_rightGrip);
|
|
|
|
|
|
|
|
m_bottomRightGrip->setFixedSize (GripSize, GripSize);
|
|
|
|
m_bottomRightGrip->hide ();
|
|
|
|
addChild (m_bottomRightGrip);
|
|
|
|
connectGripSignals (m_bottomRightGrip);
|
|
|
|
|
|
|
|
|
|
|
|
connect (this, TQ_SIGNAL (contentsMoving (int, int)),
|
|
|
|
this, TQ_SLOT (slotContentsMoving (int, int)));
|
|
|
|
|
|
|
|
connect (m_dragScrollTimer, TQ_SIGNAL (timeout ()),
|
|
|
|
this, TQ_SLOT (slotDragScroll ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
kpViewScrollableContainer::~kpViewScrollableContainer ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
int kpViewScrollableContainer::contentsXSoon ()
|
|
|
|
{
|
|
|
|
if (m_contentsXSoon < 0)
|
|
|
|
return contentsX ();
|
|
|
|
else
|
|
|
|
return m_contentsXSoon;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
int kpViewScrollableContainer::contentsYSoon ()
|
|
|
|
{
|
|
|
|
if (m_contentsYSoon < 0)
|
|
|
|
return contentsY ();
|
|
|
|
else
|
|
|
|
return m_contentsYSoon;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::connectGripSignals (kpGrip *grip)
|
|
|
|
{
|
|
|
|
connect (grip, TQ_SIGNAL (beganDraw ()),
|
|
|
|
this, TQ_SLOT (slotGripBeganDraw ()));
|
|
|
|
connect (grip, TQ_SIGNAL (continuedDraw (int, int, bool)),
|
|
|
|
this, TQ_SLOT (slotGripContinuedDraw (int, int, bool)));
|
|
|
|
connect (grip, TQ_SIGNAL (cancelledDraw ()),
|
|
|
|
this, TQ_SLOT (slotGripCancelledDraw ()));
|
|
|
|
connect (grip, TQ_SIGNAL (endedDraw (int, int)),
|
|
|
|
this, TQ_SLOT (slotGripEndedDraw (int, int)));
|
|
|
|
|
|
|
|
connect (grip, TQ_SIGNAL (statusMessageChanged (const TQString &)),
|
|
|
|
this, TQ_SLOT (slotGripStatusMessageChanged (const TQString &)));
|
|
|
|
|
|
|
|
connect (grip, TQ_SIGNAL (releasedAllButtons ()),
|
|
|
|
this, TQ_SLOT (recalculateStatusMessage ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQSize kpViewScrollableContainer::newDocSize () const
|
|
|
|
{
|
|
|
|
return newDocSize (m_resizeRoundedLastViewDX,
|
|
|
|
m_resizeRoundedLastViewDY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
bool kpViewScrollableContainer::haveMovedFromOriginalDocSize () const
|
|
|
|
{
|
|
|
|
return m_haveMovedFromOriginalDocSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
TQString kpViewScrollableContainer::statusMessage () const
|
|
|
|
{
|
|
|
|
return m_gripStatusMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
void kpViewScrollableContainer::clearStatusMessage ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 1
|
|
|
|
kdDebug () << "kpViewScrollableContainer::clearStatusMessage()" << endl;
|
|
|
|
#endif
|
|
|
|
m_bottomRightGrip->setUserMessage (TQString());
|
|
|
|
m_bottomGrip->setUserMessage (TQString());
|
|
|
|
m_rightGrip->setUserMessage (TQString());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQSize kpViewScrollableContainer::newDocSize (int viewDX, int viewDY) const
|
|
|
|
{
|
|
|
|
if (!m_view)
|
|
|
|
return TQSize ();
|
|
|
|
|
|
|
|
if (!docResizingGrip ())
|
|
|
|
return TQSize ();
|
|
|
|
|
|
|
|
const int docX = (int) m_view->transformViewToDocX (m_view->width () + viewDX);
|
|
|
|
const int docY = (int) m_view->transformViewToDocY (m_view->height () + viewDY);
|
|
|
|
|
|
|
|
return TQSize (TQMAX (1, docX), TQMAX (1, docY));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::calculateDocResizingGrip ()
|
|
|
|
{
|
|
|
|
if (m_bottomRightGrip->isDrawing ())
|
|
|
|
m_docResizingGrip = m_bottomRightGrip;
|
|
|
|
else if (m_bottomGrip->isDrawing ())
|
|
|
|
m_docResizingGrip = m_bottomGrip;
|
|
|
|
else if (m_rightGrip->isDrawing ())
|
|
|
|
m_docResizingGrip = m_rightGrip;
|
|
|
|
else
|
|
|
|
m_docResizingGrip = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
kpGrip *kpViewScrollableContainer::docResizingGrip () const
|
|
|
|
{
|
|
|
|
return m_docResizingGrip;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
int kpViewScrollableContainer::bottomResizeLineWidth () const
|
|
|
|
{
|
|
|
|
if (!docResizingGrip ())
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!m_view)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (docResizingGrip ()->type () & kpGrip::Bottom)
|
|
|
|
return TQMAX (m_view->zoomLevelY () / 100, 1);
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
int kpViewScrollableContainer::rightResizeLineWidth () const
|
|
|
|
{
|
|
|
|
if (!docResizingGrip ())
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!m_view)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (docResizingGrip ()->type () & kpGrip::Right)
|
|
|
|
return TQMAX (m_view->zoomLevelX () / 100, 1);
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::bottomResizeLineRect () const
|
|
|
|
{
|
|
|
|
if (m_resizeRoundedLastViewX < 0 || m_resizeRoundedLastViewY < 0)
|
|
|
|
return TQRect ();
|
|
|
|
|
|
|
|
return TQRect (TQPoint (0,
|
|
|
|
m_resizeRoundedLastViewY),
|
|
|
|
TQPoint (m_resizeRoundedLastViewX - 1,
|
|
|
|
m_resizeRoundedLastViewY + bottomResizeLineWidth () - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::rightResizeLineRect () const
|
|
|
|
{
|
|
|
|
if (m_resizeRoundedLastViewX < 0 || m_resizeRoundedLastViewY < 0)
|
|
|
|
return TQRect ();
|
|
|
|
|
|
|
|
return TQRect (TQPoint (m_resizeRoundedLastViewX,
|
|
|
|
0),
|
|
|
|
TQPoint (m_resizeRoundedLastViewX + rightResizeLineWidth () - 1,
|
|
|
|
m_resizeRoundedLastViewY - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::bottomRightResizeLineRect () const
|
|
|
|
{
|
|
|
|
if (m_resizeRoundedLastViewX < 0 || m_resizeRoundedLastViewY < 0)
|
|
|
|
return TQRect ();
|
|
|
|
|
|
|
|
return TQRect (TQPoint (m_resizeRoundedLastViewX,
|
|
|
|
m_resizeRoundedLastViewY),
|
|
|
|
TQPoint (m_resizeRoundedLastViewX + rightResizeLineWidth () - 1,
|
|
|
|
m_resizeRoundedLastViewY + bottomResizeLineWidth () - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: are these 2 correct? Remember that viewport()->x() == 1, viewport()->y() == 1
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQPoint kpViewScrollableContainer::mapViewToViewport (const TQPoint &viewPoint)
|
|
|
|
{
|
|
|
|
return viewPoint - TQPoint (contentsX (), contentsY ());
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::mapViewToViewport (const TQRect &viewRect)
|
|
|
|
{
|
|
|
|
if (!viewRect.isValid ())
|
|
|
|
return TQRect ();
|
|
|
|
|
|
|
|
TQRect ret = viewRect;
|
|
|
|
ret.moveBy (-contentsX (), -contentsY ());
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::mapViewportToGlobal (const TQRect &viewportRect)
|
|
|
|
{
|
|
|
|
return kpWidgetMapper::toGlobal (viewport (), viewportRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
TQRect kpViewScrollableContainer::mapViewToGlobal (const TQRect &viewRect)
|
|
|
|
{
|
|
|
|
return mapViewportToGlobal (mapViewToViewport (viewRect));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::repaintWidgetAtResizeLineViewRect (
|
|
|
|
TQWidget *widget, const TQRect &resizeLineViewRect)
|
|
|
|
{
|
|
|
|
const TQRect resizeLineGlobalRect = mapViewToGlobal (resizeLineViewRect);
|
|
|
|
const TQRect widgetGlobalRect = kpWidgetMapper::toGlobal (widget,
|
|
|
|
widget->rect ());
|
|
|
|
|
|
|
|
const TQRect redrawGlobalRect =
|
|
|
|
resizeLineGlobalRect.intersect (widgetGlobalRect);
|
|
|
|
|
|
|
|
const TQRect redrawWidgetRect =
|
|
|
|
kpWidgetMapper::fromGlobal (widget, redrawGlobalRect);
|
|
|
|
|
|
|
|
|
|
|
|
if (redrawWidgetRect.isValid ())
|
|
|
|
{
|
|
|
|
// TODO: should be "!widget->testWFlags (TQt::WRepaintNoErase)"
|
|
|
|
// but for some reason, doesn't work for viewport().
|
|
|
|
const bool erase = !dynamic_cast <kpView *> (widget);
|
|
|
|
widget->repaint (redrawWidgetRect, erase);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::repaintWidgetAtResizeLines (TQWidget *widget)
|
|
|
|
{
|
|
|
|
repaintWidgetAtResizeLineViewRect (widget, rightResizeLineRect ());
|
|
|
|
repaintWidgetAtResizeLineViewRect (widget, bottomResizeLineRect ());
|
|
|
|
repaintWidgetAtResizeLineViewRect (widget, bottomRightResizeLineRect ());
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::eraseResizeLines ()
|
|
|
|
{
|
|
|
|
if (m_resizeRoundedLastViewX >= 0 && m_resizeRoundedLastViewY >= 0)
|
|
|
|
{
|
|
|
|
repaintWidgetAtResizeLines (viewport ());
|
|
|
|
repaintWidgetAtResizeLines (m_view);
|
|
|
|
|
|
|
|
repaintWidgetAtResizeLines (m_bottomGrip);
|
|
|
|
repaintWidgetAtResizeLines (m_rightGrip);
|
|
|
|
repaintWidgetAtResizeLines (m_bottomRightGrip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::drawResizeLines ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0
|
|
|
|
kdDebug () << "kpViewScrollableContainer::drawResizeLines()"
|
|
|
|
<< " lastViewX=" << m_resizeRoundedLastViewX
|
|
|
|
<< " lastViewY=" << m_resizeRoundedLastViewY
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
TQPainter p (viewport (), true/*unclipped*/);
|
|
|
|
p.setRasterOp (TQt::NotROP);
|
|
|
|
|
|
|
|
const TQRect rightRect = rightResizeLineRect ();
|
|
|
|
if (rightRect.isValid ())
|
|
|
|
p.fillRect (mapViewToViewport (rightRect), TQt::white);
|
|
|
|
|
|
|
|
const TQRect bottomRect = bottomResizeLineRect ();
|
|
|
|
if (bottomRect.isValid ())
|
|
|
|
p.fillRect (mapViewToViewport (bottomRect), TQt::white);
|
|
|
|
|
|
|
|
const TQRect bottomRightRect = bottomRightResizeLineRect ();
|
|
|
|
if (bottomRightRect.isValid ())
|
|
|
|
p.fillRect (mapViewToViewport (bottomRightRect), TQt::white);
|
|
|
|
|
|
|
|
p.end ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::updateResizeLines (int viewX, int viewY,
|
|
|
|
int viewDX, int viewDY)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0
|
|
|
|
kdDebug () << "kpViewScrollableContainer::updateResizeLines("
|
|
|
|
<< viewX << "," << viewY << ")"
|
|
|
|
<< " oldViewX=" << m_resizeRoundedLastViewX
|
|
|
|
<< " oldViewY=" << m_resizeRoundedLastViewY
|
|
|
|
<< " viewDX=" << viewDX
|
|
|
|
<< " viewDY=" << viewDY
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
eraseResizeLines ();
|
|
|
|
|
|
|
|
|
|
|
|
if (viewX >= 0 && viewY >= 0)
|
|
|
|
{
|
|
|
|
m_resizeRoundedLastViewX = (int) m_view->transformDocToViewX ((int) m_view->transformViewToDocX (viewX));
|
|
|
|
m_resizeRoundedLastViewY = (int) m_view->transformDocToViewY ((int) m_view->transformViewToDocY (viewY));
|
|
|
|
|
|
|
|
m_resizeRoundedLastViewDX = viewDX;
|
|
|
|
m_resizeRoundedLastViewDY = viewDY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_resizeRoundedLastViewX = -1;
|
|
|
|
m_resizeRoundedLastViewY = -1;
|
|
|
|
|
|
|
|
m_resizeRoundedLastViewDX = 0;
|
|
|
|
m_resizeRoundedLastViewDY = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: This is suboptimal since if another window pops up on top of
|
|
|
|
// KolourPaint then disappears, the lines are not redrawn
|
|
|
|
// (although this doesn't happen very frequently since we grab the
|
|
|
|
// keyboard and mouse when resizing):
|
|
|
|
//
|
|
|
|
// e.g. sleep 5 && gedit & sleep 10 && killall gedit
|
|
|
|
//
|
|
|
|
// Should be done in the paintEvent's of every child of the
|
|
|
|
// scrollview.
|
|
|
|
drawResizeLines ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotGripBeganDraw ()
|
|
|
|
{
|
|
|
|
if (!m_view)
|
|
|
|
return;
|
|
|
|
|
|
|
|
calculateDocResizingGrip ();
|
|
|
|
|
|
|
|
m_haveMovedFromOriginalDocSize = false;
|
|
|
|
|
|
|
|
updateResizeLines (m_view->width (), m_view->height (),
|
|
|
|
0/*viewDX*/, 0/*viewDY*/);
|
|
|
|
|
|
|
|
emit beganDocResize ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotGripContinuedDraw (int inViewDX, int inViewDY,
|
|
|
|
bool dueToDragScroll)
|
|
|
|
{
|
|
|
|
int viewDX = inViewDX,
|
|
|
|
viewDY = inViewDY;
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotGripContinuedDraw("
|
|
|
|
<< viewDX << "," << viewDY << ") size="
|
|
|
|
<< newDocSize (viewDX, viewDY)
|
|
|
|
<< " dueToDragScroll=" << dueToDragScroll
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!m_view)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!dueToDragScroll &&
|
|
|
|
beginDragScroll (TQPoint (), TQPoint (), m_view->zoomLevelX ()))
|
|
|
|
{
|
|
|
|
const TQPoint newViewDeltaPoint = docResizingGrip ()->viewDeltaPoint ();
|
|
|
|
viewDX = newViewDeltaPoint.x ();
|
|
|
|
viewDY = newViewDeltaPoint.y ();
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "\tdrag scrolled - new view delta point="
|
|
|
|
<< newViewDeltaPoint
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
m_haveMovedFromOriginalDocSize = true;
|
|
|
|
|
|
|
|
updateResizeLines (TQMAX (1, TQMAX (m_view->width () + viewDX, (int) m_view->transformDocToViewX (1))),
|
|
|
|
TQMAX (1, TQMAX (m_view->height () + viewDY, (int) m_view->transformDocToViewY (1))),
|
|
|
|
viewDX, viewDY);
|
|
|
|
|
|
|
|
emit continuedDocResize (newDocSize ());
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotGripCancelledDraw ()
|
|
|
|
{
|
|
|
|
m_haveMovedFromOriginalDocSize = false;
|
|
|
|
|
|
|
|
updateResizeLines (-1, -1, 0, 0);
|
|
|
|
|
|
|
|
calculateDocResizingGrip ();
|
|
|
|
|
|
|
|
emit cancelledDocResize ();
|
|
|
|
|
|
|
|
endDragScroll ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotGripEndedDraw (int viewDX, int viewDY)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotGripEndedDraw("
|
|
|
|
<< viewDX << "," << viewDY << ") size="
|
|
|
|
<< newDocSize (viewDX, viewDY)
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!m_view)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const TQSize newSize = newDocSize (viewDX, viewDY);
|
|
|
|
|
|
|
|
m_haveMovedFromOriginalDocSize = false;
|
|
|
|
|
|
|
|
// must erase lines before view size changes
|
|
|
|
updateResizeLines (-1, -1, 0, 0);
|
|
|
|
|
|
|
|
calculateDocResizingGrip ();
|
|
|
|
|
|
|
|
emit endedDocResize (newSize);
|
|
|
|
|
|
|
|
endDragScroll ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotGripStatusMessageChanged (const TQString &string)
|
|
|
|
{
|
|
|
|
if (string == m_gripStatusMessage)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_gripStatusMessage = string;
|
|
|
|
emit statusMessageChanged (string);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public slot
|
|
|
|
void kpViewScrollableContainer::recalculateStatusMessage ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollabelContainer::recalculateStatusMessage()" << endl;
|
|
|
|
kdDebug () << "\tTQCursor::pos=" << TQCursor::pos ()
|
|
|
|
<< " global visibleRect="
|
|
|
|
<< kpWidgetMapper::toGlobal (this,
|
|
|
|
TQRect (0, 0, visibleWidth (), visibleHeight ()))
|
|
|
|
<< " brGrip.hotRect=" << m_bottomRightGrip->hotRect (true)
|
|
|
|
<< " bGrip.hotRect=" << m_bottomGrip->hotRect (true)
|
|
|
|
<< " rGrip.hotRect=" << m_rightGrip->hotRect (true)
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// HACK: After dragging to a new size, handles move so that they are now
|
|
|
|
// under the mouse pointer but no mouseMoveEvent() is generated for
|
|
|
|
// any grip. This also handles the case of cancelling over any
|
|
|
|
// grip.
|
|
|
|
//
|
|
|
|
if (kpWidgetMapper::toGlobal (this,
|
|
|
|
TQRect (0, 0, visibleWidth (), visibleHeight ()))
|
|
|
|
.contains (TQCursor::pos ()))
|
|
|
|
{
|
|
|
|
if (m_bottomRightGrip->isShown () &&
|
|
|
|
m_bottomRightGrip->hotRect (true/*to global*/)
|
|
|
|
.contains (TQCursor::pos ()))
|
|
|
|
{
|
|
|
|
m_bottomRightGrip->setUserMessage (i18n ("Left drag the handle to resize the image."));
|
|
|
|
}
|
|
|
|
else if (m_bottomGrip->isShown () &&
|
|
|
|
m_bottomGrip->hotRect (true/*to global*/)
|
|
|
|
.contains (TQCursor::pos ()))
|
|
|
|
{
|
|
|
|
m_bottomGrip->setUserMessage (i18n ("Left drag the handle to resize the image."));
|
|
|
|
}
|
|
|
|
else if (m_rightGrip->isShown () &&
|
|
|
|
m_rightGrip->hotRect (true/*to global*/)
|
|
|
|
.contains (TQCursor::pos ()))
|
|
|
|
{
|
|
|
|
m_rightGrip->setUserMessage (i18n ("Left drag the handle to resize the image."));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clearStatusMessage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clearStatusMessage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotContentsMoving (int x, int y)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotContentsMoving("
|
|
|
|
<< x << "," << y << ")"
|
|
|
|
<< " contentsX=" << contentsX ()
|
|
|
|
<< " contentsY=" << contentsY () << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_contentsXSoon = x, m_contentsYSoon = y;
|
|
|
|
emit contentsMovingSoon (m_contentsXSoon, m_contentsYSoon);
|
|
|
|
|
|
|
|
// Reduce flicker - don't let TQScrollView scroll to-be-erased lines
|
|
|
|
eraseResizeLines ();
|
|
|
|
|
|
|
|
TQTimer::singleShot (0, this, TQ_SLOT (slotContentsMoved ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotContentsMoved ()
|
|
|
|
{
|
|
|
|
m_contentsXSoon = m_contentsYSoon = -1;
|
|
|
|
|
|
|
|
kpGrip *grip = docResizingGrip ();
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotContentsMoved()"
|
|
|
|
<< " grip=" << grip
|
|
|
|
<< " contentsX=" << contentsX ()
|
|
|
|
<< " contentsY=" << contentsY () << endl;
|
|
|
|
#endif
|
|
|
|
if (!grip)
|
|
|
|
return;
|
|
|
|
|
|
|
|
grip->mouseMovedTo (grip->mapFromGlobal (TQCursor::pos ()),
|
|
|
|
true/*moved due to drag scroll*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::disconnectViewSignals ()
|
|
|
|
{
|
|
|
|
disconnect (m_view, TQ_SIGNAL (sizeChanged (const TQSize &)),
|
|
|
|
this, TQ_SLOT (updateGrips ()));
|
|
|
|
disconnect (m_view, TQ_SIGNAL (destroyed ()),
|
|
|
|
this, TQ_SLOT (slotViewDestroyed ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected
|
|
|
|
void kpViewScrollableContainer::connectViewSignals ()
|
|
|
|
{
|
|
|
|
connect (m_view, TQ_SIGNAL (sizeChanged (const TQSize &)),
|
|
|
|
this, TQ_SLOT (updateGrips ()));
|
|
|
|
connect (m_view, TQ_SIGNAL (destroyed ()),
|
|
|
|
this, TQ_SLOT (slotViewDestroyed ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::addChild (TQWidget *widget, int x, int y)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::addChild(" << widget
|
|
|
|
<< "," << x << "," << y << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::addChild (widget, x, y);
|
|
|
|
|
|
|
|
kpView *view = dynamic_cast <kpView *> (widget);
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "\tcast to kpView: " << view << endl;
|
|
|
|
#endif
|
|
|
|
if (view)
|
|
|
|
{
|
|
|
|
setView (view);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public
|
|
|
|
kpView *kpViewScrollableContainer::view () const
|
|
|
|
{
|
|
|
|
return m_view;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public
|
|
|
|
void kpViewScrollableContainer::setView (kpView *view)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::setView(" << view << ")" << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_view == view)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_view)
|
|
|
|
{
|
|
|
|
disconnectViewSignals ();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_view = view;
|
|
|
|
|
|
|
|
updateGrips ();
|
|
|
|
|
|
|
|
if (m_view)
|
|
|
|
{
|
|
|
|
connectViewSignals ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public slot
|
|
|
|
void kpViewScrollableContainer::updateGrips ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::updateGrips() m_view="
|
|
|
|
<< m_view << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_view)
|
|
|
|
{
|
|
|
|
m_bottomGrip->setFixedWidth (m_view->width ());
|
|
|
|
moveChild (m_bottomGrip, 0, m_view->height ());
|
|
|
|
|
|
|
|
m_rightGrip->setFixedHeight (m_view->height ());
|
|
|
|
moveChild (m_rightGrip, m_view->width (), 0);
|
|
|
|
|
|
|
|
moveChild (m_bottomRightGrip, m_view->width (), m_view->height ());
|
|
|
|
}
|
|
|
|
|
|
|
|
m_bottomGrip->setShown (bool (m_view));
|
|
|
|
m_rightGrip->setShown (bool (m_view));
|
|
|
|
m_bottomRightGrip->setShown (bool (m_view));
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "\tcontentsRect=" << contentsRect ()
|
|
|
|
<< " visibleRect=" << visibleRect ()
|
|
|
|
<< " viewportRect=" << viewport ()->rect ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_view)
|
|
|
|
{
|
|
|
|
resizeContents (m_view->width () + m_rightGrip->width (),
|
|
|
|
m_view->height () + m_bottomGrip->height ());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
resizeContents (0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
recalculateStatusMessage ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
void kpViewScrollableContainer::slotViewDestroyed ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotViewDestroyed() m_view="
|
|
|
|
<< m_view << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_view = 0;
|
|
|
|
updateGrips ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public slot
|
|
|
|
bool kpViewScrollableContainer::beginDragScroll (const TQPoint &/*docPoint*/,
|
|
|
|
const TQPoint &/*lastDocPoint*/,
|
|
|
|
int zoomLevel,
|
|
|
|
bool *didSomething)
|
|
|
|
{
|
|
|
|
if (didSomething)
|
|
|
|
*didSomething = false;
|
|
|
|
|
|
|
|
m_zoomLevel = zoomLevel;
|
|
|
|
|
|
|
|
const TQPoint p = mapFromGlobal (TQCursor::pos ());
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::beginDragScroll() p=" << p
|
|
|
|
<< " dragScrollTimerRunOnce=" << m_scrollTimerRunOnce
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool stopDragScroll = true;
|
|
|
|
bool scrolled = false;
|
|
|
|
|
|
|
|
if (!noDragScrollRect ().contains (p))
|
|
|
|
{
|
|
|
|
if (m_dragScrollTimer->isActive ())
|
|
|
|
{
|
|
|
|
if (m_scrollTimerRunOnce)
|
|
|
|
{
|
|
|
|
scrolled = slotDragScroll ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_scrollTimerRunOnce = false;
|
|
|
|
m_dragScrollTimer->start (DragScrollInitialInterval);
|
|
|
|
}
|
|
|
|
|
|
|
|
stopDragScroll = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stopDragScroll)
|
|
|
|
m_dragScrollTimer->stop ();
|
|
|
|
|
|
|
|
if (didSomething)
|
|
|
|
*didSomething = scrolled;
|
|
|
|
|
|
|
|
return scrolled;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public slot
|
|
|
|
bool kpViewScrollableContainer::beginDragScroll (const TQPoint &docPoint,
|
|
|
|
const TQPoint &lastDocPoint,
|
|
|
|
int zoomLevel)
|
|
|
|
{
|
|
|
|
return beginDragScroll (docPoint, lastDocPoint, zoomLevel,
|
|
|
|
0/*don't want scrolled notification*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// public slot
|
|
|
|
bool kpViewScrollableContainer::endDragScroll ()
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::endDragScroll()" << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (m_dragScrollTimer->isActive ())
|
|
|
|
{
|
|
|
|
m_dragScrollTimer->stop ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const int distanceFromRectToMultiplier (int dist)
|
|
|
|
{
|
|
|
|
if (dist < 0)
|
|
|
|
return 0;
|
|
|
|
else if (dist < DragDistanceFromRectMaxFor1stMultiplier)
|
|
|
|
return 1;
|
|
|
|
else if (dist < DragDistanceFromRectMaxFor2ndMultiplier)
|
|
|
|
return 2;
|
|
|
|
else
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
bool kpViewScrollableContainer::slotDragScroll (bool *didSomething)
|
|
|
|
{
|
|
|
|
bool scrolled = false;
|
|
|
|
|
|
|
|
if (didSomething)
|
|
|
|
*didSomething = false;
|
|
|
|
|
|
|
|
|
|
|
|
const TQRect rect = noDragScrollRect ();
|
|
|
|
const TQPoint pos = mapFromGlobal (TQCursor::pos ());
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotDragScroll()"
|
|
|
|
<< " noDragScrollRect=" << rect
|
|
|
|
<< " pos=" << pos
|
|
|
|
<< " contentsX=" << contentsX ()
|
|
|
|
<< " contentsY=" << contentsY () << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int dx = 0, dy = 0;
|
|
|
|
int dxMultiplier = 0, dyMultiplier = 0;
|
|
|
|
|
|
|
|
if (pos.x () < rect.left ())
|
|
|
|
{
|
|
|
|
dx = -DragScrollNumPixels;
|
|
|
|
dxMultiplier = distanceFromRectToMultiplier (rect.left () - pos.x ());
|
|
|
|
}
|
|
|
|
else if (pos.x () > rect.right ())
|
|
|
|
{
|
|
|
|
dx = +DragScrollNumPixels;
|
|
|
|
dxMultiplier = distanceFromRectToMultiplier (pos.x () - rect.right ());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pos.y () < rect.top ())
|
|
|
|
{
|
|
|
|
dy = -DragScrollNumPixels;
|
|
|
|
dyMultiplier = distanceFromRectToMultiplier (rect.top () - pos.y ());
|
|
|
|
}
|
|
|
|
else if (pos.y () > rect.bottom ())
|
|
|
|
{
|
|
|
|
dy = +DragScrollNumPixels;
|
|
|
|
dyMultiplier = distanceFromRectToMultiplier (pos.y () - rect.bottom ());
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0
|
|
|
|
kdDebug () << "kpViewScrollableContainer::slotDragScroll()"
|
|
|
|
<< " dx=" << dx << " * " << dxMultiplier
|
|
|
|
<< " dy=" << dy << " * " << dyMultiplier
|
|
|
|
<< " zoomLevel=" << m_zoomLevel
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
dx *= dxMultiplier;// * TQMAX (1, m_zoomLevel / 100);
|
|
|
|
dy *= dyMultiplier;// * TQMAX (1, m_zoomLevel / 100);
|
|
|
|
|
|
|
|
if (dx || dy)
|
|
|
|
{
|
|
|
|
const int oldContentsX = contentsX (),
|
|
|
|
oldContentsY = contentsY ();
|
|
|
|
|
|
|
|
scrollBy (dx, dy);
|
|
|
|
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 1
|
|
|
|
kdDebug () << "\tafter scrollBy():"
|
|
|
|
<< " contentsX=" << contentsX ()
|
|
|
|
<< " contentsY=" << contentsY () << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
scrolled = (oldContentsX != contentsX () ||
|
|
|
|
oldContentsY != contentsY ());
|
|
|
|
|
|
|
|
if (scrolled)
|
|
|
|
{
|
|
|
|
TQRegion region = TQRect (contentsX (), contentsY (),
|
|
|
|
visibleWidth (), visibleHeight ());
|
|
|
|
region -= TQRect (oldContentsX, oldContentsY,
|
|
|
|
visibleWidth (), visibleHeight ());
|
|
|
|
|
|
|
|
// Repaint newly exposed region immediately to reduce tearing
|
|
|
|
// of scrollView.
|
|
|
|
m_view->repaint (region, false/*no erase*/);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_dragScrollTimer->changeInterval (DragScrollInterval);
|
|
|
|
m_scrollTimerRunOnce = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (didSomething)
|
|
|
|
*didSomething = scrolled;
|
|
|
|
|
|
|
|
return scrolled;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::contentsDragMoveEvent (TQDragMoveEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::contentsDragMoveEvent"
|
|
|
|
<< e->pos ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::contentsDragMoveEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected slot
|
|
|
|
bool kpViewScrollableContainer::slotDragScroll ()
|
|
|
|
{
|
|
|
|
return slotDragScroll (0/*don't want scrolled notification*/);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::contentsMouseMoveEvent (TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::contentsMouseMoveEvent"
|
|
|
|
<< e->pos ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::contentsMouseMoveEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::mouseMoveEvent (TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::mouseMoveEvent"
|
|
|
|
<< e->pos ()
|
|
|
|
<< endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::mouseMoveEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::contentsWheelEvent (TQWheelEvent *e)
|
|
|
|
{
|
|
|
|
e->ignore ();
|
|
|
|
|
|
|
|
if (m_view)
|
|
|
|
m_view->wheelEvent (e);
|
|
|
|
|
|
|
|
if (!e->isAccepted ())
|
|
|
|
TQScrollView::contentsWheelEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TQRect kpViewScrollableContainer::noDragScrollRect () const
|
|
|
|
{
|
|
|
|
return TQRect (DragScrollLeftTopMargin, DragScrollLeftTopMargin,
|
|
|
|
width () - DragScrollLeftTopMargin - DragScrollRightBottomMargin,
|
|
|
|
height () - DragScrollLeftTopMargin - DragScrollRightBottomMargin);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
bool kpViewScrollableContainer::eventFilter (TQObject *watchedObject, TQEvent *event)
|
|
|
|
{
|
|
|
|
return TQScrollView::eventFilter (watchedObject, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::viewportPaintEvent (TQPaintEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER
|
|
|
|
kdDebug () << "kpViewScrollableContainer::viewportPaintEvent("
|
|
|
|
<< e->rect ()
|
|
|
|
<< ")" << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::viewportPaintEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQFrame]
|
|
|
|
void kpViewScrollableContainer::paintEvent (TQPaintEvent *e)
|
|
|
|
{
|
|
|
|
#if DEBUG_KP_VIEW_SCROLLABLE_CONTAINER && 0
|
|
|
|
kdDebug () << "kpViewScrollableContainer::paintEvent("
|
|
|
|
<< e->rect ()
|
|
|
|
<< ")" << endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TQScrollView::paintEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected virtual [base TQScrollView]
|
|
|
|
void kpViewScrollableContainer::resizeEvent (TQResizeEvent *e)
|
|
|
|
{
|
|
|
|
TQScrollView::resizeEvent (e);
|
|
|
|
|
|
|
|
emit resized ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include <kpviewscrollablecontainer.moc>
|