diff options
Diffstat (limited to 'basicsuite/webengine')
36 files changed, 1462 insertions, 188 deletions
diff --git a/basicsuite/webengine/ErrorPage.qml b/basicsuite/webengine/ErrorPage.qml new file mode 100644 index 0000000..daa25d0 --- /dev/null +++ b/basicsuite/webengine/ErrorPage.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.1 + +Rectangle { + id: errorPage + property alias mainMessage: errorMessage.text; + property bool displayingError: false; + anchors.fill: parent + color: "lightgray" + visible: displayingError + + Rectangle { + color: "white" + anchors.centerIn: parent + height: parent.height / 3 + width: Math.max(parent.width / 2, errorMessage.width + 20) + + border { + color: "dimgray" + width: 0.5 + } + + radius: 20 + Text { + id: errorMessage + color: "dimgray" + font.pixelSize: 20 + anchors.centerIn: parent + } + } + +} diff --git a/basicsuite/webengine/content/index.html b/basicsuite/webengine/content/index.html new file mode 100644 index 0000000..3cbeb16 --- /dev/null +++ b/basicsuite/webengine/content/index.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset=utf-8 /> + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + <title>Qt WebEngine Demo</title> + <style> + a, a:link, a:active, a:visited { + text-decoration:none; + font-family: "Helvetica"; + font-size: 18px; + color: rgb(0,0,0) + } + .bookmark { + margin: 28px; + } + .example { + display: inline-block; + } + .example_image { + width: 300px; + height: 175px; + } + </style> + </head> + <body bgcolor="#AAAAAA"> + <div style="text-align: center; padding-top: 100px;"> + <div class="bookmark"><a href="http://qt.digia.com">http://qt.digia.com</a></div> + <div class="bookmark"><a href="http://qt-project.org/doc/qt-5">http://qt-project.org/doc/qt-5</a></div> + <div class="bookmark"><a href="http://www.google.com">http://www.google.com</a></div> + <div class="example"><a href="../content/webgl/helloqt.html"><img class="example_image" src="../content/webgl/screenshot.png"></a></div> + <div class="example"><a href="../content/csstetrahedron/index.html"><img class="example_image" src="../content/csstetrahedron/screenshot.png"></a></div> + <div class="example"><a href="../content/rubiks/index.html"><img class="example_image" src="../content/rubiks/screenshot.png"></a></div> + <div class="example"><a href="../content/morphingcubes/index.html"><img class="example_image" src="../content/morphingcubes/screenshot.png"></a></div> + </div> + </body> +</html> diff --git a/basicsuite/webengine/content/morphingcubes/index.html b/basicsuite/webengine/content/morphingcubes/index.html new file mode 100644 index 0000000..a5731f1 --- /dev/null +++ b/basicsuite/webengine/content/morphingcubes/index.html @@ -0,0 +1,286 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> + <title>Morphing Power Cubes</title> + <style type="text/css" media="screen"> + body { + background-color: black; + color: white; + font-family: 'Lucida Grande', Verdana, Arial; + font-size: 12px; + background-image: -webkit-gradient(radial, + 50% 500, 1, + 50% 500, 400, + from(rgba(255, 255, 255, 0.3)), + to(rgba(255, 255, 255, 0))); + background-repeat: no-repeat; + } + + #container { + width: 100%; + height: 700px; + -webkit-perspective: 800; /* For compatibility with iPhone 3.0, we leave off the units here */ + -webkit-perspective-origin: 50% 225px; + } + #stage { + width: 100%; + height: 100%; + -webkit-transition: -webkit-transform 2s; + -webkit-transform-style: preserve-3d; + } + + #shape { + position: relative; + top: 160px; + margin: 0 auto; + height: 200px; + width: 200px; + -webkit-transform-style: preserve-3d; + } + + .plane { + position: absolute; + height: 200px; + width: 200px; + border: 1px solid white; + -webkit-border-radius: 12px; + -webkit-box-sizing: border-box; + text-align: center; + font-family: Times, serif; + font-size: 124pt; + color: black; + background-color: rgba(255, 255, 255, 0.6); + -webkit-transition: -webkit-transform 2s, opacity 2s; + -webkit-backface-visibility: hidden; + } + + #shape.backfaces .plane { + -webkit-backface-visibility: visible; + } + + #shape { + -webkit-animation: spin 8s infinite linear; + } + + @-webkit-keyframes spin { + from { -webkit-transform: rotateY(0); } + to { -webkit-transform: rotateY(-360deg); } + } + + /* ---------- cube styles ------------- */ + .cube > .one { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) rotateX(90deg) translateZ(100px); + } + + .cube > .two { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) translateZ(100px); + } + + .cube > .three { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) rotateY(90deg) translateZ(100px); + } + + .cube > .four { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) rotateY(180deg) translateZ(100px); + } + + .cube > .five { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) rotateY(-90deg) translateZ(100px); + } + + .cube > .six { + opacity: 0.5; + -webkit-transform: scale3d(1.2, 1.2, 1.2) rotateX(-90deg) translateZ(100px) rotate(180deg); + } + + + .cube > .seven { + -webkit-transform: scale3d(0.8, 0.8, 0.8) rotateX(90deg) translateZ(100px) rotate(180deg); + } + + .cube > .eight { + -webkit-transform: scale3d(0.8, 0.8, 0.8) translateZ(100px); + } + + .cube > .nine { + -webkit-transform: scale3d(0.8, 0.8, 0.8) rotateY(90deg) translateZ(100px); + } + + .cube > .ten { + -webkit-transform: scale3d(0.8, 0.8, 0.8) rotateY(180deg) translateZ(100px); + } + + .cube > .eleven { + -webkit-transform: scale3d(0.8, 0.8, 0.8) rotateY(-90deg) translateZ(100px); + } + + .cube > .twelve { + -webkit-transform: scale3d(0.8, 0.8, 0.8) rotateX(-90deg) translateZ(100px); + } + + /* ---------- ring styles ------------- */ + .ring > .one { + -webkit-transform: translateZ(380px); + } + + .ring > .two { + -webkit-transform: rotateY(30deg) translateZ(380px); + } + + .ring > .three { + -webkit-transform: rotateY(60deg) translateZ(380px); + } + + .ring > .four { + -webkit-transform: rotateY(90deg) translateZ(380px); + } + + .ring > .five { + -webkit-transform: rotateY(120deg) translateZ(380px); + } + + .ring > .six { + -webkit-transform: rotateY(150deg) translateZ(380px); + } + + .ring > .seven { + -webkit-transform: rotateY(180deg) translateZ(380px); + } + + .ring > .eight { + -webkit-transform: rotateY(210deg) translateZ(380px); + } + + .ring > .nine { + -webkit-transform: rotateY(-120deg) translateZ(380px); + } + + .ring > .ten { + -webkit-transform: rotateY(-90deg) translateZ(380px); + } + + .ring > .eleven { + -webkit-transform: rotateY(300deg) translateZ(380px); + } + + .ring > .twelve { + -webkit-transform: rotateY(330deg) translateZ(380px); + } + + .controls { + width: 80%; + margin: 0 auto; + padding: 5px 20px; + -webkit-border-radius: 12px; + background-color: rgba(255, 255, 255, 0.5); + } + .controls > div { + margin: 10px; + } + </style> + <script type="text/javascript" charset="utf-8"> + function hasClassName(inElement, inClassName) + { + var regExp = new RegExp('(?:^|\\s+)' + inClassName + '(?:\\s+|$)'); + return regExp.test(inElement.className); + } + + function addClassName(inElement, inClassName) + { + if (!hasClassName(inElement, inClassName)) + inElement.className = [inElement.className, inClassName].join(' '); + } + + function removeClassName(inElement, inClassName) + { + if (hasClassName(inElement, inClassName)) { + var regExp = new RegExp('(?:^|\\s+)' + inClassName + '(?:\\s+|$)', 'g'); + var curClasses = inElement.className; + inElement.className = curClasses.replace(regExp, ' '); + } + } + + function toggleClassName(inElement, inClassName) + { + if (hasClassName(inElement, inClassName)) + removeClassName(inElement, inClassName); + else + addClassName(inElement, inClassName); + } + function toggleShape() + { + var shape = document.getElementById('shape'); + if (hasClassName(shape, 'ring')) { + removeClassName(shape, 'ring'); + addClassName(shape, 'cube'); + } else { + removeClassName(shape, 'cube'); + addClassName(shape, 'ring'); + } + // Move the ring back in Z so it's not so in-your-face. + var stage = document.getElementById('stage'); + if (hasClassName(shape, 'ring')) + stage.style.webkitTransform = 'translateZ(-200px)'; + else + stage.style.webkitTransform = ''; + } + function toggleBackfaces() + { + var backfacesVisible = document.getElementById('backfaces').checked; + var shape = document.getElementById('shape'); + if (backfacesVisible) + addClassName(shape, 'backfaces'); + else + removeClassName(shape, 'backfaces'); + } + </script> +</head> +<body> + + <div class="controls"> + <h1>Animations, Transitions and 3D Transforms</h1> + <p>This demo shows some more interesting content using 3D transforms, animations and transitions. + Note that you can still select the text on the the elements, even while they are rotating. Transforms elements remain + fully interactive.</p> + <p>Click Toggle Shape to switch between nested cubes and one big ring. Note how the planes move smoothly to their new locations, + even while the whole shape is rotating. You can even interrupt this transition by clicking again, and they move back smoothly.</p> + <p>Toggle the Backfaces Visible checkbox to turn backfaces on and off using <code>-webkit-backface-visibility</code>.</p> + <div><button onclick="toggleShape()">Toggle Shape</button></div> + <div><input type="checkbox" id="backfaces" onclick="toggleBackfaces()" checked><label for="backfaces">Backfaces visible</label></div> + </div> + + <div id="container"> + <div id="stage"> + <div id="shape" class="cube backfaces"> + <div class="plane one">1</div> + <div class="plane two">2</div> + <div class="plane three">3</div> + <div class="plane four">4</div> + <div class="plane five">5</div> + <div class="plane six">6</div> + <div class="plane seven">7</div> + <div class="plane eight">8</div> + <div class="plane nine">9</div> + <div class="plane ten">10</div> + <div class="plane eleven">11</div> + <div class="plane twelve">12</div> + </div> + </div> + </div> + <div id="footer"></div> + <script language="javascript"> + var container = document.getElementById("footer"); + container.innerHTML = "<div style=\"font-family: monospace; font-size: 15px; margin: 0px auto 0px; padding: 2em; width: 600px; " + + "height 100px; text-align: center; color: black; background-color: rgb(238, 238, 238);\">" + navigator.userAgent + "</div>"; + </script> +</body> +</html> diff --git a/basicsuite/webengine/content/morphingcubes/screenshot.png b/basicsuite/webengine/content/morphingcubes/screenshot.png Binary files differnew file mode 100644 index 0000000..9d36114 --- /dev/null +++ b/basicsuite/webengine/content/morphingcubes/screenshot.png diff --git a/basicsuite/webengine/content/rubiks/css/style.css b/basicsuite/webengine/content/rubiks/css/style.css new file mode 100644 index 0000000..a636bb0 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/css/style.css @@ -0,0 +1,36 @@ +html, body { + height: 100%; + margin: 0px; +} + +body { + background-color: #000; + color: white; + text-shadow: 0px 1px 1px black; + text-align: center; + font-family: sans-serif; +} + +h1 { + text-align: center; + margin-top: 0px; + padding-top: 1em; +} + +footer { + position: fixed; + text-align: center; + width: 100%; + left: 0px; + bottom: 3px; + font-size: 90%; +} + +a { + color: white; +} + +.face { + border: 2px solid black; + border-radius: 10px; +} diff --git a/basicsuite/webengine/content/rubiks/index.html b/basicsuite/webengine/content/rubiks/index.html new file mode 100644 index 0000000..993b523 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/index.html @@ -0,0 +1,25 @@ +<!doctype html> +<!-- + +Copyright (c) 2012 Ondřej Žára http://ondras.zarovi.cz +This demo is released under the BSD license: +http://opensource.org/licenses/bsd-license.php + +--> + +<html> + <head> + <meta charset="utf-8" /> + <title>Rubik's cube :: CSS 3D Transformations demo</title> + <script src="js/oz.js"></script> + <script src="js/css3.oz.js"></script> + <script src="js/rubik.js"></script> + <script src="js/quaternion.js"></script> + <link rel="stylesheet" href="css/style.css" /> + <meta name="viewport" content="width=device-width" /> + <meta name="apple-mobile-web-app-capable" content="yes" /> + </head> + <body onload="new Rubik()"> + <h1>CSS 3D Rubik's cube</h1> + </body> +</html> diff --git a/basicsuite/webengine/content/rubiks/js/css3.oz.js b/basicsuite/webengine/content/rubiks/js/css3.oz.js new file mode 100644 index 0000000..d8ad6d9 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/js/css3.oz.js @@ -0,0 +1,28 @@ +OZ.CSS3 = { + getProperty: function(property) { + var prefix = this.getPrefix(this._normalize(property)); + if (prefix === null) { return null; } + return (prefix ? "-" + prefix.toLowerCase() + "-" : "") + property; + }, + set: function(node, prop, value) { + prop = this._normalize(prop); + var prefix = this.getPrefix(prop); + if (prefix === null) { return false; } + var p = (prefix ? prefix + prop.charAt(0).toUpperCase() + prop.substring(1) : prop); + node.style[p] = value; + return true; + }, + getPrefix: function(property) { + var prefixes = ["", "ms", "Webkit", "O", "Moz"]; + for (var i=0;i<prefixes.length;i++) { + var p = prefixes[i]; + var prop = (p ? p + property.charAt(0).toUpperCase() + property.substring(1) : property); + if (prop in this._node.style) { return p; } + } + return null; + }, + _normalize: function(property) { + return property.replace(/-([a-z])/g, function(match, letter) { return letter.toUpperCase(); }); + }, + _node: OZ.DOM.elm("div") +} diff --git a/basicsuite/webengine/content/rubiks/js/oz.js b/basicsuite/webengine/content/rubiks/js/oz.js new file mode 100644 index 0000000..b821c04 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/js/oz.js @@ -0,0 +1,334 @@ +/* (c) 2007 - now() Ondrej Zara, 1.7 */ +var OZ = { + $:function(x) { return typeof(x) == "string" ? document.getElementById(x) : x; }, + select: function(x) { return document.querySelectorAll(x); }, + opera:!!window.opera, + ie:!!document.attachEvent && !window.opera, + gecko:!!document.getAnonymousElementByAttribute, + webkit:!!navigator.userAgent.match(/webkit/i), + khtml:!!navigator.userAgent.match(/khtml/i) || !!navigator.userAgent.match(/konqueror/i), + Event:{ + _id:0, + _byName:{}, + _byID:{}, + add:function(elm,event,cb) { + var id = OZ.Event._id++; + var element = OZ.$(elm); + var fnc = (element && element.attachEvent ? function() { return cb.apply(element,arguments); } : cb); + var rec = [element,event,fnc]; + var parts = event.split(" "); + while (parts.length) { + var e = parts.pop(); + if (element) { + if (element.addEventListener) { + element.addEventListener(e,fnc,false); + } else if (element.attachEvent) { + element.attachEvent("on"+e,fnc); + } + } + if (!(e in OZ.Event._byName)) { OZ.Event._byName[e] = {}; } + OZ.Event._byName[e][id] = rec; + } + OZ.Event._byID[id] = rec; + return id; + }, + remove:function(id) { + var rec = OZ.Event._byID[id]; + if (!rec) { return; } + var elm = rec[0]; + var parts = rec[1].split(" "); + while (parts.length) { + var e = parts.pop(); + if (elm) { + if (elm.removeEventListener) { + elm.removeEventListener(e,rec[2],false); + } else if (elm.detachEvent) { + elm.detachEvent("on"+e,rec[2]); + } + } + delete OZ.Event._byName[e][id]; + } + delete OZ.Event._byID[id]; + }, + stop:function(e) { e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; }, + prevent:function(e) { e.preventDefault ? e.preventDefault() : e.returnValue = false; }, + target:function(e) { return e.target || e.srcElement; } + }, + Class:function() { + var c = function() { + var init = arguments.callee.prototype.init; + if (init) { init.apply(this,arguments); } + }; + c.implement = function(parent) { + for (var p in parent.prototype) { this.prototype[p] = parent.prototype[p]; } + return this; + }; + c.extend = function(parent) { + var tmp = function(){}; + tmp.prototype = parent.prototype; + this.prototype = new tmp(); + this.prototype.constructor = this; + return this; + }; + c.prototype.bind = function(fnc) { return fnc.bind(this); }; + c.prototype.dispatch = function(type, data) { + var obj = { + type:type, + target:this, + timeStamp:(new Date()).getTime(), + data:data + } + var tocall = []; + var list = OZ.Event._byName[type]; + for (var id in list) { + var item = list[id]; + if (!item[0] || item[0] == this) { tocall.push(item[2]); } + } + var len = tocall.length; + for (var i=0;i<len;i++) { tocall[i](obj); } + } + return c; + }, + DOM:{ + elm:function(name, opts) { + var elm = document.createElement(name); + for (var p in opts) { + var val = opts[p]; + if (p == "class") { p = "className"; } + if (p in elm) { elm[p] = val; } + } + OZ.Style.set(elm, opts); + return elm; + }, + text:function(str) { return document.createTextNode(str); }, + clear:function(node) { while (node.firstChild) {node.removeChild(node.firstChild);} }, + pos:function(elm) { /* relative to _viewport_ */ + var cur = OZ.$(elm); + var html = cur.ownerDocument.documentElement; + var parent = cur.parentNode; + var x = y = 0; + if (cur == html) { return [x,y]; } + while (1) { + if (OZ.Style.get(cur,"position") == "fixed") { + x += cur.offsetLeft; + y += cur.offsetTop; + return [x,y]; + } + + if (OZ.opera && (parent == html || OZ.Style.get(cur,"display") != "block")) { } else { + x -= parent.scrollLeft; + y -= parent.scrollTop; + } + if (parent == cur.offsetParent || cur.parentNode == html) { + x += cur.offsetLeft; + y += cur.offsetTop; + cur = parent; + } + + if (parent == html) { return [x,y]; } + parent = parent.parentNode; + } + }, + scroll:function() { + var x = document.documentElement.scrollLeft || document.body.scrollLeft || 0; + var y = document.documentElement.scrollTop || document.body.scrollTop || 0; + return [x,y]; + }, + win:function(avail) { + return (avail ? [window.innerWidth,window.innerHeight] : [document.documentElement.clientWidth,document.documentElement.clientHeight]); + }, + hasClass:function(node, className) { + var cn = OZ.$(node).className; + var arr = (cn ? cn.split(" ") : []); + return (arr.indexOf(className) != -1); + }, + addClass:function(node,className) { + if (OZ.DOM.hasClass(node, className)) { return; } + var cn = OZ.$(node).className; + var arr = (cn ? cn.split(" ") : []); + arr.push(className); + OZ.$(node).className = arr.join(" "); + }, + removeClass:function(node, className) { + if (!OZ.DOM.hasClass(node, className)) { return; } + var cn = OZ.$(node).className; + var arr = (cn ? cn.split(" ") : []); + var arr = arr.filter(function($){ return $ != className; }); + OZ.$(node).className = arr.join(" "); + }, + append:function() { + if (arguments.length == 1) { + var arr = arguments[0]; + var root = OZ.$(arr[0]); + for (var i=1;i<arr.length;i++) { root.appendChild(OZ.$(arr[i])); } + } else for (var i=0;i<arguments.length;i++) { OZ.DOM.append(arguments[i]); } + } + }, + Style:{ + get:function(elm, prop) { + if (document.defaultView && document.defaultView.getComputedStyle) { + try { + var cs = elm.ownerDocument.defaultView.getComputedStyle(elm,""); + } catch(e) { + return false; + } + if (!cs) { return false; } + return cs[prop]; + } else { + return elm.currentStyle[prop]; + } + }, + set:function(elm, obj) { + for (var p in obj) { + var val = obj[p]; + if (p == "opacity" && OZ.ie) { + p = "filter"; + val = "alpha(opacity="+Math.round(100*val)+")"; + elm.style.zoom = 1; + } else if (p == "float") { + p = (OZ.ie ? "styleFloat" : "cssFloat"); + } + if (p in elm.style) { elm.style[p] = val; } + } + } + }, + Request:function(url, callback, options) { + var o = {data:false, method:"get", headers:{}, xml:false} + for (var p in options) { o[p] = options[p]; } + o.method = o.method.toUpperCase(); + + var xhr = false; + if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } + else if (window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } + else { return false; } + xhr.open(o.method, url, true); + xhr.onreadystatechange = function() { + if (xhr.readyState != 4) { return; } + if (!callback) { return; } + var data = (o.xml ? xhr.responseXML : xhr.responseText); + var headers = {}; + var h = xhr.getAllResponseHeaders(); + if (h) { + h = h.split(/[\r\n]/); + for (var i=0;i<h.length;i++) if (h[i]) { + var v = h[i].match(/^([^:]+): *(.*)$/); + headers[v[1]] = v[2]; + } + } + callback(data,xhr.status,headers); + }; + if (o.method == "POST") { xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); } + for (var p in o.headers) { xhr.setRequestHeader(p,o.headers[p]); } + xhr.send(o.data || null); + return xhr; + } +} + +if (!Function.prototype.bind) { + Function.prototype.bind = function(thisObj) { + var fn = this; + var args = Array.prototype.slice.call(arguments, 1); + return function() { + return fn.apply(thisObj, args.concat(Array.prototype.slice.call(arguments))); + } + } +}; + +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(item, from) { + var len = this.length; + var i = from || 0; + if (i < 0) { i += len; } + for (;i<len;i++) { + if (i in this && this[i] === item) { return i; } + } + return -1; + } +} +if (!Array.indexOf) { + Array.indexOf = function(obj, item, from) { return Array.prototype.indexOf.call(obj, item, from); } +} + +if (!Array.prototype.lastIndexOf) { + Array.prototype.lastIndexOf = function(item, from) { + var len = this.length; + var i = from || len-1; + if (i < 0) { i += len; } + for (;i>-1;i--) { + if (i in this && this[i] === item) { return i; } + } + return -1; + } +} +if (!Array.lastIndexOf) { + Array.lastIndexOf = function(obj, item, from) { return Array.prototype.lastIndexOf.call(obj, item, from); } +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(cb, _this) { + var len = this.length; + for (var i=0;i<len;i++) { + if (i in this) { cb.call(_this, this[i], i, this); } + } + } +} +if (!Array.forEach) { + Array.forEach = function(obj, cb, _this) { Array.prototype.forEach.call(obj, cb, _this); } +} + +if (!Array.prototype.every) { + Array.prototype.every = function(cb, _this) { + var len = this.length; + for (var i=0;i<len;i++) { + if (i in this && !cb.call(_this, this[i], i, this)) { return false; } + } + return true; + } +} +if (!Array.every) { + Array.every = function(obj, cb, _this) { return Array.prototype.every.call(obj, cb, _this); } +} + +if (!Array.prototype.some) { + Array.prototype.some = function(cb, _this) { + var len = this.length; + for (var i=0;i<len;i++) { + if (i in this && cb.call(_this, this[i], i, this)) { return true; } + } + return false; + } +} +if (!Array.some) { + Array.some = function(obj, cb, _this) { return Array.prototype.some.call(obj, cb, _this); } +} + +if (!Array.prototype.map) { + Array.prototype.map = function(cb, _this) { + var len = this.length; + var res = new Array(len); + for (var i=0;i<len;i++) { + if (i in this) { res[i] = cb.call(_this, this[i], i, this); } + } + return res; + } +} +if (!Array.map) { + Array.map = function(obj, cb, _this) { return Array.prototype.map.call(obj, cb, _this); } +} + +if (!Array.prototype.filter) { + Array.prototype.filter = function(cb, _this) { + var len = this.length; + var res = []; + for (var i=0;i<len;i++) { + if (i in this) { + var val = this[i]; + if (cb.call(_this, val, i, this)) { res.push(val); } + } + } + return res; + } +} +if (!Array.filter) { + Array.filter = function(obj, cb, _this) { return Array.prototype.filter.call(obj, cb, _this); } +} diff --git a/basicsuite/webengine/content/rubiks/js/quaternion.js b/basicsuite/webengine/content/rubiks/js/quaternion.js new file mode 100644 index 0000000..a44cfea --- /dev/null +++ b/basicsuite/webengine/content/rubiks/js/quaternion.js @@ -0,0 +1,78 @@ +var Quaternion = OZ.Class(); + +Quaternion.fromRotation = function(axis, angle) { + var DEG2RAD = Math.PI/180; + var a = angle * DEG2RAD; + + var sin = Math.sin(a/2); + var cos = Math.cos(a/2); + + return new this( + axis[0]*sin, axis[1]*sin, axis[2]*sin, + cos + ); +} + +Quaternion.fromUnit = function() { + return new this(0, 0, 0, 1); +} + +Quaternion.prototype.init = function(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; +} + +Quaternion.prototype.normalize = function() { + var norm = Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w); + return new this.constructor(this.x/norm, this.y/norm, this.z/norm, this.w/norm); +} + +Quaternion.prototype.conjugate = function() { + return new this.constructor(-this.x, -this.y, -this.z, this.w); +} + +Quaternion.prototype.toString = function() { + return [this.x, this.y, this.z, this.w].toString(", "); +} + +Quaternion.prototype.multiply = function(q) { + var p = this; + + var x = p.w*q.x + p.x*q.w + p.y*q.z - p.z*q.y; + var y = p.w*q.y + p.y*q.w + p.z*q.x - p.x*q.z; + var z = p.w*q.z + p.z*q.w + p.x*q.y - p.y*q.x; + var w = p.w*q.w - p.x*q.x - p.y*q.y - p.z*q.z; + + return new this.constructor(x, y, z, w); +} + +Quaternion.prototype.toAxis = function() { + return [this.x, this.y, this.z]; +} + +Quaternion.prototype.toAngle = function() { + var RAD2DEG = 180/Math.PI; + return RAD2DEG * 2 * Math.acos(this.w); +} + +Quaternion.prototype.toRotation = function() { + var axis = this.toAxis(); + var angle = this.toAngle(); + return "rotate3d(" + axis[0].toFixed(10) + "," + axis[1].toFixed(10) + "," + axis[2].toFixed(10) + "," + angle.toFixed(10) + "deg)"; +} + +Quaternion.prototype.toRotations = function() { + var RAD2DEG = 180/Math.PI; + + var x = RAD2DEG * Math.atan2(2*(this.w*this.x + this.y*this.z), 1 - 2*(this.x*this.x + this.y*this.y)); + var y = RAD2DEG * Math.asin(2*(this.w*this.y - this.x*this.z)); + var z = RAD2DEG * Math.atan2(2*(this.w*this.z + this.x*this.y), 1 - 2*(this.y*this.y + this.z*this.z)); + + if (x < 0) { x += 360; } + if (y < 0) { y += 360; } + if (z < 0) { z += 360; } + + return "rotateX(" + x.toFixed(10) + "deg) rotateY(" + y.toFixed(10) + "deg) rotate(" + z.toFixed(10) + "deg)"; +} diff --git a/basicsuite/webengine/content/rubiks/js/rubik.js b/basicsuite/webengine/content/rubiks/js/rubik.js new file mode 100644 index 0000000..4e6cf28 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/js/rubik.js @@ -0,0 +1,492 @@ +Array.prototype.clone = function() { + var c = []; + var len = this.length; + for (var i=0;i<len;i++) { c.push(this[i]); } + return c; +} + +Array.prototype.random = function() { + return this[Math.floor(Math.random()*this.length)]; +} + +var Face = OZ.Class(); +Face.SIZE = 100; +Face.LEFT = 0; +Face.RIGHT = 1; +Face.TOP = 2; +Face.BOTTOM = 3; +Face.FRONT = 4; +Face.BACK = 5; + +Face.ROTATION = [ + [Face.TOP, Face.FRONT, Face.BOTTOM, Face.BACK].reverse(), + [Face.LEFT, Face.BACK, Face.RIGHT, Face.FRONT].reverse(), + [Face.LEFT, Face.BOTTOM, Face.RIGHT, Face.TOP].reverse() +]; + +Face.prototype.init = function(cube, type) { + this._cube = cube; + this._type = type; + this._color = null; + this._node = OZ.DOM.elm("div", {className:"face face"+type, width:Face.SIZE+"px", height:Face.SIZE+"px", position:"absolute", left:"0px", top:"0px"}); + OZ.CSS3.set(this._node, "box-sizing", "border-box"); +// OZ.CSS3.set(this._node, "backface-visibility", "hidden"); + + switch (type) { + case Face.LEFT: + OZ.CSS3.set(this._node, "transform-origin", "100% 50%"); + OZ.CSS3.set(this._node, "transform", "translate3d(-"+Face.SIZE+"px, 0px, 0px) rotateY(-90deg)"); + break; + case Face.RIGHT: + OZ.CSS3.set(this._node, "transform-origin", "0% 50%"); + OZ.CSS3.set(this._node, "transform", "translate3d("+Face.SIZE+"px, 0px, 0px) rotateY(90deg)"); + break; + case Face.TOP: + OZ.CSS3.set(this._node, "transform-origin", "50% 100%"); + OZ.CSS3.set(this._node, "transform", "translate3d(0px, -"+Face.SIZE+"px, 0px) rotateX(90deg)"); + break; + case Face.BOTTOM: + OZ.CSS3.set(this._node, "transform-origin", "50% 0%"); + OZ.CSS3.set(this._node, "transform", "translate3d(0px, "+Face.SIZE+"px, 0px) rotateX(-90deg)"); + break; + case Face.FRONT: + break; + case Face.BACK: + OZ.CSS3.set(this._node, "transform", "translate3d(0px, 0px, -"+Face.SIZE+"px) rotateY(180deg)"); + break; + } +} + +Face.prototype.getCube = function() { + return this._cube; +} + +Face.prototype.getNode = function() { + return this._node; +} + +Face.prototype.getType = function() { + return this._type; +} + +Face.prototype.setColor = function(color) { + this._color = color; + this._node.style.backgroundColor = color; +} + +Face.prototype.getColor = function() { + return this._color; +} + +var Cube = OZ.Class(); +Cube.prototype.init = function(position) { + this._rotation = null; + this._position = position; + this._node = OZ.DOM.elm("div", {className:"cube", position:"absolute", width:Face.SIZE+"px", height:Face.SIZE+"px"}); + this._faces = {}; + this._tmpFaces = {}; + OZ.CSS3.set(this._node, "transform-style", "preserve-3d"); + + this._update(); +} + +Cube.prototype.getFaces = function() { + return this._faces; +} + +Cube.prototype.setFace = function(type, color) { + if (!(type in this._faces)) { + var face = new Face(this, type); + this._node.appendChild(face.getNode()); + this._faces[type] = face; + } + this._faces[type].setColor(color); +} + +Cube.prototype.setRotation = function(rotation) { + this._rotation = rotation; + this._update(); +} + +Cube.prototype.complete = function() { + for (var i=0;i<6;i++) { + if (i in this._faces) { continue; } + this.addFace(i, "black"); + } +} + +Cube.prototype.prepareColorChange = function(sourceCube, rotation) { + this._tmpFaces = {}; + var sourceFaces = sourceCube.getFaces(); + for (var p in sourceFaces) { + var sourceType = parseInt(p); + var targetType = this._rotateType(sourceType, rotation); + this._tmpFaces[targetType] = sourceFaces[sourceType].getColor(); + } +} + +Cube.prototype.commitColorChange = function() { +// var parent = this._node.parentNode; +// parent.removeChild(this._node); + + OZ.DOM.clear(this._node); + this._faces = {}; + for (var p in this._tmpFaces) { + var type = parseInt(p); + this.setFace(type, this._tmpFaces[p]); + } + this._tmpFaces = {}; + + this._rotation = null; + this._update(); +// parent.appendChild(this._node); +} + +Cube.prototype._rotateType = function(type, rotation) { + for (var i=0;i<3;i++) { + if (!rotation[i]) { continue; } + var faces = Face.ROTATION[i]; + var index = faces.indexOf(type); + if (index == -1) { continue; } /* no rotation available */ + index = (index + rotation[i] + faces.length) % faces.length; + return faces[index]; + } + + return type; +} + +Cube.prototype._update = function() { + var transform = ""; + transform += "translate3d("+(-Face.SIZE/2)+"px, "+(-Face.SIZE/2)+"px, "+(-Face.SIZE/2)+"px) "; + if (this._rotation) { transform += this._rotation + " "; } + + var half = Math.floor(Rubik.SIZE/2); + var x = this._position[0]; + var y = this._position[1]; + var z = -this._position[2]; + x -= half; + y -= half; + z += half + 1/2; + transform += "translate3d("+(x*Face.SIZE)+"px, "+(y*Face.SIZE)+"px, "+(z*Face.SIZE)+"px)"; + + var prop = OZ.CSS3.getProperty("transform"); + var val = this._rotation ? prop + " 300ms" : ""; + OZ.CSS3.set(this._node, "transition", val); + + OZ.CSS3.set(this._node, "transform", transform); +} + +Cube.prototype.getPosition = function() { + return this._position; +} + +Cube.prototype.getNode = function() { + return this._node; +} + +Cube.prototype.getFaces = function() { + return this._faces; +} + +var Rubik = OZ.Class(); +Rubik.SIZE = 3; +Rubik.prototype.init = function() { + this._cubes = []; + this._faces = []; + this._faceNodes = []; + this._help = {}; + this._drag = { + ec: [], + mouse: [], + face: null + }; + + this._rotation = Quaternion.fromRotation([1, 0, 0], -35).multiply(Quaternion.fromRotation([0, 1, 0], 45)); + this._node = OZ.DOM.elm("div", {position:"absolute", left:"50%", top:"55%", width:"0px", height:"0px"}); + document.body.appendChild(this._node); + + OZ.CSS3.set(document.body, "perspective", "460px"); + OZ.CSS3.set(this._node, "transform-style", "preserve-3d"); + + this._build(); + this._update(); + OZ.Event.add(document.body, "mousedown touchstart", this._dragStart.bind(this)); + + setTimeout(this.randomize.bind(this), 500); +} + +Rubik.prototype.randomize = function() { + var remain = 10; + var cb = function() { + remain--; + if (remain > 0) { + this._rotateRandom(); + } else { + OZ.Event.remove(e); + + this._help.a = OZ.DOM.elm("p", {innerHTML:"Drag or swipe the background to rotate the whole cube."}); + this._help.b = OZ.DOM.elm("p", {innerHTML:"Drag or swipe the cube to rotate its layers."}); + document.body.appendChild(this._help.a); + document.body.appendChild(this._help.b); + OZ.CSS3.set(this._help.a, "transition", "opacity 500ms"); + OZ.CSS3.set(this._help.b, "transition", "opacity 500ms"); + + } + } + var e = OZ.Event.add(null, "rotated", cb.bind(this)); + this._rotateRandom(); +} + +Rubik.prototype._rotateRandom = function() { + var method = "_rotate" + ["X", "Y", "Z"].random(); + var dir = [-1, 1].random(); + var layer = Math.floor(Math.random()*Rubik.SIZE); + this[method](dir, layer); +} + +Rubik.prototype._update = function() { + OZ.CSS3.set(this._node, "transform", "translateZ(" + (-Face.SIZE/2 - Face.SIZE) + "px) " + this._rotation.toRotation() + " translateZ("+(Face.SIZE/2)+"px)"); +} + +Rubik.prototype._eventToFace = function(e) { + if (document.elementFromPoint) { + e = (e.touches ? e.touches[0] : e); + var node = document.elementFromPoint(e.clientX, e.clientY); + } else { + var node = OZ.Event.target(e); + } + var index = this._faceNodes.indexOf(node); + if (index == -1) { return null; } + return this._faces[index]; +} + +Rubik.prototype._dragStart = function(e) { + this._faces = []; + this._faceNodes = []; + for (var i=0;i<this._cubes.length;i++) { + var faces = this._cubes[i].getFaces(); + for (var p in faces) { + this._faces.push(faces[p]); + this._faceNodes.push(faces[p].getNode()); + } + } + + OZ.Event.prevent(e); + this._drag.face = this._eventToFace(e); + e = (e.touches ? e.touches[0] : e); + this._drag.mouse = [e.clientX, e.clientY]; + + this._drag.ec.push(OZ.Event.add(document.body, "mousemove touchmove", this._dragMove.bind(this))); + this._drag.ec.push(OZ.Event.add(document.body, "mouseup touchend", this._dragEnd.bind(this))); +} + +Rubik.prototype._dragMove = function(e) { + if (e.touches && e.touches.length > 1) { return; } + + if (this._drag.face) { /* check second face for rotation */ + var thisFace = this._eventToFace(e); + if (!thisFace || thisFace == this._drag.face) { return; } + this._dragEnd(); + this._rotate(this._drag.face, thisFace); + } else { /* rotate cube */ + e = (e.touches ? e.touches[0] : e); + var mouse = [e.clientX, e.clientY]; + var dx = mouse[0] - this._drag.mouse[0]; + var dy = mouse[1] - this._drag.mouse[1]; + var norm = Math.sqrt(dx*dx+dy*dy); + if (!norm) { return; } + var N = [-dy/norm, dx/norm]; + + this._drag.mouse = mouse; + this._rotation = Quaternion.fromRotation([N[0], N[1], 0], norm/2).multiply(this._rotation); + this._update(); + } +} + +Rubik.prototype._dragEnd = function(e) { + while (this._drag.ec.length) { OZ.Event.remove(this._drag.ec.pop()); } + + if (!this._drag.face && this._help.a) { + this._help.a.style.opacity = 0; + this._help.a = null; + } +} + +Rubik.prototype._rotate = function(face1, face2) { + var t1 = face1.getType(); + var t2 = face2.getType(); + var pos1 = face1.getCube().getPosition(); + var pos2 = face2.getCube().getPosition(); + + /* find difference between cubes */ + var diff = 0; + var diffIndex = -1; + for (var i=0;i<3;i++) { + var d = pos1[i]-pos2[i]; + if (d) { + if (diffIndex != -1) { return; } /* different in >1 dimensions */ + diff = (d > 0 ? 1 : -1); + diffIndex = i; + } + } + + if (t1 == t2) { /* same face => diffIndex != -1 */ + switch (t1) { + case Face.FRONT: + case Face.BACK: + var coef = (t1 == Face.FRONT ? 1 : -1); + if (diffIndex == 0) { this._rotateY(coef*diff, pos1[1]); } else { this._rotateX(coef*diff, pos1[0]); } + break; + + case Face.LEFT: + case Face.RIGHT: + var coef = (t1 == Face.LEFT ? 1 : -1); + if (diffIndex == 2) { this._rotateY(-coef*diff, pos1[1]); } else { this._rotateZ(coef*diff, pos1[2]); } + break; + + case Face.TOP: + case Face.BOTTOM: + var coef = (t1 == Face.TOP ? 1 : -1); + if (diffIndex == 0) { this._rotateZ(-coef*diff, pos1[2]); } else { this._rotateX(-coef*diff, pos1[0]); } + break; + } + return; + } + + switch (t1) { /* different face => same cube, diffIndex == 1 */ + case Face.FRONT: + case Face.BACK: + var coef = (t1 == Face.FRONT ? 1 : -1); + if (t2 == Face.LEFT) { this._rotateY(1 * coef, pos1[1]); } + if (t2 == Face.RIGHT) { this._rotateY(-1 * coef, pos1[1]); } + if (t2 == Face.TOP) { this._rotateX(1 * coef, pos1[0]); } + if (t2 == Face.BOTTOM) { this._rotateX(-1 * coef, pos1[0]); } + break; + + case Face.LEFT: + case Face.RIGHT: + var coef = (t1 == Face.LEFT ? 1 : -1); + if (t2 == Face.FRONT) { this._rotateY(-1 * coef, pos1[1]); } + if (t2 == Face.BACK) { this._rotateY(1 * coef, pos1[1]); } + if (t2 == Face.TOP) { this._rotateZ(1 * coef, pos1[2]); } + if (t2 == Face.BOTTOM) { this._rotateZ(-1 * coef, pos1[2]); } + break; + + case Face.TOP: + case Face.BOTTOM: + var coef = (t1 == Face.TOP ? 1 : -1); + if (t2 == Face.FRONT) { this._rotateX(-1 * coef, pos1[0]); } + if (t2 == Face.BACK) { this._rotateX(1 * coef, pos1[0]); } + if (t2 == Face.LEFT) { this._rotateZ(-1 * coef, pos1[2]); } + if (t2 == Face.RIGHT) { this._rotateZ(1 * coef, pos1[2]); } + break; + } + +} + +Rubik.prototype._rotateX = function(dir, layer) { + var cubes = []; + for (var i=0;i<Rubik.SIZE*Rubik.SIZE;i++) { + cubes.push(this._cubes[layer + i*Rubik.SIZE]); + } + this._rotateCubes(cubes, [dir, 0, 0]); +} + +Rubik.prototype._rotateY = function(dir, layer) { + var cubes = []; + for (var i=0;i<Rubik.SIZE;i++) { + for (var j=0;j<Rubik.SIZE;j++) { + cubes.push(this._cubes[j + layer*Rubik.SIZE + i*Rubik.SIZE*Rubik.SIZE]); + } + } + this._rotateCubes(cubes, [0, -dir, 0]); +} + +Rubik.prototype._rotateZ = function(dir, layer) { + var cubes = []; + var offset = layer * Rubik.SIZE * Rubik.SIZE; + for (var i=0;i<Rubik.SIZE*Rubik.SIZE;i++) { + cubes.push(this._cubes[offset+i]); + } + this._rotateCubes(cubes, [0, 0, dir]); +} + +Rubik.prototype._rotateCubes = function(cubes, rotation) { + var suffixes = ["X", "Y", ""]; + + var prefix = OZ.CSS3.getPrefix("transition"); + if (prefix === null) { + this._finalizeRotation(cubes, rotation); + } else { + var cb = function() { + OZ.Event.remove(e); + this._finalizeRotation(cubes, rotation); + } + var e = OZ.Event.add(document.body, "webkitTransitionEnd transitionend MSTransitionEnd oTransitionEnd", cb.bind(this)); + + var str = ""; + for (var i=0;i<3;i++) { + if (!rotation[i]) { continue; } + str = "rotate" + suffixes[i] + "(" + (90*rotation[i]) + "deg)"; + } + for (var i=0;i<cubes.length;i++) { cubes[i].setRotation(str); } + } + +} + +/** + * Remap colors + */ +Rubik.prototype._finalizeRotation = function(cubes, rotation) { + var direction = 0; + for (var i=0;i<3;i++) { + if (rotation[i]) { direction = rotation[i]; } + } + + if (rotation[0]) { direction *= -1; } /* FIXME wtf */ + + var half = Math.floor(Rubik.SIZE/2); + + for (var i=0;i<cubes.length;i++) { + var x = i % Rubik.SIZE - half; + var y = Math.floor(i / Rubik.SIZE) - half; + + var source = [y*direction + half, -x*direction + half]; + var sourceIndex = source[0] + Rubik.SIZE*source[1]; + + cubes[i].prepareColorChange(cubes[sourceIndex], rotation); + } + + for (var i=0;i<cubes.length;i++) { cubes[i].commitColorChange(); } + + setTimeout(function() { + if (this._help.b) { + this._help.b.style.opacity = 0; + this._help.b = null; + } + + this.dispatch("rotated"); + }.bind(this), 100); +} + +Rubik.prototype._build = function() { + for (var z=0;z<Rubik.SIZE;z++) { + for (var y=0;y<Rubik.SIZE;y++) { + for (var x=0;x<Rubik.SIZE;x++) { + var cube = new Cube([x, y, z]); + this._cubes.push(cube); + + if (z == 0) { cube.setFace(Face.FRONT, "red"); } + if (z == 2) { cube.setFace(Face.BACK, "blue"); } + + if (x == 0) { cube.setFace(Face.LEFT, "green"); } + if (x == 2) { cube.setFace(Face.RIGHT, "yellow"); } + + if (y == 0) { cube.setFace(Face.TOP, "cyan"); } + if (y == 2) { cube.setFace(Face.BOTTOM, "teal"); } + this._node.appendChild(cube.getNode()); + } + } + } + +} diff --git a/basicsuite/webengine/content/rubiks/screenshot.png b/basicsuite/webengine/content/rubiks/screenshot.png Binary files differnew file mode 100644 index 0000000..45b0e37 --- /dev/null +++ b/basicsuite/webengine/content/rubiks/screenshot.png diff --git a/basicsuite/webengine/description.txt b/basicsuite/webengine/description.txt index e725f8b..0a4cf41 100644 --- a/basicsuite/webengine/description.txt +++ b/basicsuite/webengine/description.txt @@ -1,3 +1,3 @@ This example demonstrates the use of the QtWebEngine WebView with Qt Quick. -Demo can be used to browse the internet (working network connection required) or run the off-line WebGL demo +Demo can be used to browse the internet (working network connection required) or run the offline web page demos. diff --git a/basicsuite/webengine/exclude.txt b/basicsuite/webengine/exclude.txt index 4ae58fb..4efe135 100644 --- a/basicsuite/webengine/exclude.txt +++ b/basicsuite/webengine/exclude.txt @@ -3,4 +3,3 @@ linux-emulator linux-raspberrypi linux-beaglebone android-beaglebone -android-nexus7v2 diff --git a/basicsuite/webengine/main.qml b/basicsuite/webengine/main.qml index 2295ea4..c8ea895 100644 --- a/basicsuite/webengine/main.qml +++ b/basicsuite/webengine/main.qml @@ -41,6 +41,7 @@ import QtQuick 2.1 import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.2 import QtQuick.Layouts 1.1 import QtWebEngine 0.9 @@ -55,28 +56,42 @@ Rectangle { width: 1280 height: 800 - property url defaultUrl: "about:blank" + property url defaultUrl: Qt.resolvedUrl("content/index.html") function load(url) { mainWebView.url = url } + ErrorPage { + id: errorPage + anchors.fill: parent + displayingError: false + } + WebEngineView { id: mainWebView anchors.fill: parent - url: Qt.resolvedUrl(defaultUrl) + url: defaultUrl + visible: !errorPage.displayingError onLoadingChanged: { if (!loading) { addressBar.cursorPosition = 0 - toolBar.state = "address" } + var loadError = loadRequest.errorDomain + if (loadError == WebEngineView.NoErrorDomain) { + errorPage.displayingError = false + return; + } + errorPage.displayingError = true + if (loadError == WebEngineView.InternalErrorDomain) + errorPage.mainMessage = "Internal error" + else if (loadError == WebEngineView.ConnectionErrorDomain) + errorPage.mainMessage = "Unable to connect to the Internet" + else if (loadError == WebEngineView.CertificateErrorDomain) + errorPage.mainMessage = "Certificate error" + else if (loadError == WebEngineView.DnsErrorDomain) + errorPage.mainMessage = "Unable to resolve the server's DNS address" + else // HTTP and FTP + errorPage.mainMessage = "Protocol error" } - } - - PageView { - id: pageView - visible: true - opacity: 1 - Behavior on opacity { - NumberAnimation { duration: 250 } - } + onActiveFocusChanged: activeFocus ? hideTimer.running = true : toolBar.state = "address" } MultiPointTouchArea { @@ -100,7 +115,7 @@ Rectangle { color: "black" opacity: 1 - height: addressBar.height + showToolBarButton.height + 50 + height: addressBar.height + showToolBarButton.height + 40 y: 0 Behavior on y { @@ -120,13 +135,13 @@ Rectangle { Timer { id: hideTimer - interval: 3000 - running: (toolBar.state == "address" || toolBar.state == "") && !addressBar.activeFocus + interval: 2000 + running: false onTriggered: { - if (toolBar.state == "address") - toolBar.state = "hidden" - if (toolBar.state == "") - toolBar.state = "address" + if (addressBar.activeFocus) + return; + toolBar.state = "hidden" + running = false } } @@ -147,54 +162,71 @@ Rectangle { RowLayout { id: addressRow - height: 65 + + Component { + id: navigationButtonStyle + ButtonStyle { + background: Rectangle { + anchors.fill: parent + color: control.pressed ? "grey" : "transparent" + radius: 5 + Image { + anchors.fill: parent + anchors.margins: 6 + source: control.icon + } + } + } + } anchors { top: parent.top bottom: showToolBarButton.top left: parent.left right: parent.right margins: 10 - topMargin: 40 + topMargin: 30 } ToolButton { id: backButton Layout.fillHeight: true - iconSource: "ui/icons/go-previous.png" + Layout.minimumWidth: height + property string icon: "ui/icons/go-previous.png" onClicked: mainWebView.goBack() enabled: mainWebView.canGoBack + style: navigationButtonStyle } ToolButton { id: forwardButton Layout.fillHeight: true - iconSource: "ui/icons/go-next.png" + Layout.minimumWidth: height + property string icon: "ui/icons/go-next.png" onClicked: mainWebView.goForward() enabled: mainWebView.canGoForward + style: navigationButtonStyle } ToolButton { id: reloadButton Layout.fillHeight: true - iconSource: mainWebView.loading ? "ui/icons/process-stop.png" : "ui/icons/view-refresh.png" + Layout.minimumWidth: height + property string icon: mainWebView.loading ? "ui/icons/process-stop.png" : "ui/icons/view-refresh.png" onClicked: mainWebView.loading ? mainWebView.stop() : mainWebView.reload() + style: navigationButtonStyle } ToolButton { id: homeButton width: 20 Layout.fillHeight: true - iconSource: pageView.enabled ? "ui/icons/window.png" : "ui/icons/home.png" - onClicked: { - if (pageView.enabled) { - pageView.hide() - } else { - pageView.show() - } - } + Layout.minimumWidth: height + property string icon: "ui/icons/home.png" + onClicked: load(defaultUrl) + style: navigationButtonStyle } TextField { id: addressBar focus: true textColor: "black" - implicitHeight: 40 - font.pointSize: 10 + implicitHeight: 50 + font.pixelSize: 25 inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoPredictiveText Image { anchors { @@ -211,7 +243,6 @@ Rectangle { Layout.fillWidth: true text: mainWebView.url onAccepted: { - pageView.hide() mainWebView.url = engine.fromUserInput(text) } } @@ -219,12 +250,16 @@ Rectangle { ToolButton { id: showToolBarButton - height: 25 - iconSource: (toolBar.state == "hidden") ? "ui/icons/down.png" : "ui/icons/up.png" + height: 30 + width: height + property string icon: (toolBar.state == "hidden") ? "ui/icons/down.png" : "ui/icons/up.png" + style: navigationButtonStyle onClicked: { - if (toolBar.state == "hidden") + if (toolBar.state == "hidden") { toolBar.state = "address" - else + addressBar.forceActiveFocus() + addressBar.selectAll() + } else toolBar.state = "hidden" } anchors { diff --git a/basicsuite/webengine/ui/PageView.qml b/basicsuite/webengine/ui/PageView.qml deleted file mode 100644 index 778fcd7..0000000 --- a/basicsuite/webengine/ui/PageView.qml +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: For any questions to Digia, please use the contact form at -** http://qt.digia.com/ -** -** This file is part of the examples of the Qt Enterprise Embedded. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.1 -import QtQuick.Layouts 1.1 - -Rectangle { - id: root - color: "#AAAAAA" - visible: true - - property real fontPointSize: 13 - - function show() { - enabled = true - opacity = 1 - } - function hide() { - enabled = false - opacity = 0 - } - anchors { - fill: parent - } - ColumnLayout { - id: links - anchors { - bottom: parent.bottom - top: parent.top - horizontalCenter: parent.horizontalCenter - margins: 50 - } - Text { - text: "http://www.google.com" - font.pointSize: fontPointSize - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: 60 - MouseArea { - anchors.fill: parent - onClicked: { - load(Qt.resolvedUrl(parent.text)) - hide() - } - } - } - Text { - text: "http://qt.digia.com" - font.pointSize: fontPointSize - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: 60 - MouseArea { - anchors.fill: parent - onClicked: { - load(Qt.resolvedUrl(parent.text)) - hide() - } - } - } - Text { - text: "http://qt-project.org/doc/qt-5" - font.pointSize: fontPointSize - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: 60 - MouseArea { - anchors.fill: parent - onClicked: { - load(Qt.resolvedUrl(parent.text)) - hide() - } - } - } - RowLayout { - id: localContent - anchors { - margins: 50 - } - Image { - sourceSize.width: 300 - sourceSize.height: 175 - source: "../content/webgl/screenshot.png" - MouseArea { - anchors.fill: parent - onClicked: { - load(Qt.resolvedUrl("../content/webgl/helloqt.html")) - hide() - } - } - } - Image { - sourceSize.width: 300 - sourceSize.height: 175 - source: "../content/csstetrahedron/screenshot.png" - MouseArea { - anchors.fill: parent - onClicked: { - load(Qt.resolvedUrl("../content/csstetrahedron/index.html")) - hide() - } - } - } - } // RowLayout - } // ColumnLayout -} diff --git a/basicsuite/webengine/ui/icons/busy.png b/basicsuite/webengine/ui/icons/busy.png Binary files differdeleted file mode 100644 index 3b60d26..0000000 --- a/basicsuite/webengine/ui/icons/busy.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/cube.png b/basicsuite/webengine/ui/icons/cube.png Binary files differdeleted file mode 100644 index a5b337b..0000000 --- a/basicsuite/webengine/ui/icons/cube.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/down.png b/basicsuite/webengine/ui/icons/down.png Binary files differindex cabd356..ec246e7 100644 --- a/basicsuite/webengine/ui/icons/down.png +++ b/basicsuite/webengine/ui/icons/down.png diff --git a/basicsuite/webengine/ui/icons/go-next.png b/basicsuite/webengine/ui/icons/go-next.png Binary files differindex c8b9b76..6ba21f8 100644 --- a/basicsuite/webengine/ui/icons/go-next.png +++ b/basicsuite/webengine/ui/icons/go-next.png diff --git a/basicsuite/webengine/ui/icons/go-previous.png b/basicsuite/webengine/ui/icons/go-previous.png Binary files differindex 7a71d7d..e0753dd 100644 --- a/basicsuite/webengine/ui/icons/go-previous.png +++ b/basicsuite/webengine/ui/icons/go-previous.png diff --git a/basicsuite/webengine/ui/icons/grid.png b/basicsuite/webengine/ui/icons/grid.png Binary files differdeleted file mode 100644 index 2959d1d..0000000 --- a/basicsuite/webengine/ui/icons/grid.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/home.png b/basicsuite/webengine/ui/icons/home.png Binary files differindex 92d01d1..b241e02 100644 --- a/basicsuite/webengine/ui/icons/home.png +++ b/basicsuite/webengine/ui/icons/home.png diff --git a/basicsuite/webengine/ui/icons/list.png b/basicsuite/webengine/ui/icons/list.png Binary files differdeleted file mode 100644 index 6cbc8b3..0000000 --- a/basicsuite/webengine/ui/icons/list.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/pin-checked.png b/basicsuite/webengine/ui/icons/pin-checked.png Binary files differdeleted file mode 100644 index aa50f2b..0000000 --- a/basicsuite/webengine/ui/icons/pin-checked.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/pin-unchecked.png b/basicsuite/webengine/ui/icons/pin-unchecked.png Binary files differdeleted file mode 100644 index c11411b..0000000 --- a/basicsuite/webengine/ui/icons/pin-unchecked.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/pin.png b/basicsuite/webengine/ui/icons/pin.png Binary files differdeleted file mode 100644 index 4439f04..0000000 --- a/basicsuite/webengine/ui/icons/pin.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/plus.png b/basicsuite/webengine/ui/icons/plus.png Binary files differdeleted file mode 100644 index 33b03d2..0000000 --- a/basicsuite/webengine/ui/icons/plus.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/process-stop.png b/basicsuite/webengine/ui/icons/process-stop.png Binary files differindex 8399059..c71d5a7 100644 --- a/basicsuite/webengine/ui/icons/process-stop.png +++ b/basicsuite/webengine/ui/icons/process-stop.png diff --git a/basicsuite/webengine/ui/icons/settings.png b/basicsuite/webengine/ui/icons/settings.png Binary files differdeleted file mode 100644 index 347a0e5..0000000 --- a/basicsuite/webengine/ui/icons/settings.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/stack.png b/basicsuite/webengine/ui/icons/stack.png Binary files differdeleted file mode 100644 index d631adc..0000000 --- a/basicsuite/webengine/ui/icons/stack.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/up.png b/basicsuite/webengine/ui/icons/up.png Binary files differindex 8a2e626..5d33c4a 100644 --- a/basicsuite/webengine/ui/icons/up.png +++ b/basicsuite/webengine/ui/icons/up.png diff --git a/basicsuite/webengine/ui/icons/view-refresh.png b/basicsuite/webengine/ui/icons/view-refresh.png Binary files differindex 265585b..e7af6b3 100644 --- a/basicsuite/webengine/ui/icons/view-refresh.png +++ b/basicsuite/webengine/ui/icons/view-refresh.png diff --git a/basicsuite/webengine/ui/icons/wifi-off.png b/basicsuite/webengine/ui/icons/wifi-off.png Binary files differdeleted file mode 100644 index 4c0490d..0000000 --- a/basicsuite/webengine/ui/icons/wifi-off.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/wifi-on.png b/basicsuite/webengine/ui/icons/wifi-on.png Binary files differdeleted file mode 100644 index 8bdc553..0000000 --- a/basicsuite/webengine/ui/icons/wifi-on.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/wifi.png b/basicsuite/webengine/ui/icons/wifi.png Binary files differdeleted file mode 100644 index 8a0d9e0..0000000 --- a/basicsuite/webengine/ui/icons/wifi.png +++ /dev/null diff --git a/basicsuite/webengine/ui/icons/window.png b/basicsuite/webengine/ui/icons/window.png Binary files differdeleted file mode 100644 index a06602b..0000000 --- a/basicsuite/webengine/ui/icons/window.png +++ /dev/null |