Commit ecbd0c54 authored by Harald Sitter's avatar Harald Sitter

add a needler app to manage needles without having to fire up gimp -.-

parent 63661e1d
project(needler)
cmake_minimum_required(VERSION 3.0)
find_package(ECM 0.0.14 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include(FeatureSummary)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings)
find_package(Qt5 CONFIG REQUIRED Gui Qml)
find_package(KF5CoreAddons 5.0.0 REQUIRED)
find_package(KF5KIO 5.0 REQUIRED)
add_subdirectory(src)
qt5_add_resources(needler_SRCS resources.qrc)
add_executable(needler main.cpp ${needler_SRCS})
target_link_libraries(needler Qt5::Qml Qt5::Gui KF5::KIOCore)
/*
Copyright © 2017 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QMutex>
#include <QWaitCondition>
#include <KIO/CopyJob>
#include <QDebug>
class Application : public QObject
{
Q_OBJECT
public slots:
QUrl fileArgument()
{
return QUrl::fromLocalFile(QCoreApplication::arguments().at(1));
}
bool copy(const QUrl &origin, const QUrl &target)
{
qDebug() << origin << target;
auto job = KIO::copy(origin, target, KIO::Overwrite);
qDebug() << "start";
return job->exec();
}
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterSingletonType<Application>("privateneedler", 1, 0, "Application",
[](QQmlEngine *, QJSEngine *) -> QObject * { return new Application; });
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
#include "main.moc"
/*
Copyright © 2017 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
Item {
id: item
property QtObject rect
Twiddler {
id: topTwiddler
anchors.verticalCenter: parent.top
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
anchors.fill: parent
drag.target: parent
drag.axis: Drag.YAxis
onMouseYChanged: {
if (!drag.active) {
return
}
rect.height = rect.height - mouseY
rect.y = rect.y + mouseY
if (rect.height < parent.radius) {
rect.height = parent.radius
}
}
}
}
Twiddler {
id: rightTwiddler
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.right
MouseArea {
anchors.fill: parent
drag.target: parent
drag.axis: Drag.XAxis
onMouseXChanged: {
if (!drag.active) {
return
}
rect.width = rect.width + mouseX
if (rect.width < parent.radius) {
rect.width = parent.radius
}
}
}
}
Twiddler {
id: bottomTwiddler
anchors.verticalCenter: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
anchors.fill: parent
drag.target: parent
drag.axis: Drag.YAxis
onMouseYChanged: {
if (!drag.active) {
return
}
rect.height = rect.height + mouseY
if(rect.height < parent.radius) {
rect.height = parent.radius
}
}
}
}
Twiddler {
id: leftTwiddler
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.left
MouseArea {
anchors.fill: parent
drag.target: parent
drag.axis: Drag.XAxis
onMouseXChanged: {
if (!drag.active) {
return
}
rect.width = rect.width - mouseX
rect.x = rect.x + mouseX
if (rect.width < parent.radius) {
rect.width = parent.radius
}
}
}
}
}
/*
Copyright © 2017 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQml.Models 2.2
import QtQuick.Layouts 1.3
Rectangle {
id: rect
property ObjectModel model
property string type: "match"
property double match: 95
// This is the hard limit offset, we'll coerce the rect inside a given
// maxX and maxY with this offset. As a result this is effectively the
// minimal square length of the rect.
property int minimumOffset: 12
function dimensionHint() {
dimensionText.text = width + "x" + height
dimensionText.visible = true
}
function fromObject(obj) {
console.debug("----- fromObject")
type = obj.type
x = obj.xpos
y = obj.ypos
width = obj.width
height = obj.height
match = obj.match || 95
}
function toObject() {
console.debug("----- toObject")
return {
type: this.type,
xpos: this.x,
ypos: this.y,
width: this.width,
height: this.height,
match: this.match,
}
}
color: "transparent"
width: 64
height: 64
border.width: 1
border.color: "lightblue"
onXChanged: {
if (x < 0) {
x = 0
} else if (x > image.width) {
x = image.width - minimumOffset
}
}
onYChanged: {
if (y < 0) {
y = 0
} else if (y > image.height) {
y = image.height - minimumOffset
}
}
onWidthChanged: {
if (x + width > image.width) {
width = image.width - x
}
dimensionHint()
}
onHeightChanged: {
if (y + height > image.height) {
height = image.height - y
}
dimensionHint()
}
Rectangle {
id: fill
anchors.fill: parent
color: "steelblue"
opacity: 0.6
}
Text {
id: dimensionText
visible: false
anchors.centerIn: parent
onVisibleChanged: {
if (!visible) {
return
}
timer.restart()
}
Timer {
id: timer
interval: 2500
repeat: false
onTriggered: {
dimensionText.visible = false
}
}
}
Dialog {
id: propDialog
visible: false
title: "Properties"
modal: true
standardButtons: Dialog.Ok | Dialog.Cancel
contentItem: ColumnLayout {
RowLayout {
Label { text: "type" }
TextField { id:typeField; text: rect.type }
}
RowLayout {
Label { text: "match" }
TextField {
id:matchField
text: rect.match
validator: IntValidator{ bottom: 0; top: 100; }
}
}
}
onAccepted: {
rect.type = typeField.text
rect.match = parseFloat(matchField.text)
}
}
Menu {
id: contextMenuComponent
modal: true
MenuItem {
text: "properties"
onTriggered: { propDialog.open() }
}
MenuItem {
text: "delete"
onTriggered: { model.removeObject(rect) }
}
}
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
drag.maximumX: image.x + image.width - rect.width
drag.minimumX: image.x
drag.maximumY: image.y + image.height - rect.height
drag.minimumY: image.y
acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressed: {
if (mouse.button == Qt.RightButton) {
contextMenuComponent.open()
return;
}
}
}
RectangleTwiddler {
anchors.fill: parent
rect: parent
}
}
/*
Copyright © 2017 Harald Sitter <sitter@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.0
Rectangle {
width: 12
height: 12
radius: 12
color: "red"
}
This diff is collapsed.
<RCC>
<qresource prefix="/">
<file>qml/main.qml</file>
<file>qml/RectangleTwiddler.qml</file>
<file>qml/Twiddler.qml</file>
<file>qml/Selector.qml</file>
</qresource>
</RCC>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment