summaryrefslogtreecommitdiffstats
path: root/src/widgets/tqscrollview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/tqscrollview.cpp')
-rw-r--r--src/widgets/tqscrollview.cpp2847
1 files changed, 2847 insertions, 0 deletions
diff --git a/src/widgets/tqscrollview.cpp b/src/widgets/tqscrollview.cpp
new file mode 100644
index 000000000..603110592
--- /dev/null
+++ b/src/widgets/tqscrollview.cpp
@@ -0,0 +1,2847 @@
+/****************************************************************************
+**
+** Implementation of TQScrollView class
+**
+** Created : 950524
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidget.h"
+#ifndef TQT_NO_SCROLLVIEW
+#include "tqscrollbar.h"
+#include "tqobjectlist.h"
+#include "tqpainter.h"
+#include "tqpixmap.h"
+#include "ntqcursor.h"
+#include "ntqfocusdata.h"
+#include "tqscrollview.h"
+#include "tqptrdict.h"
+#include "ntqapplication.h"
+#include "tqtimer.h"
+#include "tqstyle.h"
+#include "ntqlistview.h"
+#ifdef TQ_WS_MAC
+# include "qt_mac.h"
+#endif
+
+static const int coord_limit = 4000;
+static const int autoscroll_margin = 16;
+static const int initialScrollTime = 30;
+static const int initialScrollAccel = 5;
+
+struct TQSVChildRec {
+ TQSVChildRec(TQWidget* c, int xx, int yy) :
+ child(c),
+ x(xx), y(yy)
+ {
+ }
+
+ void hideOrShow(TQScrollView* sv, TQWidget* clipped_viewport);
+ void moveTo(TQScrollView* sv, int xx, int yy, TQWidget* clipped_viewport)
+ {
+ if ( x != xx || y != yy ) {
+ x = xx;
+ y = yy;
+ hideOrShow(sv,clipped_viewport);
+ }
+ }
+ TQWidget* child;
+ int x, y;
+};
+
+void TQSVChildRec::hideOrShow(TQScrollView* sv, TQWidget* clipped_viewport)
+{
+ if ( clipped_viewport ) {
+ if ( x+child->width() < sv->contentsX()+clipped_viewport->x()
+ || x > sv->contentsX()+clipped_viewport->width()
+ || y+child->height() < sv->contentsY()+clipped_viewport->y()
+ || y > sv->contentsY()+clipped_viewport->height() ) {
+ child->move(clipped_viewport->width(),
+ clipped_viewport->height());
+ } else {
+ child->move(x-sv->contentsX()-clipped_viewport->x(),
+ y-sv->contentsY()-clipped_viewport->y());
+ }
+ } else {
+ child->move(x-sv->contentsX(), y-sv->contentsY());
+ }
+}
+
+class TQViewportWidget : public TQWidget
+{
+ TQ_OBJECT
+
+public:
+ TQViewportWidget( TQScrollView* parent=0, const char* name=0, WFlags f = 0 )
+ : TQWidget( parent, name, f ) {}
+};
+
+class TQClipperWidget : public TQWidget
+{
+ TQ_OBJECT
+
+public:
+ TQClipperWidget( TQWidget * parent=0, const char * name=0, WFlags f=0 )
+ : TQWidget ( parent,name,f) {}
+};
+
+#include "tqscrollview.moc"
+
+class TQScrollViewData {
+public:
+ TQScrollViewData(TQScrollView* parent, int vpwflags) :
+ hbar( new TQScrollBar( TQScrollBar::Horizontal, parent, "qt_hbar" ) ),
+ vbar( new TQScrollBar( TQScrollBar::Vertical, parent, "qt_vbar" ) ),
+ viewport( new TQViewportWidget( parent, "qt_viewport", vpwflags ) ),
+ clipped_viewport( 0 ),
+ flags( vpwflags ),
+ vx( 0 ), vy( 0 ), vwidth( 1 ), vheight( 1 ),
+#ifndef TQT_NO_DRAGANDDROP
+ autoscroll_timer( parent, "scrollview autoscroll timer" ),
+ drag_autoscroll( TRUE ),
+#endif
+ scrollbar_timer( parent, "scrollview scrollbar timer" ),
+ inresize( FALSE ), use_cached_size_hint( TRUE )
+ {
+ l_marg = r_marg = t_marg = b_marg = 0;
+ viewport->polish();
+ viewport->setBackgroundMode( TQWidget::PaletteDark );
+ viewport->setBackgroundOrigin( TQWidget::WidgetOrigin );
+ vMode = TQScrollView::Auto;
+ hMode = TQScrollView::Auto;
+ corner = 0;
+ defaultCorner = new TQWidget( parent, "qt_default_corner" );
+ defaultCorner->hide();
+ vbar->setSteps( 20, 1/*set later*/ );
+ hbar->setSteps( 20, 1/*set later*/ );
+ policy = TQScrollView::Default;
+ signal_choke = FALSE;
+ static_bg = FALSE;
+ fake_scroll = FALSE;
+ hbarPressed = FALSE;
+ vbarPressed = FALSE;
+ }
+ ~TQScrollViewData();
+
+ TQSVChildRec* rec(TQWidget* w) { return childDict.find(w); }
+ TQSVChildRec* ancestorRec(TQWidget* w);
+ TQSVChildRec* addChildRec(TQWidget* w, int x, int y )
+ {
+ TQSVChildRec *r = new TQSVChildRec(w,x,y);
+ children.append(r);
+ childDict.insert(w, r);
+ return r;
+ }
+ void deleteChildRec(TQSVChildRec* r)
+ {
+ childDict.remove(r->child);
+ children.removeRef(r);
+ delete r;
+ }
+
+ void hideOrShowAll(TQScrollView* sv, bool isScroll = FALSE );
+ void moveAllBy(int dx, int dy);
+ bool anyVisibleChildren();
+ void autoMove(TQScrollView* sv);
+ void autoResize(TQScrollView* sv);
+ void autoResizeHint(TQScrollView* sv);
+ void viewportResized( int w, int h );
+
+ TQScrollBar* hbar;
+ TQScrollBar* vbar;
+ bool hbarPressed;
+ bool vbarPressed;
+ TQViewportWidget* viewport;
+ TQClipperWidget* clipped_viewport;
+ int flags;
+ TQPtrList<TQSVChildRec> children;
+ TQPtrDict<TQSVChildRec> childDict;
+ TQWidget* corner, *defaultCorner;
+ int vx, vy, vwidth, vheight; // for drawContents-style usage
+ int l_marg, r_marg, t_marg, b_marg;
+ TQScrollView::ResizePolicy policy;
+ TQScrollView::ScrollBarMode vMode;
+ TQScrollView::ScrollBarMode hMode;
+#ifndef TQT_NO_DRAGANDDROP
+ TQPoint cpDragStart;
+ TQTimer autoscroll_timer;
+ int autoscroll_time;
+ int autoscroll_accel;
+ bool drag_autoscroll;
+#endif
+ TQTimer scrollbar_timer;
+
+ uint static_bg : 1;
+ uint fake_scroll : 1;
+
+ // This variable allows ensureVisible to move the contents then
+ // update both the sliders. Otherwise, updating the sliders would
+ // cause two image scrolls, creating ugly flashing.
+ //
+ uint signal_choke : 1;
+
+ // This variables indicates in updateScrollBars() that we are
+ // in a resizeEvent() and thus don't want to flash scrollbars
+ uint inresize : 1;
+ uint use_cached_size_hint : 1;
+ TQSize cachedSizeHint;
+
+ inline int contentsX() const { return -vx; }
+ inline int contentsY() const { return -vy; }
+ inline int contentsWidth() const { return vwidth; }
+};
+
+inline TQScrollViewData::~TQScrollViewData()
+{
+ children.setAutoDelete( TRUE );
+}
+
+TQSVChildRec* TQScrollViewData::ancestorRec(TQWidget* w)
+{
+ if ( clipped_viewport ) {
+ while (w->parentWidget() != clipped_viewport) {
+ w = w->parentWidget();
+ if (!w) return 0;
+ }
+ } else {
+ while (w->parentWidget() != viewport) {
+ w = w->parentWidget();
+ if (!w) return 0;
+ }
+ }
+ return rec(w);
+}
+
+void TQScrollViewData::hideOrShowAll(TQScrollView* sv, bool isScroll )
+{
+ if ( !clipped_viewport )
+ return;
+ if ( clipped_viewport->x() <= 0
+ && clipped_viewport->y() <= 0
+ && clipped_viewport->width()+clipped_viewport->x() >=
+ viewport->width()
+ && clipped_viewport->height()+clipped_viewport->y() >=
+ viewport->height() ) {
+ // clipped_viewport still covers viewport
+ if( static_bg )
+ clipped_viewport->repaint( TRUE );
+ else if ( ( !isScroll && !clipped_viewport->testWFlags( TQt::WStaticContents) )
+ || static_bg )
+ TQApplication::postEvent( clipped_viewport,
+ new TQPaintEvent( clipped_viewport->clipRegion(),
+ !clipped_viewport->testWFlags(TQt::WResizeNoErase) ) );
+ } else {
+ // Re-center
+ int nx = ( viewport->width() - clipped_viewport->width() ) / 2;
+ int ny = ( viewport->height() - clipped_viewport->height() ) / 2;
+ clipped_viewport->move(nx,ny);
+ clipped_viewport->update();
+ }
+ for (TQSVChildRec *r = children.first(); r; r=children.next()) {
+ r->hideOrShow(sv, clipped_viewport);
+ }
+}
+
+void TQScrollViewData::moveAllBy(int dx, int dy)
+{
+ if ( clipped_viewport && !static_bg ) {
+ clipped_viewport->move( clipped_viewport->x()+dx,
+ clipped_viewport->y()+dy );
+ } else {
+ for (TQSVChildRec *r = children.first(); r; r=children.next()) {
+ r->child->move(r->child->x()+dx,r->child->y()+dy);
+ }
+ if ( static_bg )
+ viewport->repaint( TRUE );
+ }
+}
+
+bool TQScrollViewData::anyVisibleChildren()
+{
+ for (TQSVChildRec *r = children.first(); r; r=children.next()) {
+ if (r->child->isVisible()) return TRUE;
+ }
+ return FALSE;
+}
+
+void TQScrollViewData::autoMove(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = children.first();
+ if (r)
+ sv->setContentsPos(-r->child->x(),-r->child->y());
+ }
+}
+
+void TQScrollViewData::autoResize(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = children.first();
+ if (r)
+ sv->resizeContents(r->child->width(),r->child->height());
+ }
+}
+
+void TQScrollViewData::autoResizeHint(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = children.first();
+ if (r) {
+ TQSize s = r->child->sizeHint();
+ if ( s.isValid() )
+ r->child->resize(s);
+ }
+ } else if ( policy == TQScrollView::AutoOneFit ) {
+ TQSVChildRec* r = children.first();
+ if (r) {
+ TQSize sh = r->child->sizeHint();
+ sh = sh.boundedTo( r->child->maximumSize() );
+ sv->resizeContents( sh.width(), sh.height() );
+ }
+ }
+}
+
+void TQScrollViewData::viewportResized( int w, int h )
+{
+ if ( policy == TQScrollView::AutoOneFit ) {
+ TQSVChildRec* r = children.first();
+ if (r) {
+ TQSize sh = r->child->sizeHint();
+ sh = sh.boundedTo( r->child->maximumSize() );
+ r->child->resize( TQMAX(w,sh.width()), TQMAX(h,sh.height()) );
+ }
+
+ }
+}
+
+
+/*!
+ \class TQScrollView tqscrollview.h
+ \brief The TQScrollView widget provides a scrolling area with on-demand scroll bars.
+
+ \ingroup abstractwidgets
+ \mainclass
+
+ The TQScrollView is a large canvas - potentially larger than the
+ coordinate system normally supported by the underlying window
+ system. This is important because it is quite easy to go beyond
+ these limitations (e.g. many web pages are more than 32000 pixels
+ high). Additionally, the TQScrollView can have TQWidgets positioned
+ on it that scroll around with the drawn content. These sub-widgets
+ can also have positions outside the normal coordinate range (but
+ they are still limited in size).
+
+ To provide content for the widget, inherit from TQScrollView,
+ reimplement drawContents() and use resizeContents() to set the
+ size of the viewed area. Use addChild() and moveChild() to
+ position widgets on the view.
+
+ To use TQScrollView effectively it is important to understand its
+ widget structure in the three styles of use: a single large child
+ widget, a large panning area with some widgets and a large panning
+ area with many widgets.
+
+ \section1 Using One Big Widget
+
+ \img tqscrollview-vp2.png
+
+ The first, simplest usage of TQScrollView (depicted above), is
+ appropriate for scrolling areas that are never more than about
+ 4000 pixels in either dimension (this is about the maximum
+ reliable size on X11 servers). In this usage, you just make one
+ large child in the TQScrollView. The child should be a child of the
+ viewport() of the scrollview and be added with addChild():
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ TQVBox* big_box = new TQVBox(sv->viewport());
+ sv->addChild(big_box);
+ \endcode
+ You can go on to add arbitrary child widgets to the single child
+ in the scrollview as you would with any widget:
+ \code
+ TQLabel* child1 = new TQLabel("CHILD", big_box);
+ TQLabel* child2 = new TQLabel("CHILD", big_box);
+ TQLabel* child3 = new TQLabel("CHILD", big_box);
+ ...
+ \endcode
+
+ Here the TQScrollView has four children: the viewport(), the
+ verticalScrollBar(), the horizontalScrollBar() and a small
+ cornerWidget(). The viewport() has one child: the big TQVBox. The
+ TQVBox has the three TQLabel objects as child widgets. When the view
+ is scrolled, the TQVBox is moved; its children move with it as
+ child widgets normally do.
+
+ \section1 Using a Very Big View with Some Widgets
+
+ \img tqscrollview-vp.png
+
+ The second usage of TQScrollView (depicted above) is appropriate
+ when few, if any, widgets are on a very large scrolling area that
+ is potentially larger than 4000 pixels in either dimension. In
+ this usage you call resizeContents() to set the size of the area
+ and reimplement drawContents() to paint the contents. You may also
+ add some widgets by making them children of the viewport() and
+ adding them with addChild() (this is the same as the process for
+ the single large widget in the previous example):
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ TQLabel* child1 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child1);
+ TQLabel* child2 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child2);
+ TQLabel* child3 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child3);
+ \endcode
+ Here, the TQScrollView has the same four children: the viewport(),
+ the verticalScrollBar(), the horizontalScrollBar() and a small
+ cornerWidget(). The viewport() has the three TQLabel objects as
+ child widgets. When the view is scrolled, the scrollview moves the
+ child widgets individually.
+
+ \section1 Using a Very Big View with Many Widgets
+
+ \target enableclipper
+ \img tqscrollview-cl.png
+
+ The final usage of TQScrollView (depicted above) is appropriate
+ when many widgets are on a very large scrolling area that is
+ potentially larger than 4000 pixels in either dimension. In this
+ usage you call resizeContents() to set the size of the area and
+ reimplement drawContents() to paint the contents. You then call
+ enableClipper(TRUE) and add widgets, again by making them children
+ of the viewport(), and adding them with addChild():
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ sv->enableClipper(TRUE);
+ TQLabel* child1 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child1);
+ TQLabel* child2 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child2);
+ TQLabel* child3 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child3);
+ \endcode
+
+ Here, the TQScrollView has four children: the clipper() (not the
+ viewport() this time), the verticalScrollBar(), the
+ horizontalScrollBar() and a small cornerWidget(). The clipper()
+ has one child: the viewport(). The viewport() has the same three
+ labels as child widgets. When the view is scrolled the viewport()
+ is moved; its children move with it as child widgets normally do.
+
+ \target allviews
+ \section1 Details Relevant for All Views
+
+ Normally you will use the first or third method if you want any
+ child widgets in the view.
+
+ Note that the widget you see in the scrolled area is the
+ viewport() widget, not the TQScrollView itself. So to turn mouse
+ tracking on, for example, use viewport()->setMouseTracking(TRUE).
+
+ To enable drag-and-drop, you would setAcceptDrops(TRUE) on the
+ TQScrollView (because drag-and-drop events propagate to the
+ parent). But to work out the logical position in the view, you
+ would need to map the drop co-ordinate from being relative to the
+ TQScrollView to being relative to the contents; use the function
+ viewportToContents() for this.
+
+ To handle mouse events on the scrolling area, subclass scrollview
+ as you would subclass other widgets, but rather than
+ reimplementing mousePressEvent(), reimplement
+ contentsMousePressEvent() instead. The contents specific event
+ handlers provide translated events in the coordinate system of the
+ scrollview. If you reimplement mousePressEvent(), you'll get
+ called only when part of the TQScrollView is clicked: and the only
+ such part is the "corner" (if you don't set a cornerWidget()) and
+ the frame; everything else is covered up by the viewport, clipper
+ or scroll bars.
+
+ When you construct a TQScrollView, some of the widget flags apply
+ to the viewport() instead of being sent to the TQWidget constructor
+ for the TQScrollView. This applies to \c WNoAutoErase, \c
+ WStaticContents, and \c WPaintClever. See \l TQt::WidgetFlags for
+ documentation about these flags. Here are some examples:
+
+ \list
+
+ \i An image-manipulation widget would use \c
+ WNoAutoErase|WStaticContents because the widget draws all pixels
+ itself, and when its size increases, it only needs a paint event
+ for the new part because the old part remains unchanged.
+
+ \i A scrolling game widget in which the background scrolls as the
+ characters move might use \c WNoAutoErase (in addition to \c
+ WStaticContents) so that the window system background does not
+ flash in and out during scrolling.
+
+ \i A word processing widget might use \c WNoAutoErase and repaint
+ itself line by line to get a less-flickery resizing. If the widget
+ is in a mode in which no text justification can take place, it
+ might use \c WStaticContents too, so that it would only get a
+ repaint for the newly visible parts.
+
+ \endlist
+
+ Child widgets may be moved using addChild() or moveChild(). Use
+ childX() and childY() to get the position of a child widget.
+
+ A widget may be placed in the corner between the vertical and
+ horizontal scrollbars with setCornerWidget(). You can get access
+ to the scrollbars using horizontalScrollBar() and
+ verticalScrollBar(), and to the viewport with viewport(). The
+ scroll view can be scrolled using scrollBy(), ensureVisible(),
+ setContentsPos() or center().
+
+ The visible area is given by visibleWidth() and visibleHeight(),
+ and the contents area by contentsWidth() and contentsHeight(). The
+ contents may be repainted using one of the repaintContents() or
+ updateContents() functions.
+
+ Coordinate conversion is provided by contentsToViewport() and
+ viewportToContents().
+
+ The contentsMoving() signal is emitted just before the contents
+ are moved to a new position.
+
+ \warning TQScrollView currently does not erase the background when
+ resized, i.e. you must always clear the background manually in
+ scrollview subclasses. This will change in a future version of TQt
+ and we recommend specifying the WNoAutoErase flag explicitly.
+
+ <img src=tqscrollview-m.png> <img src=tqscrollview-w.png>
+*/
+
+
+/*!
+ \enum TQScrollView::ResizePolicy
+
+ This enum type is used to control a TQScrollView's reaction to
+ resize events.
+
+ \value Default the TQScrollView selects one of the other settings
+ automatically when it has to. In this version of TQt, TQScrollView
+ changes to \c Manual if you resize the contents with
+ resizeContents() and to \c AutoOne if a child is added.
+
+ \value Manual the contents stays the size set by resizeContents().
+
+ \value AutoOne if there is only one child widget the contents stays
+ the size of that widget. Otherwise the behavior is undefined.
+
+ \value AutoOneFit if there is only one child widget the contents stays
+ the size of that widget's sizeHint(). If the scrollview is resized
+ larger than the child's sizeHint(), the child will be resized to
+ fit. If there is more than one child, the behavior is undefined.
+
+*/
+//#### The widget will be resized to its sizeHint() when a LayoutHint event
+//#### is received
+
+/*!
+ Constructs a TQScrollView called \a name with parent \a parent and
+ widget flags \a f.
+
+ The widget flags \c WStaticContents, \c WNoAutoErase and \c
+ WPaintClever are propagated to the viewport() widget. The other
+ widget flags are propagated to the parent constructor as usual.
+*/
+
+TQScrollView::TQScrollView( TQWidget *parent, const char *name, WFlags f ) :
+ TQFrame( parent, name, f & (~WStaticContents) & (~WResizeNoErase) )
+{
+ WFlags flags = WResizeNoErase | (f&WPaintClever) | (f&WRepaintNoErase) | (f&WStaticContents);
+ d = new TQScrollViewData( this, flags );
+
+#ifndef TQT_NO_DRAGANDDROP
+ connect( &d->autoscroll_timer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( doDragAutoScroll() ) );
+#endif
+
+ connect( d->hbar, TQ_SIGNAL( valueChanged(int) ),
+ this, TQ_SLOT( hslide(int) ) );
+ connect( d->vbar, TQ_SIGNAL( valueChanged(int) ),
+ this, TQ_SLOT( vslide(int) ) );
+
+ connect( d->hbar, TQ_SIGNAL(sliderPressed()), this, TQ_SLOT(hbarIsPressed()) );
+ connect( d->hbar, TQ_SIGNAL(sliderReleased()), this, TQ_SLOT(hbarIsReleased()) );
+ connect( d->vbar, TQ_SIGNAL(sliderPressed()), this, TQ_SLOT(vbarIsPressed()) );
+ connect( d->vbar, TQ_SIGNAL(sliderReleased()), this, TQ_SLOT(vbarIsReleased()) );
+
+
+ d->viewport->installEventFilter( this );
+
+ connect( &d->scrollbar_timer, TQ_SIGNAL( timeout() ),
+ this, TQ_SLOT( updateScrollBars() ) );
+
+ setFrameStyle( TQFrame::StyledPanel | TQFrame::Sunken );
+ setLineWidth( style().pixelMetric(TQStyle::PM_DefaultFrameWidth, this) );
+ setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+}
+
+
+/*!
+ Destroys the TQScrollView. Any children added with addChild() will
+ be deleted.
+*/
+TQScrollView::~TQScrollView()
+{
+ // Be careful not to get all those useless events...
+ if ( d->clipped_viewport )
+ d->clipped_viewport->removeEventFilter( this );
+ else
+ d->viewport->removeEventFilter( this );
+
+ // order is important
+ // ~TQWidget may cause a WM_ERASEBKGND on Windows
+ delete d->vbar;
+ d->vbar = 0;
+ delete d->hbar;
+ d->hbar = 0;
+ delete d->viewport;
+ d->viewport = 0;
+ delete d;
+ d = 0;
+}
+
+/*!
+ \fn void TQScrollView::horizontalSliderPressed()
+
+ This signal is emitted whenever the user presses the horizontal slider.
+*/
+/*!
+ \fn void TQScrollView::horizontalSliderReleased()
+
+ This signal is emitted whenever the user releases the horizontal slider.
+*/
+/*!
+ \fn void TQScrollView::verticalSliderPressed()
+
+ This signal is emitted whenever the user presses the vertical slider.
+*/
+/*!
+ \fn void TQScrollView::verticalSliderReleased()
+
+ This signal is emitted whenever the user releases the vertical slider.
+*/
+void TQScrollView::hbarIsPressed()
+{
+ d->hbarPressed = TRUE;
+ emit( horizontalSliderPressed() );
+}
+
+void TQScrollView::hbarIsReleased()
+{
+ d->hbarPressed = FALSE;
+ emit( horizontalSliderReleased() );
+}
+
+/*!
+ Returns TRUE if horizontal slider is pressed by user; otherwise returns FALSE.
+*/
+bool TQScrollView::isHorizontalSliderPressed()
+{
+ return d->hbarPressed;
+}
+
+void TQScrollView::vbarIsPressed()
+{
+ d->vbarPressed = TRUE;
+ emit( verticalSliderPressed() );
+}
+
+void TQScrollView::vbarIsReleased()
+{
+ d->vbarPressed = FALSE;
+ emit( verticalSliderReleased() );
+}
+
+/*!
+ Returns TRUE if vertical slider is pressed by user; otherwise returns FALSE.
+*/
+bool TQScrollView::isVerticalSliderPressed()
+{
+ return d->vbarPressed;
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::styleChange( TQStyle& old )
+{
+ TQWidget::styleChange( old );
+ updateScrollBars();
+ d->cachedSizeHint = TQSize();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::fontChange( const TQFont &old )
+{
+ TQWidget::fontChange( old );
+ updateScrollBars();
+ d->cachedSizeHint = TQSize();
+}
+
+void TQScrollView::hslide( int pos )
+{
+ if ( !d->signal_choke ) {
+ moveContents( -pos, -d->contentsY() );
+ TQApplication::syncX();
+ }
+}
+
+void TQScrollView::vslide( int pos )
+{
+ if ( !d->signal_choke ) {
+ moveContents( -d->contentsX(), -pos );
+ TQApplication::syncX();
+ }
+}
+
+/*!
+ Called when the horizontal scroll bar geometry changes. This is
+ provided as a protected function so that subclasses can do
+ interesting things such as providing extra buttons in some of the
+ space normally used by the scroll bars.
+
+ The default implementation simply gives all the space to \a hbar.
+ The new geometry is given by \a x, \a y, \a w and \a h.
+
+ \sa setVBarGeometry()
+*/
+void TQScrollView::setHBarGeometry(TQScrollBar& hbar,
+ int x, int y, int w, int h)
+{
+ hbar.setGeometry( x, y, w, h );
+}
+
+/*!
+ Called when the vertical scroll bar geometry changes. This is
+ provided as a protected function so that subclasses can do
+ interesting things such as providing extra buttons in some of the
+ space normally used by the scroll bars.
+
+ The default implementation simply gives all the space to \a vbar.
+ The new geometry is given by \a x, \a y, \a w and \a h.
+
+ \sa setHBarGeometry()
+*/
+void TQScrollView::setVBarGeometry( TQScrollBar& vbar,
+ int x, int y, int w, int h)
+{
+ vbar.setGeometry( x, y, w, h );
+}
+
+
+/*!
+ Returns the viewport size for size (\a x, \a y).
+
+ The viewport size depends on \a (x, y) (the size of the contents),
+ the size of this widget and the modes of the horizontal and
+ vertical scroll bars.
+
+ This function permits widgets that can trade vertical and
+ horizontal space for each other to control scroll bar appearance
+ better. For example, a word processor or web browser can control
+ the width of the right margin accurately, whether or not there
+ needs to be a vertical scroll bar.
+*/
+
+TQSize TQScrollView::viewportSize( int x, int y ) const
+{
+ int fw = frameWidth();
+ int lmarg = fw+d->l_marg;
+ int rmarg = fw+d->r_marg;
+ int tmarg = fw+d->t_marg;
+ int bmarg = fw+d->b_marg;
+
+ int w = width();
+ int h = height();
+
+ bool needh, needv;
+ bool showh, showv;
+ int hsbExt = horizontalScrollBar()->sizeHint().height();
+ int vsbExt = verticalScrollBar()->sizeHint().width();
+
+ if ( d->policy != AutoOne || d->anyVisibleChildren() ) {
+ // Do we definitely need the scrollbar?
+ needh = w-lmarg-rmarg < x;
+ needv = h-tmarg-bmarg < y;
+
+ // Do we intend to show the scrollbar?
+ if (d->hMode == AlwaysOn)
+ showh = TRUE;
+ else if (d->hMode == AlwaysOff)
+ showh = FALSE;
+ else
+ showh = needh;
+
+ if (d->vMode == AlwaysOn)
+ showv = TRUE;
+ else if (d->vMode == AlwaysOff)
+ showv = FALSE;
+ else
+ showv = needv;
+
+ // Given other scrollbar will be shown, NOW do we need one?
+ if ( showh && h-vsbExt-tmarg-bmarg < y ) {
+ if (d->vMode == Auto)
+ showv=TRUE;
+ }
+ if ( showv && w-hsbExt-lmarg-rmarg < x ) {
+ if (d->hMode == Auto)
+ showh=TRUE;
+ }
+ } else {
+ // Scrollbars not needed, only show scrollbar that are always on.
+ showh = d->hMode == AlwaysOn;
+ showv = d->vMode == AlwaysOn;
+ }
+
+ return TQSize( w-lmarg-rmarg - (showv ? vsbExt : 0),
+ h-tmarg-bmarg - (showh ? hsbExt : 0) );
+}
+
+
+/*!
+ Updates scroll bars: all possibilities are considered. You should
+ never need to call this in your code.
+*/
+void TQScrollView::updateScrollBars()
+{
+ if(!horizontalScrollBar() && !verticalScrollBar())
+ return;
+
+ // I support this should use viewportSize()... but it needs
+ // so many of the temporary variables from viewportSize. hm.
+ int fw = frameWidth();
+ int lmarg = fw+d->l_marg;
+ int rmarg = fw+d->r_marg;
+ int tmarg = fw+d->t_marg;
+ int bmarg = fw+d->b_marg;
+
+ int w = width();
+ int h = height();
+
+ int portw, porth;
+
+ bool needh;
+ bool needv;
+ bool showh;
+ bool showv;
+ bool showc = FALSE;
+
+ int hsbExt = horizontalScrollBar()->sizeHint().height();
+ int vsbExt = verticalScrollBar()->sizeHint().width();
+
+ TQSize oldVisibleSize( visibleWidth(), visibleHeight() );
+
+ if ( d->policy != AutoOne || d->anyVisibleChildren() ) {
+ // Do we definitely need the scrollbar?
+ needh = w-lmarg-rmarg < d->contentsWidth();
+ if ( d->inresize )
+ needh = !horizontalScrollBar()->isHidden();
+ needv = h-tmarg-bmarg < contentsHeight();
+
+ // Do we intend to show the scrollbar?
+ if (d->hMode == AlwaysOn)
+ showh = TRUE;
+ else if (d->hMode == AlwaysOff)
+ showh = FALSE;
+ else
+ showh = needh;
+
+ if (d->vMode == AlwaysOn)
+ showv = TRUE;
+ else if (d->vMode == AlwaysOff)
+ showv = FALSE;
+ else
+ showv = needv;
+
+#ifdef TQ_WS_MAC
+ bool mac_need_scroll = FALSE;
+ if(!parentWidget()) {
+ mac_need_scroll = TRUE;
+ } else {
+ TQWidget *tlw = topLevelWidget();
+ TQPoint tlw_br = TQPoint(tlw->width(), tlw->height()),
+ my_br = posInWindow(this) + TQPoint(w, h);
+ if(my_br.x() >= tlw_br.x() - 3 && my_br.y() >= tlw_br.y() - 3)
+ mac_need_scroll = TRUE;
+ }
+ if(mac_need_scroll) {
+ WindowAttributes attr;
+ GetWindowAttributes((WindowPtr)handle(), &attr);
+ mac_need_scroll = (attr & kWindowResizableAttribute);
+ }
+ if(mac_need_scroll) {
+ showc = TRUE;
+ if(d->vMode == Auto)
+ showv = TRUE;
+ if(d->hMode == Auto)
+ showh = TRUE;
+ }
+#endif
+
+ // Given other scrollbar will be shown, NOW do we need one?
+ if ( showh && h-vsbExt-tmarg-bmarg < contentsHeight() ) {
+ needv=TRUE;
+ if (d->vMode == Auto)
+ showv=TRUE;
+ }
+ if ( showv && !d->inresize && w-hsbExt-lmarg-rmarg < d->contentsWidth() ) {
+ needh=TRUE;
+ if (d->hMode == Auto)
+ showh=TRUE;
+ }
+ } else {
+ // Scrollbars not needed, only show scrollbar that are always on.
+ needh = needv = FALSE;
+ showh = d->hMode == AlwaysOn;
+ showv = d->vMode == AlwaysOn;
+ }
+
+ bool sc = d->signal_choke;
+ d->signal_choke=TRUE;
+
+ // Hide unneeded scrollbar, calculate viewport size
+ if ( showh ) {
+ porth=h-hsbExt-tmarg-bmarg;
+ } else {
+ if (!needh)
+ d->hbar->setValue(0);
+ d->hbar->hide();
+ porth=h-tmarg-bmarg;
+ }
+ if ( showv ) {
+ portw=w-vsbExt-lmarg-rmarg;
+ } else {
+ if (!needv)
+ d->vbar->setValue(0);
+ d->vbar->hide();
+ portw=w-lmarg-rmarg;
+ }
+
+ // Configure scrollbars that we will show
+ if ( needv ) {
+ d->vbar->setRange( 0, contentsHeight()-porth );
+ d->vbar->setSteps( TQScrollView::d->vbar->lineStep(), porth );
+ } else {
+ d->vbar->setRange( 0, 0 );
+ }
+ if ( needh ) {
+ d->hbar->setRange( 0, TQMAX(0, d->contentsWidth()-portw) );
+ d->hbar->setSteps( TQScrollView::d->hbar->lineStep(), portw );
+ } else {
+ d->hbar->setRange( 0, 0 );
+ }
+
+ // Position the scrollbars, viewport and corner widget.
+ int bottom;
+ bool reverse = TQApplication::reverseLayout();
+ int xoffset = ( reverse && (showv || cornerWidget() )) ? vsbExt : 0;
+ int xpos = reverse ? 0 : w - vsbExt;
+ bool frameContentsOnly =
+ style().styleHint(TQStyle::SH_ScrollView_FrameOnlyAroundContents);
+
+ if( ! frameContentsOnly ) {
+ if ( reverse )
+ xpos += fw;
+ else
+ xpos -= fw;
+ }
+ if ( showh ) {
+ int right = ( showc || showv || cornerWidget() ) ? w-vsbExt : w;
+ if ( ! frameContentsOnly )
+ setHBarGeometry( *d->hbar, fw + xoffset, h-hsbExt-fw,
+ right-fw-fw, hsbExt );
+ else
+ setHBarGeometry( *d->hbar, 0 + xoffset, h-hsbExt, right,
+ hsbExt );
+ bottom=h-hsbExt;
+ } else {
+ bottom=h;
+ }
+ if ( showv ) {
+ clipper()->setGeometry( lmarg + xoffset, tmarg,
+ w-vsbExt-lmarg-rmarg,
+ bottom-tmarg-bmarg );
+ d->viewportResized( w-vsbExt-lmarg-rmarg, bottom-tmarg-bmarg );
+ if ( ! frameContentsOnly )
+ changeFrameRect(TQRect(0, 0, w, h) );
+ else
+ changeFrameRect(TQRect(xoffset, 0, w-vsbExt, bottom));
+ if (showc || cornerWidget()) {
+ if ( ! frameContentsOnly )
+ setVBarGeometry( *d->vbar, xpos,
+ fw, vsbExt,
+ h-hsbExt-fw-fw );
+ else
+ setVBarGeometry( *d->vbar, xpos, 0,
+ vsbExt,
+ h-hsbExt );
+ }
+ else {
+ if ( ! frameContentsOnly )
+ setVBarGeometry( *d->vbar, xpos,
+ fw, vsbExt,
+ bottom-fw-fw );
+ else
+ setVBarGeometry( *d->vbar, xpos, 0,
+ vsbExt, bottom );
+ }
+ } else {
+ if ( ! frameContentsOnly )
+ changeFrameRect(TQRect(0, 0, w, h));
+ else
+ changeFrameRect(TQRect(0, 0, w, bottom));
+ clipper()->setGeometry( lmarg, tmarg,
+ w-lmarg-rmarg, bottom-tmarg-bmarg );
+ d->viewportResized( w-lmarg-rmarg, bottom-tmarg-bmarg );
+ }
+
+ TQWidget *corner = d->corner;
+ if ( !d->corner )
+ corner = d->defaultCorner;
+ if ( ! frameContentsOnly )
+ corner->setGeometry( xpos,
+ h-hsbExt-fw,
+ vsbExt,
+ hsbExt );
+ else
+ corner->setGeometry( xpos,
+ h-hsbExt,
+ vsbExt,
+ hsbExt );
+
+ d->signal_choke=sc;
+
+ if ( d->contentsX()+visibleWidth() > d->contentsWidth() ) {
+ int x;
+#if 0
+ if ( reverse )
+ x =TQMIN(0,d->contentsWidth()-visibleWidth());
+ else
+#endif
+ x =TQMAX(0,d->contentsWidth()-visibleWidth());
+ d->hbar->setValue(x);
+ // Do it even if it is recursive
+ moveContents( -x, -d->contentsY() );
+ }
+ if ( d->contentsY()+visibleHeight() > contentsHeight() ) {
+ int y=TQMAX(0,contentsHeight()-visibleHeight());
+ d->vbar->setValue(y);
+ // Do it even if it is recursive
+ moveContents( -d->contentsX(), -y );
+ }
+
+ // Finally, show the scroll bars
+ if ( showh && ( d->hbar->isHidden() || !d->hbar->isVisible() ) )
+ d->hbar->show();
+ if ( showv && ( d->vbar->isHidden() || !d->vbar->isVisible() ) )
+ d->vbar->show();
+
+ d->signal_choke=TRUE;
+ d->vbar->setValue( d->contentsY() );
+ d->hbar->setValue( d->contentsX() );
+ d->signal_choke=FALSE;
+
+ TQSize newVisibleSize( visibleWidth(), visibleHeight() );
+ if ( d->clipped_viewport && oldVisibleSize != newVisibleSize ) {
+ TQResizeEvent e( newVisibleSize, oldVisibleSize );
+ viewportResizeEvent( &e );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::show()
+{
+ if ( isVisible() )
+ return;
+ TQWidget::show();
+ updateScrollBars();
+ d->hideOrShowAll(this);
+}
+
+/*!
+ \reimp
+ */
+void TQScrollView::resize( int w, int h )
+{
+ TQWidget::resize( w, h );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::resize( const TQSize& s )
+{
+ resize( s.width(), s.height() );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::resizeEvent( TQResizeEvent* event )
+{
+ TQFrame::resizeEvent( event );
+
+#if 0
+ if ( TQApplication::reverseLayout() ) {
+ d->fake_scroll = TRUE;
+ scrollBy( -event->size().width() + event->oldSize().width(), 0 );
+ d->fake_scroll = FALSE;
+ }
+#endif
+
+ bool inresize = d->inresize;
+ d->inresize = TRUE;
+ updateScrollBars();
+ d->inresize = inresize;
+ d->scrollbar_timer.start( 0, TRUE );
+
+ d->hideOrShowAll(this);
+}
+
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::mousePressEvent( TQMouseEvent * e) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseReleaseEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseDoubleClickEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseMoveEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::wheelEvent( TQWheelEvent *e )
+{
+ TQWheelEvent ce( viewport()->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->delta(), e->state(), e->orientation());
+ viewportWheelEvent(&ce);
+ if ( !ce.isAccepted() ) {
+ if ( e->orientation() == Horizontal && horizontalScrollBar() && horizontalScrollBar()->isEnabled() )
+ TQApplication::sendEvent( horizontalScrollBar(), e);
+ else if (e->orientation() == Vertical && verticalScrollBar() && verticalScrollBar()->isEnabled() )
+ TQApplication::sendEvent( verticalScrollBar(), e);
+ } else {
+ e->accept();
+ }
+}
+#endif
+
+/*!
+ \reimp
+*/
+void TQScrollView::contextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( e->reason() != TQContextMenuEvent::Keyboard ) {
+ e->ignore();
+ return;
+ }
+
+ TQContextMenuEvent ce( e->reason(), viewport()->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->state() );
+ viewportContextMenuEvent( &ce );
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+TQScrollView::ScrollBarMode TQScrollView::vScrollBarMode() const
+{
+ return d->vMode;
+}
+
+
+/*!
+ \enum TQScrollView::ScrollBarMode
+
+ This enum type describes the various modes of TQScrollView's scroll
+ bars.
+
+ \value Auto TQScrollView shows a scroll bar when the content is
+ too large to fit and not otherwise. This is the default.
+
+ \value AlwaysOff TQScrollView never shows a scroll bar.
+
+ \value AlwaysOn TQScrollView always shows a scroll bar.
+
+ (The modes for the horizontal and vertical scroll bars are
+ independent.)
+*/
+
+
+/*!
+ \property TQScrollView::vScrollBarMode
+ \brief the mode for the vertical scroll bar
+
+ The default mode is \c TQScrollView::Auto.
+
+ \sa hScrollBarMode
+*/
+void TQScrollView::setVScrollBarMode( ScrollBarMode mode )
+{
+ if (d->vMode != mode) {
+ d->vMode = mode;
+ updateScrollBars();
+ }
+}
+
+
+/*!
+ \property TQScrollView::hScrollBarMode
+ \brief the mode for the horizontal scroll bar
+
+ The default mode is \c TQScrollView::Auto.
+
+ \sa vScrollBarMode
+*/
+TQScrollView::ScrollBarMode TQScrollView::hScrollBarMode() const
+{
+ return d->hMode;
+}
+
+void TQScrollView::setHScrollBarMode( ScrollBarMode mode )
+{
+ if (d->hMode != mode) {
+ d->hMode = mode;
+ updateScrollBars();
+ }
+}
+
+
+/*!
+ Returns the widget in the corner between the two scroll bars.
+
+ By default, no corner widget is present.
+*/
+TQWidget* TQScrollView::cornerWidget() const
+{
+ return d->corner;
+}
+
+/*!
+ Sets the widget in the \a corner between the two scroll bars.
+
+ You will probably also want to set at least one of the scroll bar
+ modes to \c AlwaysOn.
+
+ Passing 0 shows no widget in the corner.
+
+ Any previous \a corner widget is hidden.
+
+ You may call setCornerWidget() with the same widget at different
+ times.
+
+ All widgets set here will be deleted by the TQScrollView when it is
+ destroyed unless you separately reparent the widget after setting
+ some other corner widget (or 0).
+
+ Any \e newly set widget should have no current parent.
+
+ By default, no corner widget is present.
+
+ \sa setVScrollBarMode(), setHScrollBarMode()
+*/
+void TQScrollView::setCornerWidget(TQWidget* corner)
+{
+ TQWidget* oldcorner = d->corner;
+ if (oldcorner != corner) {
+ if (oldcorner) oldcorner->hide();
+ d->corner = corner;
+
+ if ( corner && corner->parentWidget() != this ) {
+ // #### No clean way to get current WFlags
+ corner->reparent( this, (((TQScrollView*)corner))->getWFlags(),
+ TQPoint(0,0), FALSE );
+ }
+
+ updateScrollBars();
+ if ( corner ) corner->show();
+ }
+}
+
+
+void TQScrollView::setResizePolicy( ResizePolicy r )
+{
+ d->policy = r;
+}
+
+/*!
+ \property TQScrollView::resizePolicy
+ \brief the resize policy
+
+ The default is \c Default.
+
+ \sa ResizePolicy
+*/
+TQScrollView::ResizePolicy TQScrollView::resizePolicy() const
+{
+ return d->policy;
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::setEnabled( bool enable )
+{
+ TQFrame::setEnabled( enable );
+}
+
+/*!
+ Removes the \a child widget from the scrolled area. Note that this
+ happens automatically if the \a child is deleted.
+*/
+void TQScrollView::removeChild(TQWidget* child)
+{
+ if ( !d || !child ) // First check in case we are destructing
+ return;
+
+ TQSVChildRec *r = d->rec(child);
+ if ( r ) d->deleteChildRec( r );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::removeChild(TQObject* child)
+{
+ TQFrame::removeChild(child);
+}
+
+/*!
+ Inserts the widget, \a child, into the scrolled area positioned at
+ (\a x, \a y). The position defaults to (0, 0). If the child is
+ already in the view, it is just moved.
+
+ You may want to call enableClipper(TRUE) if you add a large number
+ of widgets.
+*/
+void TQScrollView::addChild(TQWidget* child, int x, int y)
+{
+ if ( !child ) {
+#if defined(QT_CHECK_NULL)
+ tqWarning( "TQScrollView::addChild(): Cannot add null child" );
+#endif
+ return;
+ }
+ child->polish();
+ child->setBackgroundOrigin(WidgetOrigin);
+
+ if ( child->parentWidget() == viewport() ) {
+ // May already be there
+ TQSVChildRec *r = d->rec(child);
+ if (r) {
+ r->moveTo(this,x,y,d->clipped_viewport);
+ if ( d->policy > Manual ) {
+ d->autoResizeHint(this);
+ d->autoResize(this); // #### better to just deal with this one widget!
+ }
+ return;
+ }
+ }
+
+ if ( d->children.isEmpty() && d->policy != Manual ) {
+ if ( d->policy == Default )
+ setResizePolicy( AutoOne );
+ child->installEventFilter( this );
+ } else if ( d->policy == AutoOne ) {
+ child->removeEventFilter( this ); //#### ?????
+ setResizePolicy( Manual );
+ }
+ if ( child->parentWidget() != viewport() ) {
+ child->reparent( viewport(), 0, TQPoint(0,0), FALSE );
+ }
+ d->addChildRec(child,x,y)->hideOrShow(this, d->clipped_viewport);
+
+ if ( d->policy > Manual ) {
+ d->autoResizeHint(this);
+ d->autoResize(this); // #### better to just deal with this one widget!
+ }
+}
+
+/*!
+ Repositions the \a child widget to (\a x, \a y). This function is
+ the same as addChild().
+*/
+void TQScrollView::moveChild(TQWidget* child, int x, int y)
+{
+ addChild(child,x,y);
+}
+
+/*!
+ Returns the X position of the given \a child widget. Use this
+ rather than TQWidget::x() for widgets added to the view.
+
+ This function returns 0 if \a child has not been added to the view.
+*/
+int TQScrollView::childX(TQWidget* child)
+{
+ TQSVChildRec *r = d->rec(child);
+ return r ? r->x : 0;
+}
+
+/*!
+ Returns the Y position of the given \a child widget. Use this
+ rather than TQWidget::y() for widgets added to the view.
+
+ This function returns 0 if \a child has not been added to the view.
+*/
+int TQScrollView::childY(TQWidget* child)
+{
+ TQSVChildRec *r = d->rec(child);
+ return r ? r->y : 0;
+}
+
+/*! \fn bool TQScrollView::childIsVisible(TQWidget*)
+ \obsolete
+
+ Returns TRUE if \a child is visible. This is equivalent
+ to child->isVisible().
+*/
+
+/*! \fn void TQScrollView::showChild(TQWidget* child, bool y)
+ \obsolete
+
+ Sets the visibility of \a child. Equivalent to
+ TQWidget::show() or TQWidget::hide().
+*/
+
+/*!
+ This event filter ensures the scroll bars are updated when a
+ single contents widget is resized, shown, hidden or destroyed; it
+ passes mouse events to the TQScrollView. The event is in \a e and
+ the object is in \a obj.
+*/
+
+bool TQScrollView::eventFilter( TQObject *obj, TQEvent *e )
+{
+ if ( !d )
+ return FALSE; // we are destructing
+ if ( obj == d->viewport || obj == d->clipped_viewport ) {
+ switch ( e->type() ) {
+ /* Forward many events to viewport...() functions */
+ case TQEvent::Paint:
+ viewportPaintEvent( (TQPaintEvent*)e );
+ break;
+ case TQEvent::Resize:
+ if ( !d->clipped_viewport )
+ viewportResizeEvent( (TQResizeEvent *)e );
+ break;
+ case TQEvent::MouseButtonPress:
+ viewportMousePressEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseButtonRelease:
+ viewportMouseReleaseEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseButtonDblClick:
+ viewportMouseDoubleClickEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseMove:
+ viewportMouseMoveEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+#ifndef TQT_NO_DRAGANDDROP
+ case TQEvent::DragEnter:
+ viewportDragEnterEvent( (TQDragEnterEvent*)e );
+ break;
+ case TQEvent::DragMove: {
+ if ( d->drag_autoscroll ) {
+ TQPoint vp = ((TQDragMoveEvent*) e)->pos();
+ TQRect inside_margin( autoscroll_margin, autoscroll_margin,
+ visibleWidth() - autoscroll_margin * 2,
+ visibleHeight() - autoscroll_margin * 2 );
+ if ( !inside_margin.contains( vp ) ) {
+ startDragAutoScroll();
+ // Keep sending move events
+ ( (TQDragMoveEvent*)e )->accept( TQRect(0,0,0,0) );
+ }
+ }
+ viewportDragMoveEvent( (TQDragMoveEvent*)e );
+ } break;
+ case TQEvent::DragLeave:
+ stopDragAutoScroll();
+ viewportDragLeaveEvent( (TQDragLeaveEvent*)e );
+ break;
+ case TQEvent::Drop:
+ stopDragAutoScroll();
+ viewportDropEvent( (TQDropEvent*)e );
+ break;
+#endif // TQT_NO_DRAGANDDROP
+ case TQEvent::ContextMenu:
+ viewportContextMenuEvent( (TQContextMenuEvent*)e );
+ if ( ((TQContextMenuEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::ChildRemoved:
+ removeChild((TQWidget*)((TQChildEvent*)e)->child());
+ break;
+ case TQEvent::LayoutHint:
+ d->autoResizeHint(this);
+ break;
+ case TQEvent::WindowActivate:
+ case TQEvent::WindowDeactivate:
+ return TRUE;
+ default:
+ break;
+ }
+ } else if ( d && d->rec((TQWidget*)obj) ) { // must be a child
+ if ( e->type() == TQEvent::Resize )
+ d->autoResize(this);
+ else if ( e->type() == TQEvent::Move )
+ d->autoMove(this);
+ }
+ return TQFrame::eventFilter( obj, e ); // always continue with standard event processing
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mousePressEvent(): the press position in \a e is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsMousePressEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseReleaseEvent(): the release position in \a e is translated to be a
+ point on the contents.
+*/
+void TQScrollView::contentsMouseReleaseEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseDoubleClickEvent(): the click position in \a e is translated to be a
+ point on the contents.
+
+ The default implementation generates a normal mouse press event.
+*/
+void TQScrollView::contentsMouseDoubleClickEvent( TQMouseEvent* e )
+{
+ contentsMousePressEvent(e); // try mouse press event
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseMoveEvent(): the mouse position in \a e is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsMouseMoveEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragEnterEvent(): the drag position is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsDragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragMoveEvent(): the drag position is translated to be a point on
+ the contents.
+*/
+void TQScrollView::contentsDragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragLeaveEvent(): the drag position is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dropEvent(): the drop position is translated to be a point on the
+ contents.
+*/
+void TQScrollView::contentsDropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ wheelEvent() in \a{e}: the mouse position is translated to be a
+ point on the contents.
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::contentsWheelEvent( TQWheelEvent * e )
+{
+ e->ignore();
+}
+#endif
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ contextMenuEvent() in \a{e}: the mouse position is translated to
+ be a point on the contents.
+*/
+void TQScrollView::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This is a low-level painting routine that draws the viewport
+ contents. Reimplement this if drawContents() is too high-level
+ (for example, if you don't want to open a TQPainter on the
+ viewport). The paint event is passed in \a pe.
+*/
+void TQScrollView::viewportPaintEvent( TQPaintEvent* pe )
+{
+ TQWidget* vp = viewport();
+
+ TQPainter p(vp);
+ TQRect r = pe->rect();
+
+ if ( d->clipped_viewport ) {
+ TQRect rr(
+ -d->clipped_viewport->x(), -d->clipped_viewport->y(),
+ d->viewport->width(), d->viewport->height()
+ );
+ r &= rr;
+ if ( r.isValid() ) {
+ int ex = r.x() + d->clipped_viewport->x() + d->contentsX();
+ int ey = r.y() + d->clipped_viewport->y() + d->contentsY();
+ int ew = r.width();
+ int eh = r.height();
+ drawContentsOffset(&p,
+ d->contentsX()+d->clipped_viewport->x(),
+ d->contentsY()+d->clipped_viewport->y(),
+ ex, ey, ew, eh);
+ }
+ } else {
+ r &= d->viewport->rect();
+ int ex = r.x() + d->contentsX();
+ int ey = r.y() + d->contentsY();
+ int ew = r.width();
+ int eh = r.height();
+ drawContentsOffset(&p, d->contentsX(), d->contentsY(), ex, ey, ew, eh);
+ }
+}
+
+
+/*!
+ To provide simple processing of events on the contents, this
+ function receives all resize events sent to the viewport.
+
+ \sa TQWidget::resizeEvent()
+*/
+void TQScrollView::viewportResizeEvent( TQResizeEvent* )
+{
+}
+
+/*! \internal
+
+ To provide simple processing of events on the contents, this
+ function receives all mouse press events sent to the viewport,
+ translates the event and calls contentsMousePressEvent().
+
+ \sa contentsMousePressEvent(), TQWidget::mousePressEvent()
+*/
+void TQScrollView::viewportMousePressEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMousePressEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse release events sent to the viewport, translates
+ the event and calls contentsMouseReleaseEvent().
+
+ \sa TQWidget::mouseReleaseEvent()
+*/
+void TQScrollView::viewportMouseReleaseEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseReleaseEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse double click events sent to the viewport,
+ translates the event and calls contentsMouseDoubleClickEvent().
+
+ \sa TQWidget::mouseDoubleClickEvent()
+*/
+void TQScrollView::viewportMouseDoubleClickEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseDoubleClickEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse move events sent to the viewport, translates the
+ event and calls contentsMouseMoveEvent().
+
+ \sa TQWidget::mouseMoveEvent()
+*/
+void TQScrollView::viewportMouseMoveEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseMoveEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag enter events sent to the viewport, translates the
+ event and calls contentsDragEnterEvent().
+
+ \sa TQWidget::dragEnterEvent()
+*/
+void TQScrollView::viewportDragEnterEvent( TQDragEnterEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDragEnterEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag move events sent to the viewport, translates the
+ event and calls contentsDragMoveEvent().
+
+ \sa TQWidget::dragMoveEvent()
+*/
+void TQScrollView::viewportDragMoveEvent( TQDragMoveEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDragMoveEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag leave events sent to the viewport and calls
+ contentsDragLeaveEvent().
+
+ \sa TQWidget::dragLeaveEvent()
+*/
+void TQScrollView::viewportDragLeaveEvent( TQDragLeaveEvent* e )
+{
+ contentsDragLeaveEvent(e);
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drop events sent to the viewport, translates the event
+ and calls contentsDropEvent().
+
+ \sa TQWidget::dropEvent()
+*/
+void TQScrollView::viewportDropEvent( TQDropEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDropEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all wheel events sent to the viewport, translates the
+ event and calls contentsWheelEvent().
+
+ \sa TQWidget::wheelEvent()
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::viewportWheelEvent( TQWheelEvent* e )
+{
+ /*
+ Different than standard mouse events, because wheel events might
+ be sent to the focus widget if the widget-under-mouse doesn't want
+ the event itself.
+ */
+ TQWheelEvent ce( viewportToContents(e->pos()),
+ e->globalPos(), e->delta(), e->state(), e->orientation());
+ contentsWheelEvent(&ce);
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+#endif
+
+/*! \internal
+
+ To provide simple processing of events on the contents, this function
+ receives all context menu events sent to the viewport, translates the
+ event and calls contentsContextMenuEvent().
+*/
+void TQScrollView::viewportContextMenuEvent( TQContextMenuEvent *e )
+{
+ TQContextMenuEvent ce(e->reason(), viewportToContents(e->pos()), e->globalPos(), e->state() );
+ contentsContextMenuEvent( &ce );
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*!
+ Returns the component horizontal scroll bar. It is made available
+ to allow accelerators, autoscrolling, etc.
+
+ It should not be used for other purposes.
+
+ This function never returns 0.
+*/
+TQScrollBar* TQScrollView::horizontalScrollBar() const
+{
+ return d->hbar;
+}
+
+/*!
+ Returns the component vertical scroll bar. It is made available to
+ allow accelerators, autoscrolling, etc.
+
+ It should not be used for other purposes.
+
+ This function never returns 0.
+*/
+TQScrollBar* TQScrollView::verticalScrollBar() const {
+ return d->vbar;
+}
+
+
+/*!
+ Scrolls the content so that the point \a (x, y) is visible with at
+ least 50-pixel margins (if possible, otherwise centered).
+*/
+void TQScrollView::ensureVisible( int x, int y )
+{
+ ensureVisible(x, y, 50, 50);
+}
+
+/*!
+ \overload
+
+ Scrolls the content so that the point \a (x, y) is visible with at
+ least the \a xmargin and \a ymargin margins (if possible,
+ otherwise centered).
+*/
+void TQScrollView::ensureVisible( int x, int y, int xmargin, int ymargin )
+{
+ int pw=visibleWidth();
+ int ph=visibleHeight();
+
+ int cx=-d->contentsX();
+ int cy=-d->contentsY();
+ int cw=d->contentsWidth();
+ int ch=contentsHeight();
+
+ if ( pw < xmargin*2 )
+ xmargin=pw/2;
+ if ( ph < ymargin*2 )
+ ymargin=ph/2;
+
+ if ( cw <= pw ) {
+ xmargin=0;
+ cx=0;
+ }
+ if ( ch <= ph ) {
+ ymargin=0;
+ cy=0;
+ }
+
+ if ( x < -cx+xmargin )
+ cx = -x+xmargin;
+ else if ( x >= -cx+pw-xmargin )
+ cx = -x+pw-xmargin;
+
+ if ( y < -cy+ymargin )
+ cy = -y+ymargin;
+ else if ( y >= -cy+ph-ymargin )
+ cy = -y+ph-ymargin;
+
+ if ( cx > 0 )
+ cx=0;
+ else if ( cx < pw-cw && cw>pw )
+ cx=pw-cw;
+
+ if ( cy > 0 )
+ cy=0;
+ else if ( cy < ph-ch && ch>ph )
+ cy=ph-ch;
+
+ setContentsPos( -cx, -cy );
+}
+
+/*!
+ Scrolls the content so that the point \a (x, y) is in the top-left
+ corner.
+*/
+void TQScrollView::setContentsPos( int x, int y )
+{
+#if 0
+ // bounds checking...
+ if ( TQApplication::reverseLayout() )
+ if ( x > d->contentsWidth() - visibleWidth() ) x = d->contentsWidth() - visibleWidth();
+ else
+#endif
+ if ( x < 0 ) x = 0;
+ if ( y < 0 ) y = 0;
+ // Choke signal handling while we update BOTH sliders.
+ d->signal_choke=TRUE;
+ moveContents( -x, -y );
+ d->vbar->setValue( y );
+ d->hbar->setValue( x );
+ d->signal_choke=FALSE;
+}
+
+/*!
+ Scrolls the content by \a dx to the left and \a dy upwards.
+*/
+void TQScrollView::scrollBy( int dx, int dy )
+{
+ setContentsPos( TQMAX( d->contentsX()+dx, 0 ), TQMAX( d->contentsY()+dy, 0 ) );
+}
+
+/*!
+ Scrolls the content so that the point \a (x, y) is in the center
+ of visible area.
+*/
+void TQScrollView::center( int x, int y )
+{
+ ensureVisible( x, y, 32000, 32000 );
+}
+
+/*!
+ \overload
+
+ Scrolls the content so that the point \a (x, y) is visible with
+ the \a xmargin and \a ymargin margins (as fractions of visible
+ the area).
+
+ For example:
+ \list
+ \i Margin 0.0 allows (x, y) to be on the edge of the visible area.
+ \i Margin 0.5 ensures that (x, y) is in middle 50% of the visible area.
+ \i Margin 1.0 ensures that (x, y) is in the center of the the visible area.
+ \endlist
+*/
+void TQScrollView::center( int x, int y, float xmargin, float ymargin )
+{
+ int pw=visibleWidth();
+ int ph=visibleHeight();
+ ensureVisible( x, y, int( xmargin/2.0*pw+0.5 ), int( ymargin/2.0*ph+0.5 ) );
+}
+
+
+/*!
+ \fn void TQScrollView::contentsMoving(int x, int y)
+
+ This signal is emitted just before the contents are moved to
+ position \a (x, y).
+
+ \sa contentsX(), contentsY()
+*/
+
+/*!
+ Moves the contents by \a (x, y).
+*/
+void TQScrollView::moveContents(int x, int y)
+{
+ if ( -x+visibleWidth() > d->contentsWidth() )
+#if 0
+ if( TQApplication::reverseLayout() )
+ x=TQMAX(0,-d->contentsWidth()+visibleWidth());
+ else
+#endif
+ x=TQMIN(0,-d->contentsWidth()+visibleWidth());
+ if ( -y+visibleHeight() > contentsHeight() )
+ y=TQMIN(0,-contentsHeight()+visibleHeight());
+
+ int dx = x - d->vx;
+ int dy = y - d->vy;
+
+ if (!dx && !dy)
+ return; // Nothing to do
+
+ emit contentsMoving( -x, -y );
+
+ d->vx = x;
+ d->vy = y;
+
+ if ( d->clipped_viewport || d->static_bg ) {
+ // Cheap move (usually)
+ d->moveAllBy(dx,dy);
+ } else if ( /*dx && dy ||*/
+ ( TQABS(dy) * 5 > visibleHeight() * 4 ) ||
+ ( TQABS(dx) * 5 > visibleWidth() * 4 )
+ )
+ {
+ // Big move
+ if ( viewport()->isUpdatesEnabled() )
+ viewport()->update();
+ d->moveAllBy(dx,dy);
+ } else if ( !d->fake_scroll || d->contentsWidth() > visibleWidth() ) {
+ // Small move
+ clipper()->scroll(dx,dy);
+ }
+ d->hideOrShowAll(this, TRUE );
+}
+
+/*!
+ \property TQScrollView::contentsX
+ \brief the X coordinate of the contents that are at the left edge of
+ the viewport.
+*/
+int TQScrollView::contentsX() const
+{
+ return d->contentsX();
+}
+
+/*!
+ \property TQScrollView::contentsY
+ \brief the Y coordinate of the contents that are at the top edge of
+ the viewport.
+*/
+int TQScrollView::contentsY() const
+{
+ return d->contentsY();
+}
+
+/*!
+ \property TQScrollView::contentsWidth
+ \brief the width of the contents area
+*/
+int TQScrollView::contentsWidth() const
+{
+ return d->contentsWidth();
+}
+
+/*!
+ \property TQScrollView::contentsHeight
+ \brief the height of the contents area
+*/
+int TQScrollView::contentsHeight() const
+{
+ return d->vheight;
+}
+
+/*!
+ Sets the size of the contents area to \a w pixels wide and \a h
+ pixels high and updates the viewport accordingly.
+*/
+void TQScrollView::resizeContents( int w, int h )
+{
+ int ow = d->vwidth;
+ int oh = d->vheight;
+ d->vwidth = w;
+ d->vheight = h;
+
+ d->scrollbar_timer.start( 0, TRUE );
+
+ if ( d->children.isEmpty() && d->policy == Default )
+ setResizePolicy( Manual );
+
+ if ( ow > w ) {
+ // Swap
+ int t=w;
+ w=ow;
+ ow=t;
+ }
+ // Refresh area ow..w
+ if ( ow < visibleWidth() && w >= 0 ) {
+ if ( ow < 0 )
+ ow = 0;
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ clipper()->update( d->contentsX()+ow, 0, w-ow, visibleHeight() );
+ }
+
+ if ( oh > h ) {
+ // Swap
+ int t=h;
+ h=oh;
+ oh=t;
+ }
+ // Refresh area oh..h
+ if ( oh < visibleHeight() && h >= 0 ) {
+ if ( oh < 0 )
+ oh = 0;
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+ clipper()->update( 0, d->contentsY()+oh, visibleWidth(), h-oh);
+ }
+}
+
+/*!
+ Calls update() on a rectangle defined by \a x, \a y, \a w, \a h,
+ translated appropriately. If the rectangle is not visible, nothing
+ is repainted.
+
+ \sa repaintContents()
+*/
+void TQScrollView::updateContents( int x, int y, int w, int h )
+{
+ if ( testWState(WState_Visible|WState_BlockUpdates) != WState_Visible )
+ return;
+
+ TQWidget* vp = viewport();
+
+ // Translate
+ x -= d->contentsX();
+ y -= d->contentsY();
+
+ // Clip to TQCOORD space
+ if ( x < 0 ) {
+ w += x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ h += y;
+ y = 0;
+ }
+
+ if ( w < 0 || h < 0 )
+ return;
+ if ( x > visibleWidth() || y > visibleHeight() )
+ return;
+
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+
+ if ( d->clipped_viewport ) {
+ // Translate clipper() to viewport()
+ x -= d->clipped_viewport->x();
+ y -= d->clipped_viewport->y();
+ }
+
+ vp->update( x, y, w, h );
+}
+
+/*!
+ \overload
+
+ Updates the contents in rectangle \a r
+*/
+void TQScrollView::updateContents( const TQRect& r )
+{
+ updateContents(r.x(), r.y(), r.width(), r.height());
+}
+
+/*!
+ \overload
+*/
+void TQScrollView::updateContents()
+{
+ updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() );
+}
+
+/*!
+ \overload
+
+ Repaints the contents of rectangle \a r. If \a erase is TRUE the
+ background is cleared using the background color.
+*/
+void TQScrollView::repaintContents( const TQRect& r, bool erase )
+{
+ repaintContents(r.x(), r.y(), r.width(), r.height(), erase);
+}
+
+
+/*!
+ \overload
+
+ Repaints the contents. If \a erase is TRUE the background is
+ cleared using the background color.
+*/
+void TQScrollView::repaintContents( bool erase )
+{
+ repaintContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight(), erase );
+}
+
+
+/*!
+ Calls repaint() on a rectangle defined by \a x, \a y, \a w, \a h,
+ translated appropriately. If the rectangle is not visible, nothing
+ is repainted. If \a erase is TRUE the background is cleared using
+ the background color.
+
+ \sa updateContents()
+*/
+void TQScrollView::repaintContents( int x, int y, int w, int h, bool erase )
+{
+ if ( testWState(WState_Visible|WState_BlockUpdates) != WState_Visible )
+ return;
+
+ TQWidget* vp = viewport();
+
+ // Translate logical to clipper()
+ x -= d->contentsX();
+ y -= d->contentsY();
+
+ // Clip to TQCOORD space
+ if ( x < 0 ) {
+ w += x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ h += y;
+ y = 0;
+ }
+
+ if ( w < 0 || h < 0 )
+ return;
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+
+ if ( d->clipped_viewport ) {
+ // Translate clipper() to viewport()
+ x -= d->clipped_viewport->x();
+ y -= d->clipped_viewport->y();
+ }
+
+ vp->repaint( x, y, w, h, erase );
+}
+
+
+/*!
+ For backward-compatibility only. It is easier to use
+ drawContents(TQPainter*,int,int,int,int).
+
+ The default implementation translates the painter appropriately
+ and calls drawContents(TQPainter*,int,int,int,int). See
+ drawContents() for an explanation of the parameters \a p, \a
+ offsetx, \a offsety, \a clipx, \a clipy, \a clipw and \a cliph.
+*/
+void TQScrollView::drawContentsOffset(TQPainter* p, int offsetx, int offsety, int clipx, int clipy, int clipw, int cliph)
+{
+ p->translate(-offsetx,-offsety);
+ drawContents(p, clipx, clipy, clipw, cliph);
+}
+
+/*!
+ \fn void TQScrollView::drawContents(TQPainter* p, int clipx, int clipy, int clipw, int cliph)
+
+ Reimplement this function if you are viewing a drawing area rather
+ than a widget.
+
+ The function should draw the rectangle (\a clipx, \a clipy, \a
+ clipw, \a cliph) of the contents using painter \a p. The clip
+ rectangle is in the scrollview's coordinates.
+
+ For example:
+ \code
+ {
+ // Fill a 40000 by 50000 rectangle at (100000,150000)
+
+ // Calculate the coordinates...
+ int x1 = 100000, y1 = 150000;
+ int x2 = x1+40000-1, y2 = y1+50000-1;
+
+ // Clip the coordinates so X/Windows will not have problems...
+ if (x1 < clipx) x1=clipx;
+ if (y1 < clipy) y1=clipy;
+ if (x2 > clipx+clipw-1) x2=clipx+clipw-1;
+ if (y2 > clipy+cliph-1) y2=clipy+cliph-1;
+
+ // Paint using the small coordinates...
+ if ( x2 >= x1 && y2 >= y1 )
+ p->fillRect(x1, y1, x2-x1+1, y2-y1+1, red);
+ }
+ \endcode
+
+ The clip rectangle and translation of the painter \a p is already
+ set appropriately.
+*/
+void TQScrollView::drawContents(TQPainter*, int, int, int, int)
+{
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::frameChanged()
+{
+ // slight ugle-hack - the listview header needs readjusting when
+ // changing the frame
+ if (TQListView *lv = ::tqt_cast<TQListView *>(this))
+ lv->triggerUpdate();
+ TQFrame::frameChanged();
+ updateScrollBars();
+}
+
+
+/*!
+ Returns the viewport widget of the scrollview. This is the widget
+ containing the contents widget or which is the drawing area.
+*/
+TQWidget* TQScrollView::viewport() const
+{
+ if ( d->clipped_viewport )
+ return d->clipped_viewport;
+ return d->viewport;
+}
+
+/*!
+ Returns the clipper widget. Contents in the scrollview are
+ ultimately clipped to be inside the clipper widget.
+
+ You should not need to use this function.
+
+ \sa visibleWidth(), visibleHeight()
+*/
+TQWidget* TQScrollView::clipper() const
+{
+ return d->viewport;
+}
+
+/*!
+ \property TQScrollView::visibleWidth
+ \brief the horizontal amount of the content that is visible
+*/
+int TQScrollView::visibleWidth() const
+{
+ return clipper()->width();
+}
+
+/*!
+ \property TQScrollView::visibleHeight
+ \brief the vertical amount of the content that is visible
+*/
+int TQScrollView::visibleHeight() const
+{
+ return clipper()->height();
+}
+
+
+void TQScrollView::changeFrameRect(const TQRect& r)
+{
+ TQRect oldr = frameRect();
+ if (oldr != r) {
+ TQRect cr = contentsRect();
+ TQRegion fr( frameRect() );
+ fr = fr.subtract( contentsRect() );
+ setFrameRect( r );
+ if ( isVisible() ) {
+ cr = cr.intersect( contentsRect() );
+ fr = fr.unite( frameRect() );
+ fr = fr.subtract( cr );
+ if ( !fr.isEmpty() )
+ TQApplication::postEvent( this, new TQPaintEvent( fr, FALSE ) );
+ }
+ }
+}
+
+
+/*!
+ Sets the margins around the scrolling area to \a left, \a top, \a
+ right and \a bottom. This is useful for applications such as
+ spreadsheets with "locked" rows and columns. The marginal space is
+ \e inside the frameRect() and is left blank; reimplement
+ drawFrame() or put widgets in the unused area.
+
+ By default all margins are zero.
+
+ \sa frameChanged()
+*/
+void TQScrollView::setMargins(int left, int top, int right, int bottom)
+{
+ if ( left == d->l_marg &&
+ top == d->t_marg &&
+ right == d->r_marg &&
+ bottom == d->b_marg )
+ return;
+
+ d->l_marg = left;
+ d->t_marg = top;
+ d->r_marg = right;
+ d->b_marg = bottom;
+ updateScrollBars();
+}
+
+
+/*!
+ Returns the left margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::leftMargin() const
+{
+ return d->l_marg;
+}
+
+
+/*!
+ Returns the top margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::topMargin() const
+{
+ return d->t_marg;
+}
+
+
+/*!
+ Returns the right margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::rightMargin() const
+{
+ return d->r_marg;
+}
+
+
+/*!
+ Returns the bottom margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::bottomMargin() const
+{
+ return d->b_marg;
+}
+
+/*!
+ \reimp
+*/
+bool TQScrollView::focusNextPrevChild( bool next )
+{
+ // Makes sure that the new focus widget is on-screen, if
+ // necessary by scrolling the scroll view.
+
+ // first set things up for the scan
+ TQFocusData *f = focusData();
+ TQWidget *startingPoint = f->home();
+ TQWidget *candidate = 0;
+ TQWidget *w = next ? f->next() : f->prev();
+ TQSVChildRec *r;
+ extern bool tqt_tab_all_widgets;
+ uint focus_flag = tqt_tab_all_widgets ? TabFocus : StrongFocus;
+
+ // then scan for a possible focus widget candidate
+ while( !candidate && w != startingPoint ) {
+ if ( w != startingPoint &&
+ (w->focusPolicy() & focus_flag) == focus_flag
+ && w->isEnabled() &&!w->focusProxy() && w->isVisible() )
+ candidate = w;
+ w = next ? f->next() : f->prev();
+ }
+
+ // if we could not find one, maybe super or parentWidget() can?
+ if ( !candidate )
+ return TQFrame::focusNextPrevChild( next );
+
+ // we've found one.
+ r = d->ancestorRec( candidate );
+ if ( r && ( r->child == candidate ||
+ candidate->isVisibleTo( r->child ) ) ) {
+ TQPoint cp = r->child->mapToGlobal(TQPoint(0,0));
+ TQPoint cr = candidate->mapToGlobal(TQPoint(0,0)) - cp;
+ ensureVisible( r->x+cr.x()+candidate->width()/2,
+ r->y+cr.y()+candidate->height()/2,
+ candidate->width()/2,
+ candidate->height()/2 );
+ }
+
+ candidate->setFocus();
+ return TRUE;
+}
+
+
+
+/*!
+ When a large numbers of child widgets are in a scrollview,
+ especially if they are close together, the scrolling performance
+ can suffer greatly. If \a y is TRUE the scrollview will use an
+ extra widget to group child widgets.
+
+ Note that you may only call enableClipper() prior to adding
+ widgets.
+
+ For a full discussion, see this class's \link #enableclipper
+ detailed description\endlink.
+*/
+void TQScrollView::enableClipper(bool y)
+{
+ if ( !d->clipped_viewport == !y )
+ return;
+ if ( d->children.count() )
+ tqFatal("May only call TQScrollView::enableClipper() before adding widgets");
+ if ( y ) {
+ d->clipped_viewport = new TQClipperWidget(clipper(), "qt_clipped_viewport", d->flags);
+ d->clipped_viewport->setGeometry(-coord_limit/2,-coord_limit/2,
+ coord_limit,coord_limit);
+ d->clipped_viewport->setBackgroundMode( d->viewport->backgroundMode() );
+ d->viewport->setBackgroundMode(NoBackground); // no exposures for this
+ d->viewport->removeEventFilter( this );
+ d->clipped_viewport->installEventFilter( this );
+ d->clipped_viewport->show();
+ } else {
+ delete d->clipped_viewport;
+ d->clipped_viewport = 0;
+ }
+}
+
+/*!
+ Sets the scrollview to have a static background if \a y is TRUE,
+ or a scrolling background if \a y is FALSE. By default, the
+ background is scrolling.
+
+ Be aware that this mode is quite slow, as a full repaint of the
+ visible area has to be triggered on every contents move.
+
+ \sa hasStaticBackground()
+*/
+void TQScrollView::setStaticBackground(bool y)
+{
+ d->static_bg = y;
+}
+
+/*!
+ Returns TRUE if TQScrollView uses a static background; otherwise
+ returns FALSE.
+
+ \sa setStaticBackground()
+*/
+bool TQScrollView::hasStaticBackground() const
+{
+ return d->static_bg;
+}
+
+/*!
+ \overload
+
+ Returns the point \a p translated to a point on the viewport()
+ widget.
+*/
+TQPoint TQScrollView::contentsToViewport( const TQPoint& p ) const
+{
+ if ( d->clipped_viewport ) {
+ return TQPoint( p.x() - d->contentsX() - d->clipped_viewport->x(),
+ p.y() - d->contentsY() - d->clipped_viewport->y() );
+ } else {
+ return TQPoint( p.x() - d->contentsX(),
+ p.y() - d->contentsY() );
+ }
+}
+
+/*!
+ \overload
+
+ Returns the point on the viewport \a vp translated to a point in
+ the contents.
+*/
+TQPoint TQScrollView::viewportToContents( const TQPoint& vp ) const
+{
+ if ( d->clipped_viewport ) {
+ return TQPoint( vp.x() + d->contentsX() + d->clipped_viewport->x(),
+ vp.y() + d->contentsY() + d->clipped_viewport->y() );
+ } else {
+ return TQPoint( vp.x() + d->contentsX(),
+ vp.y() + d->contentsY() );
+ }
+}
+
+
+/*!
+ Translates a point (\a x, \a y) in the contents to a point (\a vx,
+ \a vy) on the viewport() widget.
+*/
+void TQScrollView::contentsToViewport( int x, int y, int& vx, int& vy ) const
+{
+ const TQPoint v = contentsToViewport(TQPoint(x,y));
+ vx = v.x();
+ vy = v.y();
+}
+
+/*!
+ Translates a point (\a vx, \a vy) on the viewport() widget to a
+ point (\a x, \a y) in the contents.
+*/
+void TQScrollView::viewportToContents( int vx, int vy, int& x, int& y ) const
+{
+ const TQPoint c = viewportToContents(TQPoint(vx,vy));
+ x = c.x();
+ y = c.y();
+}
+
+/*!
+ \reimp
+*/
+TQSize TQScrollView::sizeHint() const
+{
+ if ( d->use_cached_size_hint && d->cachedSizeHint.isValid() )
+ return d->cachedSizeHint;
+
+ constPolish();
+ int f = 2 * frameWidth();
+ int h = fontMetrics().height();
+ TQSize sz( f, f );
+ if ( d->policy > Manual ) {
+ TQSVChildRec *r = d->children.first();
+ if ( r ) {
+ TQSize cs = r->child->sizeHint();
+ if ( cs.isValid() )
+ sz += cs.boundedTo( r->child->maximumSize() );
+ else
+ sz += r->child->size();
+ }
+ } else {
+ sz += TQSize( d->contentsWidth(), contentsHeight() );
+ }
+ if (d->vMode == AlwaysOn)
+ sz.setWidth(sz.width() + d->vbar->sizeHint().width());
+ if (d->hMode == AlwaysOn)
+ sz.setHeight(sz.height() + d->hbar->sizeHint().height());
+ return sz.expandedTo( TQSize(12 * h, 8 * h) )
+ .boundedTo( TQSize(36 * h, 24 * h) );
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQScrollView::minimumSizeHint() const
+{
+ int h = fontMetrics().height();
+ if ( h < 10 )
+ h = 10;
+ int f = 2 * frameWidth();
+ return TQSize( (6 * h) + f, (4 * h) + f );
+}
+
+
+/*!
+ \reimp
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQScrollView::drawContents( TQPainter * )
+{
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ \internal
+*/
+void TQScrollView::startDragAutoScroll()
+{
+ if ( !d->autoscroll_timer.isActive() ) {
+ d->autoscroll_time = initialScrollTime;
+ d->autoscroll_accel = initialScrollAccel;
+ d->autoscroll_timer.start( d->autoscroll_time );
+ }
+}
+
+
+/*!
+ \internal
+*/
+void TQScrollView::stopDragAutoScroll()
+{
+ d->autoscroll_timer.stop();
+}
+
+
+/*!
+ \internal
+*/
+void TQScrollView::doDragAutoScroll()
+{
+ TQPoint p = d->viewport->mapFromGlobal( TQCursor::pos() );
+
+ if ( d->autoscroll_accel-- <= 0 && d->autoscroll_time ) {
+ d->autoscroll_accel = initialScrollAccel;
+ d->autoscroll_time--;
+ d->autoscroll_timer.start( d->autoscroll_time );
+ }
+ int l = TQMAX( 1, ( initialScrollTime- d->autoscroll_time ) );
+
+ int dx = 0, dy = 0;
+ if ( p.y() < autoscroll_margin ) {
+ dy = -l;
+ } else if ( p.y() > visibleHeight() - autoscroll_margin ) {
+ dy = +l;
+ }
+ if ( p.x() < autoscroll_margin ) {
+ dx = -l;
+ } else if ( p.x() > visibleWidth() - autoscroll_margin ) {
+ dx = +l;
+ }
+ if ( dx || dy ) {
+ scrollBy(dx,dy);
+ } else {
+ stopDragAutoScroll();
+ }
+}
+
+
+/*!
+ \property TQScrollView::dragAutoScroll
+ \brief whether autoscrolling in drag move events is enabled
+
+ If this property is set to TRUE (the default), the TQScrollView
+ automatically scrolls the contents in drag move events if the user
+ moves the cursor close to a border of the view. Of course this
+ works only if the viewport accepts drops. Specifying FALSE
+ disables this autoscroll feature.
+
+ \warning Enabling this property might not be enough to
+ effectively turn on autoscrolling. If you put a custom widget in
+ the TQScrollView, you might need to call TQDragEvent::ignore() on
+ the event in the dragEnterEvent() and dragMoveEvent()
+ reimplementations.
+*/
+
+void TQScrollView::setDragAutoScroll( bool b )
+{
+ d->drag_autoscroll = b;
+}
+
+bool TQScrollView::dragAutoScroll() const
+{
+ return d->drag_autoscroll;
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!\internal
+ */
+void TQScrollView::setCachedSizeHint( const TQSize &sh ) const
+{
+ if ( isVisible() && !d->cachedSizeHint.isValid() )
+ d->cachedSizeHint = sh;
+}
+
+/*!\internal
+ */
+void TQScrollView::disableSizeHintCaching()
+{
+ d->use_cached_size_hint = FALSE;
+}
+
+/*!\internal
+ */
+TQSize TQScrollView::cachedSizeHint() const
+{
+ return d->use_cached_size_hint ? d->cachedSizeHint : TQSize();
+}
+
+#endif // TQT_NO_SCROLLVIEW