comparison demos/deform/pathdeform.d @ 163:ab01453c9d56

change to QObject.findChildren and code formatting
author mwarning
date Wed, 17 Jun 2009 23:21:57 +0000
parents 849b66609571
children 0f23cdea249a
comparison
equal deleted inserted replaced
162:4bbd9f3d9add 163:ab01453c9d56
40 ****************************************************************************/ 40 ****************************************************************************/
41 module pathdeform; 41 module pathdeform;
42 42
43 43
44 import arthurwidgets, 44 import arthurwidgets,
45 qt.gui.QPainterPath, 45 qt.gui.QPainterPath,
46 46 qt.gui.QApplication,
47 qt.gui.QApplication, 47 qt.gui.QMouseEvent,
48 qt.gui.QMouseEvent, 48 qt.core.QDateTime,
49 qt.core.QDateTime, 49 qt.core.QTimerEvent,
50 qt.core.QTimerEvent, 50 qt.core.QBasicTimer,
51 qt.core.QBasicTimer, 51 qt.gui.QLayout,
52 qt.gui.QLayout, 52 qt.gui.QLineEdit,
53 qt.gui.QLineEdit, 53 qt.gui.QPainter,
54 qt.gui.QPainter, 54 qt.gui.QSlider,
55 qt.gui.QSlider, 55 qt.gui.QLabel,
56 qt.gui.QLabel, 56 qt.gui.QDesktopWidget,
57 qt.gui.QDesktopWidget, 57 qt.gui.QGroupBox,
58 qt.gui.QGroupBox, 58 qt.gui.QPushButton,
59 qt.gui.QPushButton, 59 qt.gui.QVBoxLayout,
60 qt.gui.QVBoxLayout, 60 qt.gui.QGridLayout,
61 qt.gui.QGridLayout, 61 qt.gui.QHBoxLayout,
62 qt.gui.QHBoxLayout, 62 qt.gui.QRadialGradient,
63 qt.gui.QRadialGradient, 63 qt.opengl.QGLFormat,
64 qt.opengl.QGLFormat, 64 tango.math.Math;
65 tango.math.Math;
66 65
67 66
68 class PathDeformControls : QWidget 67 class PathDeformControls : QWidget
69 { 68 {
70 private PathDeformRenderer m_renderer; 69 private PathDeformRenderer m_renderer;
71 70
72 mixin Signal!("okPressed"); 71 mixin Signal!("okPressed");
73 mixin Signal!("quitPressed"); 72 mixin Signal!("quitPressed");
74 73
75 this(QWidget parent, PathDeformRenderer renderer, bool smallScreen) 74 this(QWidget parent, PathDeformRenderer renderer, bool smallScreen)
76 { 75 {
77 super(parent); 76 super(parent);
78 m_renderer = renderer; 77 m_renderer = renderer;
79 78
80 if (smallScreen) 79 if (smallScreen)
81 layoutForSmallScreen(); 80 layoutForSmallScreen();
82 else 81 else
83 layoutForDesktop(); 82 layoutForDesktop();
84 } 83 }
85 84
86 void layoutForDesktop() 85 void layoutForDesktop()
87 { 86 {
88 QGroupBox mainGroup = new QGroupBox(this); 87 QGroupBox mainGroup = new QGroupBox(this);
89 mainGroup.setTitle(tr("Controls")); 88 mainGroup.setTitle(tr("Controls"));
90 89
91 QGroupBox radiusGroup = new QGroupBox(mainGroup); 90 QGroupBox radiusGroup = new QGroupBox(mainGroup);
92 radiusGroup.setTitle(tr("Lens Radius")); 91 radiusGroup.setTitle(tr("Lens Radius"));
93 QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup); 92 QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup);
94 radiusSlider.setRange(15, 150); 93 radiusSlider.setRange(15, 150);
95 radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); 94 radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
96 95
97 QGroupBox deformGroup = new QGroupBox(mainGroup); 96 QGroupBox deformGroup = new QGroupBox(mainGroup);
98 deformGroup.setTitle(tr("Deformation")); 97 deformGroup.setTitle(tr("Deformation"));
99 QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup); 98 QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup);
100 deformSlider.setRange(-100, 100); 99 deformSlider.setRange(-100, 100);
101 deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); 100 deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
102 101
103 QGroupBox fontSizeGroup = new QGroupBox(mainGroup); 102 QGroupBox fontSizeGroup = new QGroupBox(mainGroup);
104 fontSizeGroup.setTitle(tr("Font Size")); 103 fontSizeGroup.setTitle(tr("Font Size"));
105 QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup); 104 QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup);
106 fontSizeSlider.setRange(16, 200); 105 fontSizeSlider.setRange(16, 200);
107 fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed); 106 fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
108 107
109 QGroupBox textGroup = new QGroupBox(mainGroup); 108 QGroupBox textGroup = new QGroupBox(mainGroup);
110 textGroup.setTitle(tr("Text")); 109 textGroup.setTitle(tr("Text"));
111 QLineEdit textInput = new QLineEdit(textGroup); 110 QLineEdit textInput = new QLineEdit(textGroup);
112 111
113 QPushButton animateButton = new QPushButton(mainGroup); 112 QPushButton animateButton = new QPushButton(mainGroup);
114 animateButton.setText(tr("Animated")); 113 animateButton.setText(tr("Animated"));
115 animateButton.setCheckable(true); 114 animateButton.setCheckable(true);
116 115
117 QPushButton showSourceButton = new QPushButton(mainGroup); 116 QPushButton showSourceButton = new QPushButton(mainGroup);
118 showSourceButton.setText(tr("Show Source")); 117 showSourceButton.setText(tr("Show Source"));
119 118
120 version (QT_OPENGL_SUPPORT) 119 version (QT_OPENGL_SUPPORT)
121 { 120 {
122 QPushButton enableOpenGLButton = new QPushButton(mainGroup); 121 QPushButton enableOpenGLButton = new QPushButton(mainGroup);
123 enableOpenGLButton.setText(tr("Use OpenGL")); 122 enableOpenGLButton.setText(tr("Use OpenGL"));
124 enableOpenGLButton.setCheckable(true); 123 enableOpenGLButton.setCheckable(true);
125 enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); 124 enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
126 if (!QGLFormat.hasOpenGL()) 125 if (!QGLFormat.hasOpenGL())
127 enableOpenGLButton.hide(); 126 enableOpenGLButton.hide();
128 } 127 }
129 128
130 QPushButton whatsThisButton = new QPushButton(mainGroup); 129 QPushButton whatsThisButton = new QPushButton(mainGroup);
131 whatsThisButton.setText(tr("What's This?")); 130 whatsThisButton.setText(tr("What's This?"));
132 whatsThisButton.setCheckable(true); 131 whatsThisButton.setCheckable(true);
133 132
134 mainGroup.setFixedWidth(180); 133 mainGroup.setFixedWidth(180);
135 134
136 QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup); 135 QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup);
137 mainGroupLayout.addWidget(radiusGroup); 136 mainGroupLayout.addWidget(radiusGroup);
138 mainGroupLayout.addWidget(deformGroup); 137 mainGroupLayout.addWidget(deformGroup);
139 mainGroupLayout.addWidget(fontSizeGroup); 138 mainGroupLayout.addWidget(fontSizeGroup);
140 mainGroupLayout.addWidget(textGroup); 139 mainGroupLayout.addWidget(textGroup);
141 mainGroupLayout.addWidget(animateButton); 140 mainGroupLayout.addWidget(animateButton);
142 mainGroupLayout.addStretch(1); 141 mainGroupLayout.addStretch(1);
143 version (QT_OPENGL_SUPPORT) 142 version (QT_OPENGL_SUPPORT)
144 { 143 {
145 mainGroupLayout.addWidget(enableOpenGLButton); 144 mainGroupLayout.addWidget(enableOpenGLButton);
146 } 145 }
147 mainGroupLayout.addWidget(showSourceButton); 146 mainGroupLayout.addWidget(showSourceButton);
148 mainGroupLayout.addWidget(whatsThisButton); 147 mainGroupLayout.addWidget(whatsThisButton);
149 148
150 QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup); 149 QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup);
151 radiusGroupLayout.addWidget(radiusSlider); 150 radiusGroupLayout.addWidget(radiusSlider);
152 151
153 QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup); 152 QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup);
154 deformGroupLayout.addWidget(deformSlider); 153 deformGroupLayout.addWidget(deformSlider);
155 154
156 QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup); 155 QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
157 fontSizeGroupLayout.addWidget(fontSizeSlider); 156 fontSizeGroupLayout.addWidget(fontSizeSlider);
158 157
159 QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup); 158 QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup);
160 textGroupLayout.addWidget(textInput); 159 textGroupLayout.addWidget(textInput);
161 160
162 QVBoxLayout mainLayout = new QVBoxLayout(this); 161 QVBoxLayout mainLayout = new QVBoxLayout(this);
163 mainLayout.addWidget(mainGroup); 162 mainLayout.addWidget(mainGroup);
164 mainLayout.setMargin(0); 163 mainLayout.setMargin(0);
165 164
166 radiusSlider.valueChanged.connect(&m_renderer.setRadius); 165 radiusSlider.valueChanged.connect(&m_renderer.setRadius);
167 deformSlider.valueChanged.connect(&m_renderer.setIntensity); 166 deformSlider.valueChanged.connect(&m_renderer.setIntensity);
168 fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); 167 fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
169 animateButton.clicked.connect(&m_renderer.setAnimated); 168 animateButton.clicked.connect(&m_renderer.setAnimated);
170 version (QT_OPENGL_SUPPORT) 169 version (QT_OPENGL_SUPPORT)
171 { 170 {
172 enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); 171 enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
173 } 172 }
174 173
175 textInput.textChanged.connect(&m_renderer.setText); 174 textInput.textChanged.connect(&m_renderer.setText);
176 m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked); 175 m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked);
177 whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled); 176 whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled);
178 showSourceButton.clicked.connect(&m_renderer.showSource); 177 showSourceButton.clicked.connect(&m_renderer.showSource);
179 178
180 animateButton.animateClick(); 179 animateButton.animateClick();
181 deformSlider.setValue(80); 180 deformSlider.setValue(80);
182 fontSizeSlider.setValue(120); 181 fontSizeSlider.setValue(120);
183 radiusSlider.setValue(100); 182 radiusSlider.setValue(100);
184 textInput.setText(tr("Qt")); 183 textInput.setText(tr("Qt"));
185 } 184 }
186 185
187 void layoutForSmallScreen() 186 void layoutForSmallScreen()
188 { 187 {
189 QGroupBox mainGroup = new QGroupBox(this); 188 QGroupBox mainGroup = new QGroupBox(this);
190 mainGroup.setTitle(tr("Controls")); 189 mainGroup.setTitle(tr("Controls"));
191 190
192 QLabel radiusLabel = new QLabel(mainGroup); 191 QLabel radiusLabel = new QLabel(mainGroup);
193 radiusLabel.setText(tr("Lens Radius:")); 192 radiusLabel.setText(tr("Lens Radius:"));
194 QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup); 193 QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup);
195 radiusSlider.setRange(15, 150); 194 radiusSlider.setRange(15, 150);
196 radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); 195 radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
197 196
198 QLabel deformLabel = new QLabel(mainGroup); 197 QLabel deformLabel = new QLabel(mainGroup);
199 deformLabel.setText(tr("Deformation:")); 198 deformLabel.setText(tr("Deformation:"));
200 QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup); 199 QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup);
201 deformSlider.setRange(-100, 100); 200 deformSlider.setRange(-100, 100);
202 deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); 201 deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
203 202
204 QLabel fontSizeLabel = new QLabel(mainGroup); 203 QLabel fontSizeLabel = new QLabel(mainGroup);
205 fontSizeLabel.setText(tr("Font Size:")); 204 fontSizeLabel.setText(tr("Font Size:"));
206 QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup); 205 QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup);
207 fontSizeSlider.setRange(16, 200); 206 fontSizeSlider.setRange(16, 200);
208 fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed); 207 fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
209 208
210 QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup); 209 QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup);
211 animateButton.setCheckable(true); 210 animateButton.setCheckable(true);
212 211
213 version (QT_OPENGL_SUPPORT) 212 version (QT_OPENGL_SUPPORT)
214 { 213 {
215 QPushButton enableOpenGLButton = new QPushButton(mainGroup); 214 QPushButton enableOpenGLButton = new QPushButton(mainGroup);
216 enableOpenGLButton.setText(tr("Use OpenGL")); 215 enableOpenGLButton.setText(tr("Use OpenGL"));
217 enableOpenGLButton.setCheckable(true); 216 enableOpenGLButton.setCheckable(true);
218 enableOpenGLButton.setChecked(m_renderer.usesOpenGL()); 217 enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
219 if (!QGLFormat.hasOpenGL()) 218 if (!QGLFormat.hasOpenGL())
220 enableOpenGLButton.hide(); 219 enableOpenGLButton.hide();
221 } 220 }
222 221
223 QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup); 222 QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup);
224 QPushButton okButton = new QPushButton(tr("OK"), mainGroup); 223 QPushButton okButton = new QPushButton(tr("OK"), mainGroup);
225 224
226 225
227 QGridLayout mainGroupLayout = new QGridLayout(mainGroup); 226 QGridLayout mainGroupLayout = new QGridLayout(mainGroup);
228 mainGroupLayout.setMargin(0); 227 mainGroupLayout.setMargin(0);
229 mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight); 228 mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight);
230 mainGroupLayout.addWidget(radiusSlider, 0, 1); 229 mainGroupLayout.addWidget(radiusSlider, 0, 1);
231 mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight); 230 mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight);
232 mainGroupLayout.addWidget(deformSlider, 1, 1); 231 mainGroupLayout.addWidget(deformSlider, 1, 1);
233 mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight); 232 mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight);
234 mainGroupLayout.addWidget(fontSizeSlider, 2, 1); 233 mainGroupLayout.addWidget(fontSizeSlider, 2, 1);
235 mainGroupLayout.addWidget(animateButton, 3,0, 1,2); 234 mainGroupLayout.addWidget(animateButton, 3,0, 1,2);
236 version (QT_OPENGL_SUPPORT) 235 version (QT_OPENGL_SUPPORT)
237 { 236 {
238 mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2); 237 mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2);
239 } 238 }
240 239
241 QVBoxLayout mainLayout = new QVBoxLayout(this); 240 QVBoxLayout mainLayout = new QVBoxLayout(this);
242 mainLayout.addWidget(mainGroup); 241 mainLayout.addWidget(mainGroup);
243 mainLayout.addStretch(1); 242 mainLayout.addStretch(1);
244 mainLayout.addWidget(okButton); 243 mainLayout.addWidget(okButton);
245 mainLayout.addWidget(quitButton); 244 mainLayout.addWidget(quitButton);
246 245
247 quitButton.clicked.connect(&emitQuitSignal); 246 quitButton.clicked.connect(&emitQuitSignal);
248 okButton.clicked.connect(&emitOkSignal); 247 okButton.clicked.connect(&emitOkSignal);
249 radiusSlider.valueChanged.connect(&m_renderer.setRadius); 248 radiusSlider.valueChanged.connect(&m_renderer.setRadius);
250 deformSlider.valueChanged.connect(&m_renderer.setIntensity); 249 deformSlider.valueChanged.connect(&m_renderer.setIntensity);
251 fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize); 250 fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
252 animateButton.clicked.connect(&m_renderer.setAnimated); 251 animateButton.clicked.connect(&m_renderer.setAnimated);
253 version (QT_OPENGL_SUPPORT) 252 version (QT_OPENGL_SUPPORT)
254 { 253 {
255 enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL); 254 enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
256 } 255 }
257 256
258 257 animateButton.animateClick();
259 animateButton.animateClick(); 258 deformSlider.setValue(80);
260 deformSlider.setValue(80); 259 fontSizeSlider.setValue(120);
261 fontSizeSlider.setValue(120); 260
262 261 QRect screen_size = QApplication.desktop().screenGeometry();
263 QRect screen_size = QApplication.desktop().screenGeometry(); 262 radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5);
264 radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5); 263 m_renderer.setText(tr("Qt"));
265 m_renderer.setText(tr("Qt")); 264 }
266 } 265
267 266 void emitQuitSignal()
268 267 {
269 void emitQuitSignal() 268 quitPressed.emit;
270 { quitPressed.emit; } 269 }
271 270
272 void emitOkSignal() 271 void emitOkSignal()
273 { okPressed.emit; } 272 {
273 okPressed.emit;
274 }
274 } 275 }
275 276
276 277
277 class PathDeformWidget : QWidget 278 class PathDeformWidget : QWidget
278 { 279 {
279 private: 280 private:
280 PathDeformRenderer m_renderer; 281
281 PathDeformControls m_controls; 282 PathDeformRenderer m_renderer;
283 PathDeformControls m_controls;
282 284
283 public: 285 public:
284 this(QWidget parent, bool smallScreen) 286
285 { 287 this(QWidget parent, bool smallScreen)
286 super(parent); 288 {
287 289 super(parent);
288 setWindowTitle(tr("Vector Deformation")); 290
289 291 setWindowTitle(tr("Vector Deformation"));
290 m_renderer = new PathDeformRenderer(this, smallScreen); 292
291 m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); 293 m_renderer = new PathDeformRenderer(this, smallScreen);
292 294 m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding);
293 // Layouts 295
294 QHBoxLayout mainLayout = new QHBoxLayout(this); 296 // Layouts
295 mainLayout.addWidget(m_renderer); 297 QHBoxLayout mainLayout = new QHBoxLayout(this);
296 298 mainLayout.addWidget(m_renderer);
297 m_controls = new PathDeformControls(null, m_renderer, smallScreen); 299
298 m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum); 300 m_controls = new PathDeformControls(null, m_renderer, smallScreen);
299 301 m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum);
300 if (!smallScreen) 302
301 mainLayout.addWidget(m_controls); 303 if (!smallScreen)
302 304 mainLayout.addWidget(m_controls);
303 m_renderer.loadSourceFile(":res/deform/pathdeform.d"); 305
304 m_renderer.loadDescription(":res/deform/pathdeform.html"); 306 m_renderer.loadSourceFile(":res/deform/pathdeform.d");
305 m_renderer.setDescriptionEnabled(false); 307 m_renderer.loadDescription(":res/deform/pathdeform.html");
306 308 m_renderer.setDescriptionEnabled(false);
307 m_renderer.clicked.connect(&showControls); 309
308 m_controls.okPressed.connect(&hideControls); 310 m_renderer.clicked.connect(&showControls);
309 311 m_controls.okPressed.connect(&hideControls);
310 m_controls.quitPressed.connect(&QApplication.quit); 312
311 } 313 m_controls.quitPressed.connect(&QApplication.quit);
312 314 }
313 void showControls() 315
314 { 316 void showControls()
315 m_controls.showFullScreen; 317 {
316 } 318 m_controls.showFullScreen;
317 319 }
318 void hideControls() 320
319 { 321 void hideControls()
320 m_controls.hide; 322 {
321 } 323 m_controls.hide;
322 324 }
323 void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual 325
324 { 326 void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual
325 super.setStyle(style); 327 {
326 if (m_controls) 328 super.setStyle(style);
327 { 329 if (m_controls)
328 m_controls.setStyle(style); 330 {
329 331 m_controls.setStyle(style);
330 QWidget[] widgets; // = qFindChildren!(QWidget)(m_controls); //TODO 332
331 foreach (w; widgets) 333 QWidget[] widgets = m_controls.findChildren!(QWidget);
332 w.setStyle(style); 334 foreach (w; widgets)
333 } 335 w.setStyle(style);
334 } 336 }
337 }
335 } 338 }
336 339
337 private QRect circle_bounds(QPointF center, qreal radius, qreal compensation) 340 private QRect circle_bounds(QPointF center, qreal radius, qreal compensation)
338 { 341 {
339 return QRect(qRound(center.x() - radius - compensation), 342 return QRect(qRound(center.x() - radius - compensation),
340 qRound(center.y() - radius - compensation), 343 qRound(center.y() - radius - compensation),
341 qRound((radius + compensation) * 2), 344 qRound((radius + compensation) * 2),
342 qRound((radius + compensation) * 2)); 345 qRound((radius + compensation) * 2));
343 } 346 }
344 347
345 enum 348 enum
346 { 349 {
347 LENS_EXTENT = 10 350 LENS_EXTENT = 10
348 } 351 }
349 352
350 class PathDeformRenderer : ArthurFrame 353 class PathDeformRenderer : ArthurFrame
351 { 354 {
352 private: 355 private:
353 QBasicTimer m_repaintTimer; 356
354 // QBasicTimer m_fpsTimer; 357 QBasicTimer m_repaintTimer;
355 // int m_fpsCounter; 358 // QBasicTimer m_fpsTimer;
356 QTime m_repaintTracker; 359 // int m_fpsCounter;
357 360 QTime m_repaintTracker;
358 QPainterPath[] m_paths; 361
359 QPointF[] m_advances; 362 QPainterPath[] m_paths;
360 QRectF m_pathBounds; 363 QPointF[] m_advances;
361 string m_text; 364 QRectF m_pathBounds;
362 365 string m_text;
363 QPixmap m_lens_pixmap; 366
364 QImage m_lens_image; 367 QPixmap m_lens_pixmap;
365 368 QImage m_lens_image;
366 int m_fontSize; 369
367 bool m_animated; 370 int m_fontSize;
368 371 bool m_animated;
369 qreal m_intensity; 372
370 qreal m_radius; 373 qreal m_intensity;
371 QPointF m_pos; 374 qreal m_radius;
372 QPointF m_offset; 375 QPointF m_pos;
373 QPointF m_direction; 376 QPointF m_offset;
374 QPointF m_mousePress; 377 QPointF m_direction;
375 bool m_mouseDrag; 378 QPointF m_mousePress;
376 bool m_smallScreen; 379 bool m_mouseDrag;
380 bool m_smallScreen;
377 381
378 public: 382 public:
379 mixin Signal!("clicked"); 383
380 384 mixin Signal!("clicked");
381 this(QWidget widget, bool smallScreen) 385
382 { 386 this(QWidget widget, bool smallScreen)
383 super(widget); 387 {
384 m_radius = 100; 388 super(widget);
385 m_pos = QPointF(m_radius, m_radius); 389 m_radius = 100;
386 m_direction = QPointF(1, 1); 390 m_pos = QPointF(m_radius, m_radius);
387 m_fontSize = 24; 391 m_direction = QPointF(1, 1);
388 m_animated = true; 392 m_fontSize = 24;
389 m_repaintTimer.start(25, this); 393 m_animated = true;
390 m_repaintTracker.start(); 394 m_repaintTimer.start(25, this);
391 m_intensity = 100; 395 m_repaintTracker.start();
392 m_smallScreen = smallScreen; 396 m_intensity = 100;
393 397 m_smallScreen = smallScreen;
394 // m_fpsTimer.start(1000, this); 398
395 // m_fpsCounter = 0; 399 // m_fpsTimer.start(1000, this);
396 400 // m_fpsCounter = 0;
397 generateLensPixmap(); 401
398 } 402 generateLensPixmap();
399 403 }
400 void setFontSize(int fontSize) { m_fontSize = fontSize; setText(m_text); } 404
401 405 void setFontSize(int fontSize)
402 override QSize sizeHint() { return QSize(600, 500); } 406 {
403 407 m_fontSize = fontSize;
404 bool animated() { return m_animated; } 408 setText(m_text);
405 int radius() { return cast(int)m_radius; } 409 }
406 int fontSize() { return m_fontSize; } 410
407 int intensity() { return cast(int)m_intensity; } 411 override QSize sizeHint() { return QSize(600, 500); }
408 string text() { return m_text; } 412
409 413 bool animated() { return m_animated; }
410 414 int radius() { return cast(int) m_radius; }
411 void setText(string text) 415 int fontSize() { return m_fontSize; }
412 { 416 int intensity() { return cast(int) m_intensity; }
413 m_text = text; 417 string text() { return m_text; }
414 418
415 auto f = new QFont("times new roman,utopia"); 419 void setText(string text)
416 f.setStyleStrategy(QFont.ForceOutline); 420 {
417 f.setPointSize(m_fontSize); 421 m_text = text;
418 f.setStyleHint(QFont.Times); 422
419 423 auto f = new QFont("times new roman,utopia");
420 m_paths = null; 424 f.setStyleStrategy(QFont.ForceOutline);
421 m_pathBounds = QRectF(); 425 f.setPointSize(m_fontSize);
422 426 f.setStyleHint(QFont.Times);
423 QPointF advance; 427
424 428 m_paths = null;
425 auto path = new QPainterPath; 429 m_pathBounds = QRectF();
426 path.addText(advance, f, text); 430
427 m_pathBounds = m_pathBounds.united(path.boundingRect); 431 QPointF advance(0, 0);
428 m_paths ~= path; 432
429 433 bool do_quick = true;
430 foreach (ref p; m_paths) 434 for (int i = 0; i < text.length; ++i) {
431 p = (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y())).map(path); 435 if (text[i].unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
432 436 do_quick = false;
433 update; 437 break;
434 } 438 }
435 439 }
436 440
437 void generateLensPixmap() 441 if (do_quick) {
438 { 442 for (int i = 0; i < text.length; ++i) {
439 qreal rad = m_radius + LENS_EXTENT; 443 QPainterPath path = new QPainterPath;
440 444 path.addText(advance, f, text.mid(i, 1));
441 QRect bounds = circle_bounds(QPointF(), rad, 0); 445 m_pathBounds |= path.boundingRect();
442 446 m_paths ~= path;
443 QPainter painter = new QPainter; 447 advance += QPointF(fm.width(text.mid(i, 1)), 0);
444 448 }
445 if (preferImage()) { 449 } else {
446 m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied); 450 QPainterPath path = new QPainterPath;
447 m_lens_image.fill(0); 451 path.addText(advance, f, text);
448 painter.begin(m_lens_image); 452 m_pathBounds |= path.boundingRect();
449 } else { 453 m_paths ~= path;
450 m_lens_pixmap = new QPixmap(bounds.size()); 454 }
451 m_lens_pixmap.fill(new QColor(Qt.transparent)); 455
452 painter.begin(m_lens_pixmap); 456 for (int i = 0; i < m_paths.length; ++i)
453 } 457 m_paths[i] = m_paths[i] * (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y());
454 458
455 auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5); 459 update();
456 gr.setColorAt(0.0, new QColor(255, 255, 255, 191)); 460 }
457 gr.setColorAt(0.2, new QColor(255, 255, 127, 191)); 461
458 gr.setColorAt(0.9, new QColor(150, 150, 200, 63)); 462 void generateLensPixmap()
459 gr.setColorAt(0.95, new QColor(0, 0, 0, 127)); 463 {
460 gr.setColorAt(1, new QColor(0, 0, 0, 0)); 464 qreal rad = m_radius + LENS_EXTENT;
461 painter.setRenderHint(QPainter.Antialiasing); 465
462 painter.setBrush(gr); 466 QRect bounds = circle_bounds(QPointF(), rad, 0);
463 painter.setPen(Qt.NoPen); 467
464 painter.drawEllipse(0, 0, bounds.width(), bounds.height()); 468 QPainter painter = new QPainter;
465 } 469
466 470 if (preferImage()) {
467 void setAnimated(bool animated) 471 m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied);
468 { 472 m_lens_image.fill(0);
469 m_animated = animated; 473 painter.begin(m_lens_image);
470 474 } else {
471 if (m_animated) { 475 m_lens_pixmap = new QPixmap(bounds.size());
472 // m_fpsTimer.start(1000, this); 476 m_lens_pixmap.fill(new QColor(Qt.transparent));
473 // m_fpsCounter = 0; 477 painter.begin(m_lens_pixmap);
474 m_repaintTimer.start(25, this); 478 }
475 m_repaintTracker.start(); 479
476 } else { 480 auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
477 // m_fpsTimer.stop(); 481 gr.setColorAt(0.0, new QColor(255, 255, 255, 191));
478 m_repaintTimer.stop(); 482 gr.setColorAt(0.2, new QColor(255, 255, 127, 191));
479 } 483 gr.setColorAt(0.9, new QColor(150, 150, 200, 63));
480 } 484 gr.setColorAt(0.95, new QColor(0, 0, 0, 127));
481 485 gr.setColorAt(1, new QColor(0, 0, 0, 0));
482 override void timerEvent(QTimerEvent e) 486 painter.setRenderHint(QPainter.Antialiasing);
483 { 487 painter.setBrush(gr);
484 488 painter.setPen(Qt.NoPen);
485 if (e.timerId == m_repaintTimer.timerId) { 489 painter.drawEllipse(0, 0, bounds.width(), bounds.height());
486 490 }
487 if ((QLineF(QPointF(0,0), m_direction)).length() > 1) 491
488 m_direction *= 0.995; 492 void setAnimated(bool animated)
489 qreal time = m_repaintTracker.restart(); 493 {
490 494 m_animated = animated;
491 QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); 495
492 496 if (m_animated) {
493 qreal dx = m_direction.x(); 497 // m_fpsTimer.start(1000, this);
494 qreal dy = m_direction.y(); 498 // m_fpsCounter = 0;
495 if (time > 0) { 499 m_repaintTimer.start(25, this);
496 dx = dx * time * .1; 500 m_repaintTracker.start();
497 dy = dy * time * .1; 501 } else {
498 } 502 // m_fpsTimer.stop();
499 503 m_repaintTimer.stop();
500 m_pos += QPointF(dx, dy); 504 }
501 505 }
502 if (m_pos.x() - m_radius < 0) { 506
503 m_direction.x = -m_direction.x; 507 override void timerEvent(QTimerEvent e)
504 m_pos.x = m_radius; 508 {
505 } else if (m_pos.x + m_radius > width) { 509 if (e.timerId == m_repaintTimer.timerId)
506 m_direction.x = -m_direction.x; 510 {
507 m_pos.x = width - m_radius; 511 if ((QLineF(QPointF(0,0), m_direction)).length() > 1)
508 } 512 m_direction *= 0.995;
509 513 qreal time = m_repaintTracker.restart();
510 if (m_pos.y - m_radius < 0) { 514
511 m_direction.y = -m_direction.y; 515 QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
512 m_pos.y = m_radius; 516
513 } else if (m_pos.y + m_radius > height) { 517 qreal dx = m_direction.x();
514 m_direction.y = -m_direction.y; 518 qreal dy = m_direction.y();
515 m_pos.y = height - m_radius; 519 if (time > 0) {
516 } 520 dx = dx * time * .1;
517 521 dy = dy * time * .1;
518 void noGLUpdate() 522 }
519 { 523
520 QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); 524 m_pos += QPointF(dx, dy);
521 update(rectAfter.united(rectBefore)); 525
522 QApplication.syncX(); 526 if (m_pos.x() - m_radius < 0) {
523 } 527 m_direction.x = -m_direction.x;
524 528 m_pos.x = m_radius;
525 version (QT_OPENGL_SUPPORT) 529 } else if (m_pos.x + m_radius > width) {
526 { 530 m_direction.x = -m_direction.x;
527 if (usesOpenGL()) { 531 m_pos.x = width - m_radius;
528 update; 532 }
529 } 533
530 else 534 if (m_pos.y - m_radius < 0) {
531 noGLUpdate; 535 m_direction.y = -m_direction.y;
532 } 536 m_pos.y = m_radius;
533 else 537 } else if (m_pos.y + m_radius > height) {
534 noGLUpdate; 538 m_direction.y = -m_direction.y;
535 } 539 m_pos.y = height - m_radius;
536 // else if (e.timerId() == m_fpsTimer.timerId()) { 540 }
537 // printf("fps: %d\n", m_fpsCounter); 541
538 // emit frameRate(m_fpsCounter); 542 void noGLUpdate()
539 // m_fpsCounter = 0; 543 {
540 544 QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
541 // } 545 update(rectAfter.united(rectBefore));
542 } 546 QApplication.syncX();
543 547 }
544 override void mousePressEvent(QMouseEvent e) 548
545 { 549 version (QT_OPENGL_SUPPORT)
546 setDescriptionEnabled(false); 550 {
547 551 if (usesOpenGL()) {
548 m_repaintTimer.stop(); 552 update;
549 m_offset = QPointF(); 553 }
550 if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius) 554 else
551 m_offset = m_pos - QPointF(e.pos); 555 noGLUpdate;
552 556 }
553 m_mousePress = QPointF(e.pos); 557 else
554 558 noGLUpdate;
555 // If we're not running in small screen mode, always assume we're dragging 559 }
556 m_mouseDrag = !m_smallScreen; 560 // else if (e.timerId() == m_fpsTimer.timerId()) {
557 561 // printf("fps: %d\n", m_fpsCounter);
558 mouseMoveEvent(e); 562 // emit frameRate(m_fpsCounter);
559 } 563 // m_fpsCounter = 0;
560 564
561 override void mouseReleaseEvent(QMouseEvent e) 565 // }
562 { 566 }
563 if (e.buttons() == Qt.NoButton && m_animated) { 567
564 m_repaintTimer.start(10, this); 568 override void mousePressEvent(QMouseEvent e)
565 m_repaintTracker.start(); 569 {
566 } 570 setDescriptionEnabled(false);
567 571
568 if (!m_mouseDrag && m_smallScreen) 572 m_repaintTimer.stop();
569 clicked.emit; 573 m_offset = QPointF();
570 } 574 if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius)
571 575 m_offset = m_pos - QPointF(e.pos);
572 override void mouseMoveEvent(QMouseEvent e) 576
573 { 577 m_mousePress = QPointF(e.pos);
574 auto epos = QPointF(e.pos); 578
575 579 // If we're not running in small screen mode, always assume we're dragging
576 if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0) 580 m_mouseDrag = !m_smallScreen;
577 m_mouseDrag = true; 581
578 582 mouseMoveEvent(e);
579 if (m_mouseDrag) { 583 }
580 QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize); 584
581 if (e.type() == QEvent.MouseMove) { 585 override void mouseReleaseEvent(QMouseEvent e)
582 QLineF line = QLineF(m_pos, epos + m_offset); 586 {
583 line.setLength(line.length() * .1); 587 if (e.buttons() == Qt.NoButton && m_animated) {
584 auto dir = QPointF(line.dx(), line.dy()); 588 m_repaintTimer.start(10, this);
585 m_direction = (m_direction + dir) / 2; 589 m_repaintTracker.start();
586 } 590 }
587 m_pos = epos + m_offset; 591
588 592 if (!m_mouseDrag && m_smallScreen)
589 void noGLUpdate() 593 clicked.emit;
590 { 594 }
591 QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize); 595
592 update(rectBefore.united(rectAfter)); 596 override void mouseMoveEvent(QMouseEvent e)
593 } 597 {
594 598 auto epos = QPointF(e.pos);
595 version (QT_OPENGL_SUPPORT) 599
596 { 600 if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0)
597 if (usesOpenGL()) { 601 m_mouseDrag = true;
598 update; 602
599 } else 603 if (m_mouseDrag)
600 noGLUpdate; 604 {
601 } 605 QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
602 else 606 if (e.type() == QEvent.MouseMove) {
603 noGLUpdate; 607 QLineF line = QLineF(m_pos, epos + m_offset);
604 } 608 line.setLength(line.length() * .1);
605 } 609 auto dir = QPointF(line.dx(), line.dy());
606 610 m_direction = (m_direction + dir) / 2;
607 QPainterPath lensDeform(QPainterPath source, QPointF offset) 611 }
608 { 612 m_pos = epos + m_offset;
609 auto path = new QPainterPath; 613
610 path.addPath(source); 614 void noGLUpdate()
611 615 {
612 qreal flip = m_intensity / 100.0; 616 QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
613 617 update(rectBefore.united(rectAfter));
614 for (int i=0; i<path.elementCount; ++i) { 618 }
615 auto e = path.elementAt(i); 619
616 620 version (QT_OPENGL_SUPPORT)
617 qreal x = e.x + offset.x(); 621 {
618 qreal y = e.y + offset.y(); 622 if (usesOpenGL()) {
619 623 update;
620 qreal dx = x - m_pos.x(); 624 } else
621 qreal dy = y - m_pos.y(); 625 noGLUpdate;
622 qreal len = m_radius - sqrt(dx * dx + dy * dy); 626 }
623 627 else
624 if (len > 0) { 628 noGLUpdate;
625 path.setElementPositionAt(i, 629 }
626 x + flip * dx * len / m_radius, 630 }
627 y + flip * dy * len / m_radius); 631
628 } else { 632 QPainterPath lensDeform(QPainterPath source, QPointF offset)
629 path.setElementPositionAt(i, x, y); 633 {
630 } 634 auto path = new QPainterPath;
631 635 path.addPath(source);
632 } 636
633 637 qreal flip = m_intensity / 100.0;
634 return path; 638
635 } 639 for (int i=0; i<path.elementCount; ++i)
636 640 {
637 641 auto e = path.elementAt(i);
638 override void paint(QPainter painter) 642
639 { 643 qreal x = e.x + offset.x();
640 int pad_x = 5; 644 qreal y = e.y + offset.y();
641 int pad_y = 5; 645
642 646 qreal dx = x - m_pos.x();
643 int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2); 647 qreal dy = y - m_pos.y();
644 int skip_y = qRound(m_pathBounds.height() + pad_y); 648 qreal len = m_radius - sqrt(dx * dx + dy * dy);
645 649
646 painter.setPen(Qt.NoPen); 650 if (len > 0) {
647 painter.setBrush(new QColor(Qt.black)); 651 path.setElementPositionAt(i,
648 652 x + flip * dx * len / m_radius,
649 auto clip = painter.clipPath().boundingRect(); 653 y + flip * dy * len / m_radius);
650 654 } else {
651 int overlap = pad_x / 2; 655 path.setElementPositionAt(i, x, y);
652 656 }
653 for (int start_y=0; start_y < height(); start_y += skip_y) { 657 }
654 658
655 if (start_y > clip.bottom()) 659 return path;
656 break; 660 }
657 661
658 int start_x = -overlap; 662 override void paint(QPainter painter)
659 for (; start_x < width(); start_x += skip_x) { 663 {
660 664 int pad_x = 5;
661 if (start_y + skip_y >= clip.top() && 665 int pad_y = 5;
662 start_x + skip_x >= clip.left() && 666
663 start_x <= clip.right()) { 667 int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
664 for (int i=0; i<m_paths.length; ++i) { 668 int skip_y = qRound(m_pathBounds.height() + pad_y);
665 QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y)); 669
666 painter.drawPath(path); 670 painter.setPen(Qt.NoPen);
667 } 671 painter.setBrush(new QColor(Qt.black));
668 } 672
669 } 673 auto clip = painter.clipPath().boundingRect();
670 overlap = skip_x - (start_x - width()); 674
671 675 int overlap = pad_x / 2;
672 } 676
673 677 for (int start_y=0; start_y < height(); start_y += skip_y)
674 if (preferImage) { 678 {
675 painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), 679 if (start_y > clip.bottom())
676 m_lens_image); 680 break;
677 } else { 681
678 painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), 682 int start_x = -overlap;
679 m_lens_pixmap); 683 for (; start_x < width(); start_x += skip_x)
680 } 684 {
681 } 685 if (start_y + skip_y >= clip.top() &&
682 686 start_x + skip_x >= clip.left() &&
683 687 start_x <= clip.right())
684 void setRadius(int radius) 688 {
685 { 689 for (int i=0; i<m_paths.length; ++i) {
686 qreal max = max(m_radius, cast(qreal)radius); 690 QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
687 m_radius = radius; 691 painter.drawPath(path);
688 generateLensPixmap(); 692 }
689 if (!m_animated || m_radius < max) { 693 }
690 694 }
691 auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); }; 695 overlap = skip_x - (start_x - width());
692 696 }
693 version (QT_OPENGL_SUPPORT) 697
694 { 698 if (preferImage) {
695 if (usesOpenGL()) 699 painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_image);
696 update(); 700 } else {
697 else 701 painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_pixmap);
698 noGLUpdate(); 702 }
699 } 703 }
700 else 704
701 noGLUpdate(); 705 void setRadius(int radius)
702 } 706 {
703 } 707 qreal max = max(m_radius, cast(qreal)radius);
704 708 m_radius = radius;
705 void setIntensity(int intensity) 709 generateLensPixmap();
706 { 710 if (!m_animated || m_radius < max)
707 m_intensity = intensity; 711 {
708 if (!m_animated) { 712 auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); };
709 713
710 auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); }; 714 version (QT_OPENGL_SUPPORT)
711 715 {
712 version (QT_OPENGL_SUPPORT) 716 if (usesOpenGL())
713 { 717 update();
714 718 else
715 719 noGLUpdate();
716 if (usesOpenGL()) { 720 }
717 update(); 721 else
718 } else 722 noGLUpdate();
719 noGLUpdate(); 723 }
720 } 724 }
721 else 725
722 noGLUpdate(); 726 void setIntensity(int intensity)
723 } 727 {
724 } 728 m_intensity = intensity;
729 if (!m_animated)
730 {
731 auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); };
732
733 version (QT_OPENGL_SUPPORT)
734 {
735 if (usesOpenGL()) {
736 update();
737 } else
738 noGLUpdate();
739 }
740 else
741 noGLUpdate();
742 }
743 }
725 } 744 }