summaryrefslogtreecommitdiffstats
path: root/kig/kig/kig_view.h
blob: 7970e088184b1b9f5dec316b8102c1633b0d55bc (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
/**
 This file is part of Kig, a KDE program for Interactive Geometry...
 Copyright (C) 2002  Dominique Devriese <devriese@kde.org>

 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.

 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
**/


#ifndef KIG_VIEW_H
#define KIG_VIEW_H

#include <qwidget.h>
#include <qpixmap.h>

#include <kparts/part.h>

#include <vector>

#include "../objects/object_holder.h"
#include "../misc/rect.h"
#include "../misc/screeninfo.h"

class QGridLayout;
class QScrollBar;

class KigDocument;
class KigView;

/**
 * This class is the real widget showing the document.  The other is a
 * wrapper, that has the scrollbars...  I'm not using QScrollView
 * cause i've been having problems with that, and it's easier to do
 * the work myself...
 * Internally, this is basically a dumb class, which is manipulated by
 * KigMode's.  All events are forwarded to them.
 */
class KigWidget : public QWidget
{
  Q_OBJECT

  KigPart* mpart;
  KigView* mview;

  // we reimplement these from QWidget to suit our needs
  void mousePressEvent( QMouseEvent* e );
  void mouseMoveEvent( QMouseEvent* e );
  void mouseReleaseEvent( QMouseEvent* e );
  void paintEvent( QPaintEvent* e );
  void wheelEvent( QWheelEvent* e );
  void resizeEvent( QResizeEvent* );
  QSize sizeHint() const;

  /**
   * this is called to match a rect's dimensions to the dimensions of
   * the window before we set mViewRect to it.  This is done cause we
   * always want circles to look like circles etc...
   */
  Rect matchScreenShape( const Rect& r ) const;

public:
  /**
   * what do the still objects look like
   * wondering if this is appropriate, maybe it should be part of
   * MovingMode ?
   */
  QPixmap stillPix;
  /**
   * temporary, gets bitBlt'd (copied) onto the widget
   * (to avoid flickering)
   */
  QPixmap curPix;

protected:
  std::vector<QRect> oldOverlay;

  /**
   * this is a class that maps from our widget coordinates to the
   * document's coordinates ( and back ).
   */
  ScreenInfo msi;

  /**
   * is this a full-screen widget ?
   */
  bool misfullscreen;

public:
  /**
   * standard qwidget constructor.  if fullscreen is true, we're a
   * fullscreen widget.
   */
  KigWidget( KigPart* doc,
             KigView* view,
             QWidget* parent = 0,
             const char* name = 0,
             bool fullscreen = false
	   );
  ~KigWidget();

  bool isFullScreen() const;
  void setFullScreen( bool f );

  const KigView* view() const {
    return mview;
  }

  KigView* view() {
    return mview;
  }

  /**
   * The following are functions used by KigMode's to tell us to draw
   * stuff...
   * i tried to optimise the drawing as much as possible, using
   * much ideas from kgeo
   * DOUBLE BUFFERING:
   * we don't draw on the widget directly, we draw on a QPixmap (
   * curPix ), and bitBlt that onto the widget to avoid flickering.
   * TRIPLE BUFFERING:
   * we also currently keep an extra pixmap of what the widget looks
   * like without objects that are moving... i'm currently wondering
   * whether this isn't a performance loss rather than a gain, but
   * well, i haven't done any measurements (yet ?), so for now it
   * stays in...
   * OVERLAYS
   * Another thing: it turns out that working on the pixmaps isn't
   * that slow, but working on the widget is.  So we try to reduce the
   * amount of work we spend on the widget. (i got this idea from
   * kgeo, all credits for this go to marc.bartsch@web.de)
   * on drawing, KigPainter tells us (appendOverlay) for everything it
   * draws what rects it draws in, so we know on updating the widget (
   * updateWidget() that the rest is still ok and doesn't need to be
   * bitBlt'd again on the widget...
   */

  /**
   * clear stillPix...
   */
  void clearStillPix();
  /**
   * update curPix (bitBlt stillPix onto curPix..)
   */
  void updateCurPix( const std::vector<QRect>& = std::vector<QRect>());

  /**
   * this means bitBlting curPix on the actual widget...
   */
  void updateWidget( const std::vector<QRect>& = std::vector<QRect>() );
  void updateEntireWidget();

  /**
   * Mapping between Internal Coordinate Systems
   * there are two coordinate systems:
   * 1 the widget's coordinates: these are simple int's from (0,0) in
   * the topleft of the widget to size() in the bottomRight...
   * 2 the document's coordinates: these are the coordinates used by
   * the KigDocument.  Objects only know of their coordinates as
   * related to this system.
   * These are mapped by the KigView using the ScreenInfo class.
   */
  const Rect showingRect() const;
  void setShowingRect( const Rect& r );

  const Coordinate fromScreen( const QPoint& p );
  const Rect fromScreen( const QRect& r );
  double pixelWidth() const;

  /**
   * the part of the document we're currently showing
   * i.e. a rectangle of the document (which has its own coordinate
   * system) which is mapped onto the widget.
   */
  const ScreenInfo& screenInfo() const;

  Rect entireDocumentRect() const;

  void updateScrollBars();

  void scrollSetBottom( double rhs );
  void scrollSetLeft( double rhs );

  const KigDocument& document() const;

public:
  /**
   * this recenters the screen, that is, resets the shown rect to
   * mpart->document().suggestedRect()..
   */
  void recenterScreen();
  /**
   * this gets called if the user clicks the recenter screen button.
   * It adds a KigCommand to the CommandHistory that recenters the
   * screen..
   */
  void slotRecenterScreen();

  // called when the user clicks the appropriate buttons..
  void slotZoomIn();
  void slotZoomOut();

  void zoomRect();
  void zoomArea();

  void redrawScreen( const std::vector<ObjectHolder*>& selection, bool paintOnWidget = true );
};

/**
 * This class is a wrapper for KigWidget.  It has some actions
 * that belong here, and not in the part.  It also maintains the
 * scrollbars, but it doesn't manipulate them itself.  It forwards
 * most of its functionality to KigWidget...
 */
class KigView
  : public QWidget
{
  Q_OBJECT

  QGridLayout* mlayout;
  QScrollBar* mrightscroll;
  QScrollBar* mbottomscroll;

  /**
   * apparently, QScrollBar also emits its signals when you update it
   * manually, so we ignore them while we're in \ref updateScrollBars()...
   */
  bool mupdatingscrollbars;

  KigWidget* mrealwidget;
  KigPart* mpart;

public:
  KigView( KigPart* part,
           bool fullscreen = false,
	   QWidget* parent = 0,
	   const char* name = 0
	   );
  ~KigView();

  void setupActions();

  const ScreenInfo& screenInfo() const;

  KigWidget* realWidget() const;
  void scrollHorizontal( int delta );
  void scrollVertical( int delta );

public slots:
  void updateScrollBars();
  void slotZoomIn();
  void slotZoomOut();
  void zoomRect();
  void zoomArea();
  void slotInternalRecenterScreen();
  void slotRecenterScreen();
  void toggleFullScreen();

private slots:
  void slotRightScrollValueChanged( int );
  void slotBottomScrollValueChanged( int );
};
#endif