You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ksquirrel/ksquirrel/sq_glwidget.h

621 lines
17 KiB

/***************************************************************************
sq_glwidget.h - description
-------------------
begin : Mon Mar 15 2004
copyright : (C) 2004 by Baryshev Dmitry
email : ksquirrel.iv@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef SQ_GLWIDGET_H
#define SQ_GLWIDGET_H
#include <tqimage.h>
#include <tqrect.h>
#include <tqpair.h>
#include <tqdatetime.h>
#include <kurl.h>
#include <vector>
#include "sq_glparts.h"
#ifdef KSQUIRREL_PART
#include "sq_glview.h"
#endif
class SQ_GLSelectionPainter;
struct SQ_ImageFilterOptions;
struct SQ_ImageBCGOptions;
struct RGBA;
// parameters in GL matrix
#define MATRIX_C1 tab->matrix[0]
#define MATRIX_S1 tab->matrix[1]
#define MATRIX_X tab->matrix[3]
#define MATRIX_S2 tab->matrix[4]
#define MATRIX_C2 tab->matrix[5]
#define MATRIX_Y tab->matrix[7]
#define MATRIX_Z tab->matrix[11]
class TDEAction;
class TDEActionCollection;
class TDEToggleAction;
class TDEPopupMenu;
class TDERadioAction;
class KTempFile;
namespace TDEIO { class Job; }
class TQTimer;
class TQPopupMenu;
class TQSlider;
class TQLabel;
class SQ_ToolButtonPopup;
class SQ_ToolButton;
class SQ_ToolBar;
/* *************************************************************** */
/*
* SQ_GLWidget represents a widget, which loads, shows and manipulates
* an image.
*
* It contains complex decoding method. Since OpenGL can show textures
* only with dimensions of power of 2 (32x62, 512, 256 etc.), we should divide
* decoded image into quads and only then generate textures.
* It means, that the image you see consists of several parts:
*
* |----------------------------------
* | | |
* | tex N1 | tex N2 |
* | | |
* ----------------------------------- <= Entire image
* | | |
* | tex N3 | tex N4 |
* | | |
* -----------------------------------
*
*
* The main class member is 'parts'. It's an array of decoded images
* and appropriate memory buffers and textures. Here comes an explanation:
* [ use monotype fonts :) ]
*
* textures & coordinates Part
* +-----------------------------------+ ##################### ##################
* | parts[2] | # # #===> # #
* | +-------------------------------------+ # # # # texture id #
* | | parts[1] | |======> ##################### # texture coords #
* | | +-------------------------------------+ | # # # # ... #
* | | | m_parts parts[0] | | # # # ##################
* | | | ##### | | #####################
* | | | # # | |
* | | | # #===============================|
* | | | # # |
* | | | ##### |
* | | | | memory buffers
* | | | m32 | ###############################
* | | | ##### | #RGBA.#.....#.....#.....#.....#
* | | | # # | #RGBA.#.....#.....#.....#.....#
* | | | # #==================================> ###############################
* +-| | # # | #RGBA.#.....#.....#.....#.....#
* +-| ##### | #RGBA.#.....#.....#.....#.....#
* +-------------------------------------+ ###############################
* \ /
* \ /
* parts
*
*
******************************************************************************
*
*/
class SQ_GLWidget : public TQGLWidget
{
TQ_OBJECT
public:
SQ_GLWidget(TQWidget *parent = 0, const char *name = 0);
~SQ_GLWidget();
void setDownloadPercents(int);
void removeNonCurrentTabs(int);
void setExpectedURL(const KURL &u);
TQString originalURL() const;
/*
* Start decoding given image. We can call it from anywhere.
*/
void startDecoding(const TQString &file);
void startDecoding(const KURL &url);
void zoom(GLfloat);
/*
* Set zoom, move and rotate factors from config.
*/
void updateFactors();
/*
* Set clear color for context.
*/
void setClearColor();
void setOriginalURL(const KURL &);
/*
* Get zoom value, e.g. 1.5, 2.2 ...
*/
GLfloat getZoom() const;
/*
* Get zoom value in percents, e.g. 150, 220 ...
*/
GLfloat getZoomPercents() const;
TDEActionCollection* actionCollection() const;
/*
* Are we in fullscreen state ?
*/
bool fullscreen() const;
/*
* Toggle fullscreen state.
*/
void toggleFullScreen();
/*
* Direct call to updateGL().
*/
void updateGLA() { updateGL(); }
/*
* Type of zoom: fit width, fit height...
*/
int zoomType();
/*
* Filter is GL_LINEAR ?
*/
bool isnice();
/*
* Direct call to glInit();
*/
void glInitA() { TQGLWidget::glInit(); }
/*
* Start animation, if loaded image is animated.
*/
void startAnimation();
/*
* Stop animation, if loaded image is animated.
*/
void stopAnimation();
/*
* Is animation stopped by user ?
*/
bool manualBlocked();
/*
* Change statusbar info according with
* current matrix (it shows current zoom & angle values).
*/
void matrixChanged();
/*
* Check or uncheck 'Slideshow' button in toolbar.
*/
void updateSlideShowButton(bool toggled);
void closeAllTabsFull();
static SQ_GLWidget* window() { return m_instance; }
protected:
/*
* Next three methods should be reimplemented in
* every TQGLWidget's subclass.
*/
void initializeGL();
void paintGL();
void resizeGL(int,int);
/*
* Mouse wheel event. Let's load next/previous image, or
* zoom in/zoom out (depends on settings).
*/
void wheelEvent(TQWheelEvent *);
/*
* Palette changed. Let's update tickmarks and background color.
*/
void paletteChange(const TQPalette &oldPalette);
/*
* Accept drag-and-drop events. We can drop some images
* on this widget, SQ_GLWidget will try to decode first file.
*
* TODO: find first supported image and decode it ?
*/
void dragEnterEvent(TQDragEnterEvent *);
void dropEvent(TQDropEvent *);
/*
* Mouse events.
*/
void mousePressEvent(TQMouseEvent *);
void mouseReleaseEvent(TQMouseEvent *);
void mouseMoveEvent(TQMouseEvent *);
private:
void copyURL();
TQImage generatePreview();
bool calcSelection();
void changeSlider(GLfloat z = -1.0);
void hackMatrix();
void enableActions(bool U);
void initAccelsAndMenu();
void crop();
void bcg();
void filter();
void editUpdate();
/*
* Save current image page to clipboard
*/
void toClipboard();
/*
* Save current image page to file
*/
void saveAs();
void enableSettingsButton(bool enab);
/*
* Remove currently loaded textures and memory buffers.
*/
void removeCurrentParts();
void removeCurrentTabs();
void closeAllTabs();
/*
* Since 0.6.0-final KSquirrel doesn't show error messages,
* if the image is broken or not supported. It uses "broken" image
* instead. This method does all needed init.
*/
void initBrokenImage();
/*
* Force using broken image + update context.
* Show appropriate error message in statusbar.
*/
void useBrokenImage(const int err_index);
/*
* Update filter. If 'nice' is true, use GL_LINEAR
* and GL_NEAREST otherwise.
*/
void updateFilter(bool nice);
/*
* Cleanup method.
*/
void decodeFailedOn0(const int err_code);
/*
* Create TDEActions.
*/
void createActions();
/*
* Create toolbars.
*/
void createToolbar();
/*
* Fill a w x h region with texture. Generate texture if needed.
*/
void draw_background(void *bits, unsigned int *tex, int dim, GLfloat w, GLfloat h, bool &bind, bool deleteOld);
void setupBits(Parts *p, RGBA *buffer, int y, int x);
/*
* Jump to first or last image in animated sequence.
*/
void jumpToImage(bool);
/*
* Next image in animated sequence. Called by user (with F3).
*/
void nextImage();
/*
* Previous image in animated sequence. Called by user (with F2).
*/
void prevImage();
/*
* Draw (or not) image's background.
*/
void toggleDrawingBackground();
/*
* Show popup menu with external tools.
*/
void showExternalTools();
/*
* Generate textures for tickmarks and bind them.
*/
void initMarks();
/*
* Load and check tickmarks from disk.
*/
void createMarks();
/*
* Wrapper for 'delete' key. Called from keyPressEvent().
*/
void deleteWrapper();
/*
* Show current image's width, height and bpp in statusbar.
*/
void updateCurrentFileInfo();
/*
* Show/hide tickmarks.
*/
void toogleTickmarks();
/*
* Show current page number in multipaged images.
*
* For example: "3/11" means that current page is the third in current image,
* which has 11 pages.
*/
void frameChanged();
void calcFrameLabelWidth();
/*
* Set current zoom to 'z'.
*/
void internalZoom(const GLfloat &z);
/*
* Find best tile's width and height for given width and height.
*/
static void findCloserTiles(int w, int h, std::vector<int> &x, std::vector<int> &y);
static TQPair<int, int> calcRealDimensions(Parts &, int y = -1, int x = -1);
/*
* Prepare decoding. It will find proper library for decoding,
* clear old memory buffers, etc.
*/
bool prepare();
/*
* Zoom to 'r'. Will be called after somebody used mouse button
* to select zoom region. Return true, if zoomed.
*/
bool zoomRect(const TQRect &r);
/*
* Bind textures, draw them and create GL lists.
* If 'swap' it true, swap buffers.
*/
bool showFrames(int y, Parts *, bool swap);
/*
* OpenGL-related methods, not interesting :-)
*
* Move, zoom, reset, flip and rotate current matrix.
*/
void matrix_move(GLfloat x, GLfloat y);
void matrix_move_z(GLfloat z);
bool matrix_zoom(GLfloat ratio);
void matrix_reset(bool = true);
void matrix_pure_reset();
void matrix_push();
void matrix_pop();
void write_gl_matrix();
void matrix_rotate(GLfloat angle, bool = true);
void matrix_rotate2(GLfloat angle);
void flip(int, bool = true);
void flip_h();
void flip_v();
void exifRotate(bool);
signals:
void tabCountChanged();
void message(const TQString &);
public slots:
void slotPrint();
void slotSelectionEllipse();
void slotSelectionRect();
void slotSelectionClear();
private slots:
void decode();
void slotAccelActivated();
void slotChangeTab(int);
void slotCloseRequest(int);
void slotCopyJobResult(TDEIO::Job *job);
/*
* Slots for toolbar's actions:
* fit width, fit height, zoom+, zoom-, rotate, flip,
* first file, last file, reset...
*/
void slotShowNav();
void slotSetZoomPercents(int);
void slotZoomW();
void slotZoomH();
void slotZoomWH();
void slotZoomPlus();
void slotZoom100();
void slotZoomLast();
void slotZoomMinus();
void slotZoomIfLess();
void slotRotateLeft();
void slotRotateRight();
void slotFlipV();
void slotFlipH();
void slotMatrixReset();
void slotProperties(); // show image properties
void slotFirst();
void slotLast();
void slotNext();
void slotPrev();
void slotZoomMenu();
void slotAnimateNext();
void slotToggleAnimate(); // start/stop animation
void slotSetCurrentImage(int);
void slotShowImages();
void slotImagesHidden();
void slotImagesShown();
void slotShowHelp();
void slotShowCodecSettings();
void slotApplyCodecSettings();
void slotBCG(SQ_ImageBCGOptions *);
void slotFilter(SQ_ImageFilterOptions *fltopt);
void slotCopyResult(TDEIO::Job *);
private:
TDEAction *pASelectionClear;
TDEToggleAction *pAFull, *pAIfLess, *pAZoomW,
*pAZoomH, *pAZoomWH, *pAZoom100,
*pAZoomLast,
*pASelectionEllipse, *pASelectionRect;
SQ_ToolButton *pAToolQuick, *pAToolFull, *pAToolProp, *pAToolPrint;
SQ_ToolButtonPopup *pAToolZoom, *pAToolImages;
TDEActionCollection *ac, *acMain;
TQPopupMenu *menu, *menuFile, *menuImage;
int id_saveas, id_settings,
id_f5, id_f6, id_f7, id_f8, id_del,
id_prop;
// popup menu with zoom types (fit width, fit height, zoom 100%...)
TDEPopupMenu *zoomMenu, *selectionMenu,
// popup menu with image pages
*images;
TQImage BGpixmap, BGquads;
TQTimer *timer_prev, *timer_next;
TQTimer *timer_anim;
TQImage mm[4];
fmt_image image_broken;
SQ_GLSelectionPainter *gls;
Parts *parts_broken;
GLfloat saved[12], zoomfactor, movefactor, rotatefactor;
unsigned int texQuads, texPixmap, mark[4];
int xmoveold, ymoveold, xmove, ymove,
zoom_type, old_id, total, errors, movetype;
bool reset_mode, decoded, blocked,
changed, marks, linear;
float zoomFactor, oldZoom;
RGBA *buffer;
TQSlider *slider_zoom;
KTempFile *tmp;
KURL lastCopy, m_expected, m_original;
TQTime clickTime, started;
std::vector<Tab> tabs;
Tab *tab, *tabold;
Tab tmptab, taborig;
bool hackResizeGL, bindChecker;
TQLabel *percentsLabel;
#ifdef KSQUIRREL_PART
SQ_GLView t_glv;
#endif
static SQ_GLWidget *m_instance;
};
inline
int SQ_GLWidget::zoomType()
{
return zoom_type;
}
inline
bool SQ_GLWidget::isnice()
{
return linear;
}
inline
TDEActionCollection* SQ_GLWidget::actionCollection() const
{
return ac;
}
inline
void SQ_GLWidget::setOriginalURL(const KURL &u)
{
m_original = u;
}
inline
TQString SQ_GLWidget::originalURL() const
{
return tab->m_original.isLocalFile() ? tab->m_original.path() : tab->m_original.prettyURL();
}
inline
void SQ_GLWidget::setExpectedURL(const KURL &u)
{
m_expected = u;
}
#endif