|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2001-2002 Matthias Kretz <kretz@kde.org>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License version 2
|
|
|
|
as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
// $Id$
|
|
|
|
|
|
|
|
#ifndef _KIMAGECANVAS_H
|
|
|
|
#define _KIMAGECANVAS_H
|
|
|
|
|
|
|
|
#include "kimageviewer/canvas.h"
|
|
|
|
|
|
|
|
#include <tqscrollview.h>
|
|
|
|
#include <tqwmatrix.h>
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqrect.h>
|
|
|
|
|
|
|
|
#include <kdemacros.h>
|
|
|
|
|
|
|
|
class KImageHolder;
|
|
|
|
class TQColor;
|
|
|
|
class TQImage;
|
|
|
|
class KPixmap;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @short KViewCanvas
|
|
|
|
* @author Matthias Kretz <kretz@kde.org>
|
|
|
|
* @version $Id$
|
|
|
|
*/
|
|
|
|
class KDE_EXPORT KImageCanvas : public TQScrollView, public KImageViewer::Canvas
|
|
|
|
{
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* KImageCanvas Constructor
|
|
|
|
*/
|
|
|
|
KImageCanvas( TQWidget * parent, const char * name, const TQStringList & args );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* KImageCanvas Destructor
|
|
|
|
*/
|
|
|
|
virtual ~KImageCanvas();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set the background color of the canvas
|
|
|
|
*/
|
|
|
|
void setBgColor( const TQColor & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the current background color
|
|
|
|
*/
|
|
|
|
const TQColor & bgColor() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the depth of the contained image
|
|
|
|
*/
|
|
|
|
int imageDepth() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the size of the unzoomed image
|
|
|
|
*/
|
|
|
|
TQSize imageSize() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the size of the zoomed (current) image
|
|
|
|
*/
|
|
|
|
TQSize currentSize() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the zoom factor
|
|
|
|
*/
|
|
|
|
double zoom() const { return m_zoom; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns the current (unzoomed) image
|
|
|
|
*/
|
|
|
|
const TQImage * image() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Scrolls the content so that the point (x, y) is in the top-left corner.
|
|
|
|
*/
|
|
|
|
void setXYOffset( int x, int y ) { setContentsPos( x, y ); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the leftmost visible X coordinate of the image.
|
|
|
|
*/
|
|
|
|
int xOffset() const { return contentsX(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the topmost visible Y coordinate of the image.
|
|
|
|
*/
|
|
|
|
int yOffset() const { return contentsY(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether to use fast or smooth scaling
|
|
|
|
*/
|
|
|
|
bool fastScale() const { return m_fastscale; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return whether the image should always be centered.
|
|
|
|
*/
|
|
|
|
bool centered() const { return m_bCentered; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the selected rectangle
|
|
|
|
*/
|
|
|
|
TQRect selection() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether the aspect ratio of the image is kept
|
|
|
|
*/
|
|
|
|
bool keepAspectRatio() const { return m_keepaspectratio; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the number of available blend effects
|
|
|
|
*/
|
|
|
|
unsigned int numOfBlendEffects() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the description of the blend effect
|
|
|
|
*/
|
|
|
|
TQString blendEffectDescription( unsigned int ) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the current maximum image size
|
|
|
|
*/
|
|
|
|
const TQSize & maximumImageSize() const { return m_maxsize; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the current minimum image size
|
|
|
|
*/
|
|
|
|
const TQSize & minimumImageSize() const { return m_minsize; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return a pointer to the TQWidget interface of this object
|
|
|
|
*/
|
|
|
|
TQWidget * widget() { return static_cast<TQWidget *>( this ); }
|
|
|
|
|
|
|
|
bool eventFilter( TQObject *, TQEvent * );
|
|
|
|
|
|
|
|
signals:
|
|
|
|
/**
|
|
|
|
* a mouse button was pressed and a context menu should be openend
|
|
|
|
*/
|
|
|
|
void contextPress( const TQPoint& );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the size of the image has changed (a new image was loaded, or the
|
|
|
|
* image was zoomed or cropped)
|
|
|
|
*
|
|
|
|
* it passes the new size of the image
|
|
|
|
*/
|
|
|
|
void imageSizeChanged( const TQSize & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The zoom of the image has changed.
|
|
|
|
*/
|
|
|
|
void zoomChanged( double zoom );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The selection has changed. Connect to this signal if you want to
|
|
|
|
* do something with a selection of the image (e.g. crop).
|
|
|
|
*/
|
|
|
|
void selectionChanged( const TQRect & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Emitted when an image is finished being shown. If a blend effect is being used
|
|
|
|
* the signal is emitted when the effect is finished.
|
|
|
|
*/
|
|
|
|
void showingImageDone();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This signal is emitted whenever the canvas changes between image/no-image. For
|
|
|
|
* example, if someone calls @ref clear() hasImage( false ) is emitted if an image
|
|
|
|
* was shown before.
|
|
|
|
*/
|
|
|
|
void hasImage( bool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Some methods of the canvas not only change the way the image is shown (e.g. zoom)
|
|
|
|
* but also change the image itself (e.g. rotation) - @ref image() returns something
|
|
|
|
* different. If such a change happens this signal is emitted.
|
|
|
|
* It is not emitted when a new image is set with the @ref setImage() methods.
|
|
|
|
*/
|
|
|
|
void imageChanged();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The current mouse cursor position on the image.
|
|
|
|
*/
|
|
|
|
void cursorPos( const TQPoint & );
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
/**
|
|
|
|
* Set if the image should always be centered if the canvas is
|
|
|
|
* bigger than the image.
|
|
|
|
*/
|
|
|
|
void setCentered( bool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* give the canvas a new image to show. The zoom level is kept.
|
|
|
|
*/
|
|
|
|
void setImage( const TQImage & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Give the canvas a new image to show.
|
|
|
|
*
|
|
|
|
* You have to pass the size the image should have when it appears
|
|
|
|
* on screen.
|
|
|
|
*/
|
|
|
|
void setImage( const TQImage &, const TQSize & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set the zoom to be used when showing the image
|
|
|
|
*/
|
|
|
|
void setZoom( double );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fit the image into the requested width and height.
|
|
|
|
*/
|
|
|
|
void boundImageTo( const TQSize & size );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the maximum size of the image. If this is set the image will
|
|
|
|
* never exceed this size.
|
|
|
|
*
|
|
|
|
* If you set this to 0x0 the image size may be as big as possible
|
|
|
|
*/
|
|
|
|
void setMaximumImageSize( const TQSize & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the minimum size of the image. If this is set the image will
|
|
|
|
* never be smaller than this size.
|
|
|
|
*
|
|
|
|
* If you set this to 0x0 the image size can be as small as possible
|
|
|
|
*/
|
|
|
|
void setMinimumImageSize( const TQSize & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resize the image to the given size. It will keep the aspect ratio
|
|
|
|
* as long as keepAspectRatio is true (default). The image will be as
|
|
|
|
* large as possible within the given constraints.
|
|
|
|
*/
|
|
|
|
void resizeImage( const TQSize & );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hides the scrollbars of the canvas. It's still possible to scroll
|
|
|
|
* by moving the image with the mouse.
|
|
|
|
*/
|
|
|
|
void hideScrollbars( bool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Changes the zoom behaviour: Normally the aspect ratio of the image
|
|
|
|
* won't change, but if you want to allow it you may do.
|
|
|
|
*/
|
|
|
|
void setKeepAspectRatio( bool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the canvas supports different methods for scaling you may
|
|
|
|
* switch between fast and smooth scaling.
|
|
|
|
*
|
|
|
|
* It defaults to smooth scaling.
|
|
|
|
*/
|
|
|
|
void setFastScale( bool );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clears the canvas (no image loaded)
|
|
|
|
*/
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* flip the image horizontally
|
|
|
|
*/
|
|
|
|
void flipHorizontal( bool change = false );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* flip the image vertically
|
|
|
|
*/
|
|
|
|
void flipVertical( bool change = false );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* rotate the image a degrees counterclockwise
|
|
|
|
*/
|
|
|
|
void rotate( double a, bool change = false );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void checkBounds( TQSize & newsize );
|
|
|
|
void zoomFromSize( const TQSize & );
|
|
|
|
void sizeFromZoom( double );
|
|
|
|
void updateImage();
|
|
|
|
|
|
|
|
void mouseMoveEvent( TQMouseEvent * );
|
|
|
|
void resizeEvent( TQResizeEvent * );
|
|
|
|
void contentsMousePressEvent( TQMouseEvent * );
|
|
|
|
void contentsWheelEvent( TQWheelEvent * );
|
|
|
|
void keyPressEvent( TQKeyEvent * );
|
|
|
|
void timerEvent( TQTimerEvent * );
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void slotUpdateImage();
|
|
|
|
void hideCursor();
|
|
|
|
void slotImageChanged();
|
|
|
|
void loadSettings();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void selected( const TQRect & ); // map rect to unzoomed rect
|
|
|
|
void mapCursorPos( const TQPoint & );
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum BlendEffect {
|
|
|
|
NoBlending = 0,
|
|
|
|
WipeFromLeft = 1,
|
|
|
|
WipeFromRight = 2,
|
|
|
|
WipeFromTop = 3,
|
|
|
|
WipeFromBottom = 4,
|
|
|
|
AlphaBlend = 5
|
|
|
|
};
|
|
|
|
const KPixmap pixmap();
|
|
|
|
void sizeChanged();
|
|
|
|
void matrixChanged();
|
|
|
|
void center();
|
|
|
|
void finishNewClient();
|
|
|
|
KImageHolder * createNewClient();
|
|
|
|
|
|
|
|
KImageHolder * m_client;
|
|
|
|
KImageHolder * m_oldClient;
|
|
|
|
TQImage * m_image; //unzoomed copy of the current image
|
|
|
|
TQImage * m_imageTransformed; //xForm( m_matrix ) copy of the current image
|
|
|
|
KPixmap * m_pixmap; //copy of the current pixmap (if ( m_fastscale ) it's unzoomed else it's m_imageTransformed.smoothScale()d)
|
|
|
|
|
|
|
|
TQTimer * m_pTimer; // timer for single shot to hide the cursor
|
|
|
|
TQCursor m_cursor; // the cursor show in the canvas (for auto-hiding)
|
|
|
|
|
|
|
|
TQWMatrix m_matrix; // the current transformation matrix
|
|
|
|
TQSize m_maxsize, m_minsize;
|
|
|
|
TQSize m_currentsize;
|
|
|
|
|
|
|
|
double m_zoom;
|
|
|
|
bool m_fastscale;
|
|
|
|
bool m_keepaspectratio;
|
|
|
|
bool m_bImageChanged;
|
|
|
|
bool m_bSizeChanged;
|
|
|
|
bool m_bMatrixChanged;
|
|
|
|
bool m_bNeedNewPixmap;
|
|
|
|
bool m_bCentered;
|
|
|
|
bool m_bImageUpdateScheduled;
|
|
|
|
bool m_bNewImage;
|
|
|
|
int m_iBlendTimerId;
|
|
|
|
|
|
|
|
TQRect m_selection; //unzoomed selection rect
|
|
|
|
};
|
|
|
|
#endif // _KIMAGECANVAS_H
|