Skip to content

Commit

Permalink
Squashed v1.1.0 plugin source code (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbouny authored Nov 22, 2017
1 parent 7a0dbab commit b4216c8
Show file tree
Hide file tree
Showing 11 changed files with 689 additions and 0 deletions.
39 changes: 39 additions & 0 deletions ButtonAutoLink.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import AlgWidgets.Style 1.0
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

Button {
id: root
height: 30
width: height
tooltip: "<p>Enable/disable auto link</p>" +
"<p>After modifications in the current stack, maps will be automatically sent to the integration</p>"

property bool enableAutoLink: true

style: ButtonStyle {
background: Rectangle {
color: (root.enabled && hovered)? AlgStyle.background.color.gray : "#141414"
}
label: Item {
height: control.height
width: control.width
Rectangle {
anchors.fill: parent
anchors.margins: 2
radius: width
color: !root.enabled? "#666" : (enableAutoLink?
(hovered? "#0d0" : "#0a0") :
(hovered? "#d00" : "#a00")
)
}
}
}

onClicked: {
if (root.enabled) {
enableAutoLink = !enableAutoLink
}
}
}
28 changes: 28 additions & 0 deletions ButtonSendMaps.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import AlgWidgets.Style 1.0
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

Button {
id: root
height: 30
width: 30
tooltip: "Send all materials to Integration"

property string clientName: ""

style: ButtonStyle {
background: Rectangle {
color: (root.enabled && hovered)? AlgStyle.background.color.gray : "#141414"
}
label: Item {
Image {
height: parent.height
antialiasing: true
fillMode:Image.PreserveAspectFit
source: enabled ? (clientName == "Unreal4" ? "icons/ue4_connected.png" : "icons/unity_connected.png") : "icons/no_connection.png"
opacity: root.enabled? (hovered? 0.9 : 0.7) : 0.4
}
}
}
}
93 changes: 93 additions & 0 deletions CommandServer.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Painter 1.0
import QtQuick 2.7
import QtWebSockets 1.0

Item {
id: root

property alias host : server.host
property alias listen: server.listen
property alias port: server.port
property alias currentWebSocket: server.currentWebSocket
readonly property bool connected: currentWebSocket !== null

signal jsonMessageReceived(var command, var jsonData)

property var _callbacks: null

function registerCallback(command, callback) {
if (_callbacks === null) {
_callbacks = {};
}
_callbacks[command.toUpperCase()] = callback;
}

function sendCommand(command, data) {
if (!connected) {
alg.log.warn(qsTr("Can't send \"%1\" command as there is no client connected").arg(command));
return;
}
try {
server.currentWebSocket.sendTextMessage(command + " " + JSON.stringify(data));
}
catch(err) {
alg.log.error(qsTr("Unexpected error while sending \"%1\" command: %2").arg(command).arg(err.message));
}
}

WebSocketServer {
id: server

listen: true
port: 6404
property var currentWebSocket: null
name: "Substance Painter"
accept: !root.connected // Ensure only one connection at a time

onClientConnected: {
currentWebSocket = webSocket;

webSocket.statusChanged.connect(function onWSStatusChanged() {
if (root && root.connected && (
webSocket.status == WebSocket.Closed ||
webSocket.status == WebSocket.Error))
{
server.currentWebSocket = null;
}
if (webSocket.status == WebSocket.Error) {
alg.log.warn(qsTr("Command server connection error: %1").arg(webSocket.errorString));
}
});
webSocket.onTextMessageReceived.connect(function onWSTxtMessageReceived(message) {
// Try to retrieve command and json data
var command, jsonData;
try {
var separator = message.indexOf(" ");
var jsonString = message.substring(separator + 1, message.length);
jsonData = JSON.parse(jsonString);
command = message.substring(0, separator).toUpperCase();
}
catch(err) {
alg.log.warn(qsTr("Command connection received badly formated message starting with: \"%1\"...: %2")
.arg(message.substring(0, 30))
.arg(err.message));
return;
}

if (root._callbacks && command in root._callbacks) {
try {
root._callbacks[command](jsonData)
}
catch(err) {
alg.log.warn(err.message);
}
}
root.jsonMessageReceived(command, jsonData);
})
}

onErrorStringChanged: {
alg.log.warn(qsTr("Command server error: %1").arg(errorString));
}
}
}
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# DCC Live Link - Substance Painter plugin

This plugin handles a link between Substance Painter and a third-party application allowing live materials transfer.

## Installation

Download or clone this project into the Substance Painter plugins folder. The plugins folder can be opened from Substance Painter through the menu ``Plugins/Plugins folder``.

## License

Distributed under the MIT license. See [LICENSE](LICENSE) file for more information.
127 changes: 127 additions & 0 deletions Settings.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import AlgWidgets 1.0
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Painter 1.0

AlgWindow {
id: root

title: "Live Link configuration"
visible: false
minimumWidth: 300
maximumWidth: minimumWidth
minimumHeight: 150
maximumHeight: minimumHeight

Component.onCompleted: {
flags = flags | Qt.WindowStaysOnTopHint;
}

property int linkQuickInterval: 300 /*ms*/
property int linkDegradedResolution: 1024
property int linkHQTreshold: 2048
property int linkHQInterval: 4000 /*ms*/
property int initDelayOnProjectCreation: 5000 /*ms*/
readonly property string settingsKeyPrefix: "live_link"

GridLayout {
id: layout
anchors.fill: parent
anchors.margins: 10

columns: 2

function initSlider(component, linkedProperty) {
var settingKey = "%1_%2".arg(root.settingsKeyPrefix).arg(linkedProperty);
var defaultValue = alg.settings.contains(settingKey)?
alg.settings.value(settingKey) : root[linkedProperty];

// Bind slider value changed on setting value
root[linkedProperty] = Qt.binding(function() {return component.value;});
component.valueChanged.connect(function() {
alg.settings.setValue(settingKey, component.value);
});

// Set default value
component.value = defaultValue;
}

function initResolutionComboBox(component, linkedProperty, model) {
var settingKey = "%1_%2".arg(root.settingsKeyPrefix).arg(linkedProperty);
var defaultValue = alg.settings.contains(settingKey)?
alg.settings.value(settingKey) : root[linkedProperty];

// Bind combo box index changed on setting value
component.currentIndexChanged.connect(function() {
var resolution = model.get(component.currentIndex).resolution;
root[linkedProperty] = resolution;
alg.settings.setValue(settingKey, resolution);
});

// Fill model
for (var resolution = component.minResolution; resolution <= component.maxResolution; resolution = resolution << 1) {
model.append({
text: resolution + " px",
resolution: resolution
});
}

// Set default resolution/index
function log2(n) { return Math.log(n) / Math.log(2); }
component.currentIndex = log2(defaultValue) - log2(component.minResolution);
}

AlgSlider {
Layout.columnSpan: 2
Layout.fillWidth:true
precision: 0
stepSize: 1000
minValue: 1000
maxValue: 10000
text: "Delay on project creation (ms)"
Component.onCompleted: parent.initSlider(this, "initDelayOnProjectCreation");
}

AlgSlider {
Layout.columnSpan: 2
Layout.fillWidth:true
precision: 0
stepSize: 50
minValue: 50
maxValue: 2000
text: "Standard maps transfer delay (ms)"
Component.onCompleted: parent.initSlider(this, "linkQuickInterval");
}

AlgLabel {text: "Degraded preview treshold"}
AlgComboBox {
Layout.fillWidth: true
property int minResolution: 1024
property int maxResolution: 4096
textRole: "text"
Component.onCompleted: parent.initResolutionComboBox(this, "linkHQTreshold", model);
model: ListModel {}
}

AlgLabel {text: "Degraded preview resolution"}
AlgComboBox {
Layout.fillWidth: true
property int minResolution: 256
property int maxResolution: 2048
textRole: "text"
Component.onCompleted: parent.initResolutionComboBox(this, "linkDegradedResolution", model);
model: ListModel {}
}

AlgSlider {
Layout.columnSpan: 2
Layout.fillWidth:true
precision: 0
stepSize: 50
minValue: 100
maxValue: 5000
text: "HQ maps transfer delay (ms)"
Component.onCompleted: parent.initSlider(this, "linkHQInterval");
}
}
}
Binary file added icons/no_connection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/ue4_connected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/unity_connected.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b4216c8

Please sign in to comment.