summaryrefslogtreecommitdiff
path: root/qml
diff options
context:
space:
mode:
Diffstat (limited to 'qml')
-rw-r--r--qml/cover/CoverPage.qml42
-rw-r--r--qml/finesketch.qml40
-rw-r--r--qml/items/SketchArea.qml84
-rw-r--r--qml/items/SketchView.qml80
-rw-r--r--qml/pages/SketchPage.qml12
5 files changed, 258 insertions, 0 deletions
diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml
new file mode 100644
index 0000000..7679cfc
--- /dev/null
+++ b/qml/cover/CoverPage.qml
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2013 Jolla Ltd.
+ Contact: Thomas Perl <thomas.perl@jollamobile.com>
+ All rights reserved.
+
+ You may use this file under the terms of 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 the Jolla Ltd 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 HOLDERS 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.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+CoverBackground {
+ Label {
+ id: label
+ anchors.centerIn: parent
+ text: "Finescript"
+ }
+}
+
+
diff --git a/qml/finesketch.qml b/qml/finesketch.qml
new file mode 100644
index 0000000..e116e6f
--- /dev/null
+++ b/qml/finesketch.qml
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2013 Jolla Ltd.
+ Contact: Thomas Perl <thomas.perl@jollamobile.com>
+ All rights reserved.
+
+ You may use this file under the terms of 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 the Jolla Ltd 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 HOLDERS 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.
+*/
+
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "pages"
+
+ApplicationWindow
+{
+ id: appWindow
+ initialPage: Component { SketchPage { } }
+ cover: Qt.resolvedUrl("cover/CoverPage.qml")
+}
diff --git a/qml/items/SketchArea.qml b/qml/items/SketchArea.qml
new file mode 100644
index 0000000..3a528d9
--- /dev/null
+++ b/qml/items/SketchArea.qml
@@ -0,0 +1,84 @@
+import QtQuick 2.0
+
+SketchView {
+ id: area
+ autoRepaint: false
+
+ property color fingerLineColor: Qt.rgba(1.0, 0.0, 0.0, 1.0)
+ property color stylusLineColor: Qt.rgba(0.0, 0.0, 0.0, 1.0)
+ property color eraserLineColor: Qt.rgba(1.0, 1.0, 1.0, 1.0)
+ property real curLineWidth: 4
+
+ function _boundingBox(points) {
+ if (!points.length) return Qt.rect(0, 0, 0, 0);
+ var x1 = points[0].x, y1 = points[0].y;
+ var x2 = x1, y2 = y1;
+
+ for (var i = 1; i < points.length; i++) {
+ if (points[i].x < x1) x1 = points[i].x;
+ if (points[i].y < y1) y1 = points[i].y;
+ if (points[i].x > x2) x2 = points[i].x;
+ if (points[i].y > y2) y2 = points[i].y;
+ }
+
+ return Qt.rect(x1, y1, x2 - x1, y2 - y1);
+ }
+
+ function _isStylusOn() {
+ return stylus.pressure > 0.15;
+ }
+ function _isEraserOn() {
+ return !_isStylusOn() && stylus.y > 0.85;
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ preventStealing: true
+
+ onPressed: {
+ var point = Qt.point(mouse.x, mouse.y);
+ var stroke = {
+ lineWidth : curLineWidth,
+ lineColor : fingerLineColor,
+ stylus : false,
+ eraser : false,
+ boundingBox : Qt.rect(0, 0, area.width, area.height),
+ points : [point]
+ }
+ strokes.push(stroke);
+ canvas.requestPaint();
+ }
+ onReleased: {
+ canvas.requestPaint();
+ }
+ onPositionChanged: {
+ var cur_stroke = strokes[area.strokes.length - 1];
+ var point = Qt.point(mouse.x, mouse.y);
+ var prev_point = cur_stroke.points[cur_stroke.points.length - 1];
+ cur_stroke.points.push(point);
+ cur_stroke.boundingBox = _boundingBox(cur_stroke.points);
+
+ var rect = Qt.rect(Math.floor(Math.min(point.x, prev_point.x) - cur_stroke.lineWidth/2),
+ Math.floor(Math.min(point.y, prev_point.y) - cur_stroke.lineWidth/2),
+ Math.ceil(Math.abs(point.x - prev_point.x) + cur_stroke.lineWidth),
+ Math.ceil(Math.abs(point.y - prev_point.y) + cur_stroke.lineWidth));
+
+ if (!cur_stroke.stylus) {
+ if (_isStylusOn()) {
+ cur_stroke.stylus = true;
+ cur_stroke.lineColor = stylusLineColor;
+ canvas.requestPaint();
+ return;
+ } else if (_isEraserOn()) {
+ cur_stroke.stylus = true;
+ cur_stroke.eraser = true;
+ cur_stroke.lineColor = eraserLineColor;
+ canvas.requestPaint();
+ return;
+ }
+ }
+
+ canvas.markDirty(rect);
+ }
+ }
+}
diff --git a/qml/items/SketchView.qml b/qml/items/SketchView.qml
new file mode 100644
index 0000000..8ded87a
--- /dev/null
+++ b/qml/items/SketchView.qml
@@ -0,0 +1,80 @@
+import QtQuick 2.0
+
+Item {
+ id: view
+
+ property alias fillColor: rectangle.color
+ property alias border: rectangle.border
+
+ property var strokes: []
+
+ property bool autoRepaint: true
+ property alias canvas: canvas
+
+ function _drawStroke(ctx, stroke) {
+ var points = stroke.points;
+ ctx.save();
+ ctx.lineWidth = stroke.lineWidth;
+ ctx.strokeStyle = stroke.lineColor;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(points[0].x, points[0].y);
+ for (var i = 1; i < points.length; i++) {
+ ctx.lineTo(points[i].x, points[i].y);
+ }
+ ctx.stroke();
+ ctx.restore();
+ }
+
+ function _intersect(r1, r2) {
+ if (!r1.width || !r2.width) return false;
+ if (!r1.height || !r2.height) return false;
+
+ if (r1.x >= r2.x + r2.width) return false;
+ if (r1.y >= r2.y + r2.height) return false;
+ if (r2.x >= r1.x + r1.width) return false;
+ if (r2.y >= r1.y + r1.height) return false;
+ return true;
+ }
+
+ Rectangle {
+ id: rectangle
+ anchors.fill: parent
+
+ color: Qt.rgba(1.0, 1.0, 1.0, 0.3)
+ radius: 10.0
+ }
+
+ Canvas {
+ id: canvas
+ anchors.fill: parent
+
+ renderTarget: Canvas.Image
+ renderStrategy: Canvas.Immediate
+
+ onPaint: {
+ var ctx = canvas.getContext('2d');
+ ctx.clearRect(region.x, region.y, region.width, region.height);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.rect(region.x, region.y, region.width, region.height);
+ ctx.clip();
+
+ for (var i = 0; i < strokes.length; i++) {
+ if (_intersect(region, strokes[i].boundingBox)) {
+ _drawStroke(ctx, strokes[i]);
+ }
+ }
+
+ ctx.restore();
+ }
+ }
+
+ onStrokesChanged: {
+ if (autoRepaint) {
+ canvas.requestPaint();
+ }
+ }
+}
diff --git a/qml/pages/SketchPage.qml b/qml/pages/SketchPage.qml
new file mode 100644
index 0000000..449b2aa
--- /dev/null
+++ b/qml/pages/SketchPage.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import "../items"
+
+Page {
+ id: sketchPage
+
+ SketchArea {
+ id: area
+ anchors.fill: parent
+ }
+}