Mercurial > projects > qtd
comparison demos/shared/arthurwidgets.d @ 41:691e68637348
non-working deform example
author | maxter |
---|---|
date | Sun, 17 May 2009 12:41:14 +0000 |
parents | |
children | 4bbd9f3d9add |
comparison
equal
deleted
inserted
replaced
40:a5cc4ada07f5 | 41:691e68637348 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | |
4 ** Contact: Qt Software Information (qt-info@nokia.com) | |
5 ** | |
6 ** This file is part of the demonstration applications of the Qt Toolkit. | |
7 ** | |
8 ** $QT_BEGIN_LICENSE:LGPL$ | |
9 ** Commercial Usage | |
10 ** Licensees holding valid Qt Commercial licenses may use this file in | |
11 ** accordance with the Qt Commercial License Agreement provided with the | |
12 ** Software or, alternatively, in accordance with the terms contained in | |
13 ** a written agreement between you and Nokia. | |
14 ** | |
15 ** GNU Lesser General Public License Usage | |
16 ** Alternatively, this file may be used under the terms of the GNU Lesser | |
17 ** General Public License version 2.1 as published by the Free Software | |
18 ** Foundation and appearing in the file LICENSE.LGPL included in the | |
19 ** packaging of this file. Please review the following information to | |
20 ** ensure the GNU Lesser General Public License version 2.1 requirements | |
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
22 ** | |
23 ** In addition, as a special exception, Nokia gives you certain | |
24 ** additional rights. These rights are described in the Nokia Qt LGPL | |
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this | |
26 ** package. | |
27 ** | |
28 ** GNU General Public License Usage | |
29 ** Alternatively, this file may be used under the terms of the GNU | |
30 ** General Public License version 3.0 as published by the Free Software | |
31 ** Foundation and appearing in the file LICENSE.GPL included in the | |
32 ** packaging of this file. Please review the following information to | |
33 ** ensure the GNU General Public License version 3.0 requirements will be | |
34 ** met: http://www.gnu.org/copyleft/gpl.html. | |
35 ** | |
36 ** If you are unsure which license is appropriate for your use, please | |
37 ** contact the sales department at qt-sales@nokia.com. | |
38 ** $QT_END_LICENSE$ | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 | |
43 import qt.core.QFile, | |
44 qt.gui.QApplication, | |
45 qt.gui.QPainter, | |
46 qt.gui.QPainterPath, | |
47 qt.gui.QPixmapCache, | |
48 qt.gui.QTextDocument, | |
49 qt.gui.QAbstractTextDocumentLayout, | |
50 qt.gui.QLinearGradient, | |
51 | |
52 qt.gui.QTextBrowser, | |
53 qt.gui.QBoxLayout, | |
54 qt.opengl.QGL, | |
55 qt.Signal, | |
56 tango.text.Util; | |
57 | |
58 import tango.text.Regex : Regex; | |
59 | |
60 //#include <private/qpixmapdata_p.h> | |
61 | |
62 //extern QPixmap cached(const QString &img); | |
63 | |
64 version (QT_OPENGL_SUPPORT) | |
65 { | |
66 import qt.opengl.QGLWidget; | |
67 class GLWidget : QGLWidget | |
68 { | |
69 this(QWidget parent) | |
70 { | |
71 super(new QGLFormat(QGL.SampleBuffers), parent); | |
72 } | |
73 | |
74 void disableAutoBufferSwap() { setAutoBufferSwap(false); } | |
75 override void paintEvent(QPaintEvent) { parentWidget().update(); } | |
76 } | |
77 } | |
78 | |
79 class ArthurFrame : QWidget | |
80 { | |
81 protected: | |
82 | |
83 version(QT_OPENGL_SUPPORT) | |
84 { | |
85 GLWidget glw; | |
86 bool m_use_opengl; | |
87 } | |
88 | |
89 QPixmap m_tile; | |
90 | |
91 bool m_show_doc; | |
92 bool m_prefer_image; | |
93 QTextDocument m_document; | |
94 | |
95 string m_sourceFileName; | |
96 | |
97 public: | |
98 mixin Signal!("descriptionEnabledChanged", bool); | |
99 | |
100 bool preferImage() { return m_prefer_image; } | |
101 | |
102 void paint(QPainter) {} | |
103 | |
104 this(QWidget parent) | |
105 { | |
106 super(parent); | |
107 | |
108 version (QT_OPENGL_SUPPORT) | |
109 { | |
110 QGLFormat f = QGLFormat.defaultFormat(); | |
111 f.setSampleBuffers(true); | |
112 f.setStencil(true); | |
113 f.setAlpha(true); | |
114 f.setAlphaBufferSize(8); | |
115 QGLFormat.setDefaultFormat(f); | |
116 } | |
117 | |
118 m_tile = new QPixmap(128, 128); | |
119 m_tile.fill(new QColor(Qt.white)); | |
120 scope pt = new QPainter(m_tile); | |
121 auto color = new QColor(230, 230, 230); | |
122 pt.fillRect(0, 0, 64, 64, color); | |
123 pt.fillRect(64, 64, 64, 64, color); | |
124 pt.end(); | |
125 | |
126 // QPalette pal = palette(); | |
127 // pal.setBrush(backgroundRole(), m_tile); | |
128 // setPalette(pal); | |
129 | |
130 version (Q_WS_X11) | |
131 { | |
132 auto xRenderPixmap = new QPixmap(1, 1); | |
133 m_prefer_image = xRenderPixmap.pixmapData().classId() == QPixmapData.X11Class && !xRenderPixmap.x11PictureHandle(); | |
134 } | |
135 } | |
136 | |
137 version (QT_OPENGL_SUPPORT) | |
138 { | |
139 void enableOpenGL(bool use_opengl) | |
140 { | |
141 m_use_opengl = use_opengl; | |
142 | |
143 if (!glw) { | |
144 glw = new GLWidget(this); | |
145 glw.setAutoFillBackground(false); | |
146 glw.disableAutoBufferSwap(); | |
147 QApplication.postEvent(this, new QResizeEvent(size(), size())); | |
148 } | |
149 | |
150 if (use_opengl) { | |
151 glw.show(); | |
152 } else { | |
153 glw.hide(); | |
154 } | |
155 | |
156 update(); | |
157 } | |
158 | |
159 bool usesOpenGL() { return m_use_opengl; } | |
160 QGLWidget glWidget(){ return glw; } | |
161 } | |
162 | |
163 override void paintEvent(QPaintEvent e) | |
164 { | |
165 version (Q_WS_QWS) | |
166 static QPixmap static_image; | |
167 else | |
168 static QImage static_image; | |
169 | |
170 auto painter = new QPainter; | |
171 | |
172 version (QT_OPENGL_SUPPORT) | |
173 auto prefImage = preferImage && !m_use_opengl; | |
174 else | |
175 auto prefImage = preferImage; | |
176 | |
177 if (prefImage) { | |
178 if (!static_image || static_image.size() != size()) { | |
179 delete static_image; | |
180 version (Q_WS_QWS) | |
181 static_image = new QPixmap(size()); | |
182 else | |
183 static_image = new QImage(size(), QImage.Format_RGB32); | |
184 } | |
185 painter.begin(static_image); | |
186 | |
187 int o = 10; | |
188 | |
189 QBrush bg = palette().brush(QPalette.Window); | |
190 painter.fillRect(0, 0, o, o, bg); | |
191 painter.fillRect(width() - o, 0, o, o, bg); | |
192 painter.fillRect(0, height() - o, o, o, bg); | |
193 painter.fillRect(width() - o, height() - o, o, o, bg); | |
194 } else { | |
195 version (QT_OPENGL_SUPPORT) | |
196 { | |
197 if (m_use_opengl) { | |
198 painter.begin(glw); | |
199 painter.fillRect(new QRectF(0, 0, glw.width(), glw.height()), palette().color(backgroundRole())); | |
200 } else { | |
201 painter.begin(this); | |
202 } | |
203 } | |
204 else | |
205 painter.begin(this); | |
206 } | |
207 | |
208 painter.setClipRect(e.rect()); | |
209 | |
210 painter.setRenderHint(QPainter.Antialiasing); | |
211 | |
212 auto clipPath = new QPainterPath; | |
213 | |
214 QRect r = rect(); | |
215 qreal left = r.x() + 1; | |
216 qreal top = r.y() + 1; | |
217 qreal right = r.right(); | |
218 qreal bottom = r.bottom(); | |
219 qreal radius2 = 8 * 2; | |
220 | |
221 clipPath.moveTo(right - radius2, top); | |
222 clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90); | |
223 clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90); | |
224 clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90); | |
225 clipPath.arcTo(left, top, radius2, radius2, 180, -90); | |
226 clipPath.closeSubpath(); | |
227 | |
228 painter.save(); | |
229 painter.setClipPath(clipPath, Qt.IntersectClip); | |
230 | |
231 painter.drawTiledPixmap(rect(), m_tile); | |
232 | |
233 // client painting | |
234 | |
235 paint(painter); | |
236 painter.restore(); | |
237 | |
238 painter.save(); | |
239 if (m_show_doc) | |
240 paintDescription(painter); | |
241 painter.restore(); | |
242 | |
243 int level = 180; | |
244 painter.setPen(new QPen(new QBrush(new QColor(level, level, level)), 2)); | |
245 painter.setBrush(Qt.NoBrush); | |
246 painter.drawPath(clipPath); | |
247 | |
248 if (prefImage) { | |
249 painter.end(); | |
250 painter.begin(this); | |
251 version (Q_WS_QWS) | |
252 painter.drawPixmap(e.rect(), static_image, e.rect()); | |
253 else | |
254 painter.drawImage(e.rect(), static_image, e.rect()); | |
255 } | |
256 | |
257 // TODO: this sucks | |
258 version (QT_OPENGL_SUPPORT) { | |
259 if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc)) | |
260 glw.swapBuffers(); | |
261 } | |
262 } | |
263 | |
264 void resizeEvent(QResizeEvent e) | |
265 { | |
266 version (QT_OPENGL_SUPPORT) | |
267 { | |
268 if (glw) | |
269 glw.setGeometry(0, 0, e.size().width()-1, e.size().height()-1); | |
270 } | |
271 super.resizeEvent(e); | |
272 } | |
273 | |
274 void setDescriptionEnabled(bool enabled) | |
275 { | |
276 if (m_show_doc != enabled) { | |
277 m_show_doc = enabled; | |
278 descriptionEnabledChanged.emit(m_show_doc); | |
279 update(); | |
280 } | |
281 } | |
282 | |
283 void loadDescription(string fileName) | |
284 { | |
285 auto textFile = new QFile(fileName); | |
286 string text; | |
287 if (!textFile.open(QFile.ReadOnly)) | |
288 text = "Unable to load resource file: " ~ fileName; | |
289 else | |
290 text = textFile.readAll().toString; // TODO: excessive copying | |
291 setDescription(text); | |
292 } | |
293 | |
294 void setDescription(string text) | |
295 { | |
296 m_document = new QTextDocument(this); | |
297 m_document.setHtml(text); | |
298 } | |
299 | |
300 void paintDescription(QPainter painter) | |
301 { | |
302 if (!m_document) | |
303 return; | |
304 | |
305 int pageWidth = qMax(width() - 100, 100); | |
306 int pageHeight = qMax(height() - 100, 100); | |
307 if (pageWidth != m_document.pageSize().width()) { | |
308 m_document.setPageSize(QSizeF(pageWidth, pageHeight)); | |
309 } | |
310 | |
311 auto textRect = new QRect(width() / 2 - pageWidth / 2, | |
312 height() / 2 - pageHeight / 2, | |
313 pageWidth, | |
314 pageHeight); | |
315 int pad = 10; | |
316 QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad); | |
317 painter.setPen(Qt.NoPen); | |
318 painter.setBrush(new QColor(0, 0, 0, 63)); | |
319 int shade = 10; | |
320 painter.drawRect(clearRect.x() + clearRect.width() + 1, | |
321 clearRect.y() + shade, | |
322 shade, | |
323 clearRect.height() + 1); | |
324 painter.drawRect(clearRect.x() + shade, | |
325 clearRect.y() + clearRect.height() + 1, | |
326 clearRect.width() - shade + 1, | |
327 shade); | |
328 | |
329 painter.setRenderHint(QPainter.Antialiasing, false); | |
330 painter.setBrush(new QColor(255, 255, 255, 220)); | |
331 painter.setPen(new QColor(Qt.black)); | |
332 painter.drawRect(clearRect); | |
333 | |
334 painter.setClipRect(textRect, Qt.IntersectClip); | |
335 painter.translate(textRect.topLeft()); | |
336 | |
337 auto ctx = new QAbstractTextDocumentLayout_PaintContext; | |
338 | |
339 auto g = new QLinearGradient(0, 0, 0, textRect.height()); | |
340 g.setColorAt(0, new QColor(Qt.black)); | |
341 g.setColorAt(0.9, new QColor(Qt.black)); | |
342 g.setColorAt(1, new QColor(Qt.transparent)); | |
343 | |
344 QPalette pal = palette(); | |
345 pal.setBrush(QPalette.Text, new QBrush(g)); | |
346 | |
347 ctx.setPalette(pal); | |
348 ctx.setClip(new QRectF(0, 0, textRect.width(), textRect.height())); | |
349 m_document.documentLayout().draw(painter, ctx); | |
350 } | |
351 | |
352 void loadSourceFile(string sourceName) | |
353 { | |
354 m_sourceFileName = sourceName; | |
355 } | |
356 | |
357 void showSource() | |
358 { | |
359 // Check for existing source | |
360 if (findChild!(QTextBrowser)) | |
361 return; | |
362 | |
363 string contents; | |
364 if (!m_sourceFileName.length) { | |
365 contents = "No source for widget: " ~ objectName(); | |
366 } else { | |
367 auto f = new QFile(m_sourceFileName); | |
368 if (!f.open(QFile.ReadOnly)) | |
369 contents = "Could not open file: " ~ m_sourceFileName; | |
370 else | |
371 contents = f.readAll.toString; | |
372 } | |
373 | |
374 contents = contents.substitute("&", "&"); | |
375 contents = contents.substitute("<", "<"); | |
376 contents = contents.substitute(">", ">"); | |
377 | |
378 static const string[] keywords = | |
379 ["for ", "if ", "switch ", " int ", "#include ", "const" | |
380 , "void ", "uint ", "case ", "double ", "#define ", "static" | |
381 , "new", "this"]; | |
382 | |
383 foreach (keyword; keywords) | |
384 contents = contents.substitute(keyword, "<font color=olive>" ~ keyword ~ "</font>"); | |
385 contents = contents.substitute("(int ", "(<font color=olive><b>int </b></font>"); | |
386 | |
387 static const string[] ppKeywords = | |
388 ["#ifdef", "#ifndef", "#if", "#endif", "#else"]; | |
389 | |
390 foreach (keyword; ppKeywords) | |
391 contents = contents.substitute(keyword, "<font color=navy>" ~ keyword ~ "</font>"); | |
392 | |
393 auto ddRe = new Regex("(\\d\\d?)"); | |
394 contents = ddRe.replaceAll(contents, "<font color=navy>\\1</font>"); | |
395 | |
396 auto commentRe = new Regex("(//.+?)\\n"); | |
397 contents = commentRe.replaceAll(contents, "<font color=red>\\1</font>\n"); | |
398 | |
399 auto stringLiteralRe = new Regex("(\".+?\")"); | |
400 contents = stringLiteralRe.replaceAll(contents, "<font color=green>\\1</font>"); | |
401 | |
402 auto html = contents.dup; | |
403 html = "<html><pre>" ~ html ~ "</pre></html>"; | |
404 | |
405 QTextBrowser sourceViewer = new QTextBrowser(null); | |
406 sourceViewer.setWindowTitle("Source: " ~ m_sourceFileName[5..$]); | |
407 sourceViewer.setParent(this, Qt.Dialog); | |
408 sourceViewer.setAttribute(Qt.WA_DeleteOnClose); | |
409 sourceViewer.setLineWrapMode(QTextEdit.NoWrap); | |
410 sourceViewer.setHtml(html); | |
411 sourceViewer.resize(600, 600); | |
412 sourceViewer.show(); | |
413 } | |
414 } |