summaryrefslogtreecommitdiffstats
path: root/ksquirrel/ksquirrelpart/sq_glwidget.h
blob: bb092a92b81ea1c648f7c4f22139128ea38185a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
/***************************************************************************
                          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 KAction;
class KActionCollection;
class KToggleAction;
class KPopupMenu;
class KRadioAction;
class KTempFile;

namespace KIO { 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
{
    Q_OBJECT
  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;

        KActionCollection* 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 KActions.
         */
        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(KIO::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(KIO::Job *);

    private:
        KAction               *pASelectionClear;
        KToggleAction         *pAFull, *pAIfLess, *pAZoomW,
                              *pAZoomH, *pAZoomWH, *pAZoom100,
                              *pAZoomLast,
                              *pASelectionEllipse, *pASelectionRect;

        SQ_ToolButton         *pAToolQuick, *pAToolFull, *pAToolProp, *pAToolPrint;
        SQ_ToolButtonPopup    *pAToolZoom,  *pAToolImages;

        KActionCollection     *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%...)
        KPopupMenu            *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
KActionCollection* 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