Skip to content
145 changes: 141 additions & 4 deletions data/gloperate/qml/GlOperatePipeline.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ Item

signal slotChanged(string path, string slot, var status)

// Canvas scripting interface (accessed by 'root')
property var canvas: null
property var canvas: null ///< Canvas scripting interface (accessed by 'root')
property var internalStages: {} ///< Store stages only accessible for scripting and UI
property var internalTypes: null ///< Stores internal stage types, lazy initialize
property string editor: '' ///< State of editor

function getStageTypes()
{
Expand All @@ -32,6 +34,8 @@ Item
}
}

types = types.concat(Object.keys(getInternalTypes()));

return types;
}

Expand All @@ -45,6 +49,11 @@ Item

function createStage(path, name, type)
{
if (getInternalTypes().hasOwnProperty(type))
{
return createInternalStage(path, name, type);
}

if (canvas)
{
return canvas.createStage(path, name, type);
Expand All @@ -71,12 +80,35 @@ Item
{
var connections = canvas ? canvas.getConnections(path) : null;

if (connections) return connections;
else return [];
if (!connections)
{
return [];
}

if (path === "root")
{
for (var internalPath in internalStages)
{
if (isVisible(internalStages[internalPath]))
{
connections = connections.concat(internalStages[internalPath].getConnections());
}
}
}

return connections;
}

function createConnection(sourcePath, sourceSlot, destPath, destSlot)
{
for (var internalPath in internalStages)
{
if (destPath === internalPath)
{
internalStages[internalPath].connectionCreated(sourcePath, sourceSlot, destPath, destSlot);
}
}

if (canvas)
{
canvas.createConnection(sourcePath, sourceSlot, destPath, destSlot);
Expand All @@ -85,6 +117,14 @@ Item

function removeConnection(path, slot)
{
for (var internalPath in internalStages)
{
if (path === internalPath)
{
internalStages[internalPath].connectionRemoved(path, slot);
}
}

if (canvas)
{
canvas.removeConnection(path, slot);
Expand All @@ -95,6 +135,26 @@ Item
{
var info = canvas ? canvas.getStage(path) : null;

if (info && path === "root")
{
for (var internalPath in internalStages)
{
var stage = internalStages[internalPath];
if (isVisible(stage))
{
info.stages.push(stage.name);
}
}
}

for (var internalPath in internalStages)
{
if (path === internalPath)
{
return internalStages[internalPath].getDescription();
}
}

if (info) {
return info;
} else {
Expand Down Expand Up @@ -137,4 +197,81 @@ Item
canvas.setValue(path, slot, value);
}
}

// Functions regarding internal stages
function isVisible(stage)
{
return editor === 'internal' ? stage.isVisibleInternal : stage.isVisibleExternal;
}

function getInternalTypes()
{
if (internalTypes === null)
{
initializeInternalTypes();
}
return internalTypes;
}

function getInternalStages()
{
var stages = {};

for (var internalPath in internalStages)
{
var stage = internalStages[internalPath];

if (isVisible(stage))
{
stages[internalPath] = stage;
}
}

return stages;
}

function clearInternalStages()
{
internalStages = {};
}

function createInternalStage(path, name, type)
{
var realName = name;

if (internalStages.hasOwnProperty(path + "." + name))
{
// name already taken, add a number
var i = 2;
while (internalStages.hasOwnProperty(path + "." + name + i))
{
i += 1;
}
realName = name + i;
}

var stageComponent = getInternalTypes()[type];

var newStage = stageComponent.createObject(pipelineInterface, {});
var stage = newStage.stageDefinition;

stage.name = realName;
stage.path = path + "." + realName;

internalStages[stage.path] = stage;

return realName;
}

function initializeInternalTypes()
{
internalTypes = {};

internalTypes['PreviewStage'] = previewStageComponent;
}

property Component previewStageComponent : PreviewStage
{
id: previewStage
}
}
89 changes: 89 additions & 0 deletions data/gloperate/qml/InternalStage.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

import QtQuick 2.0


/**
* InternalStage
*
* Describes the state of an internal stage for (scripting and UI), only supports inputs
*/
Item
{
id: stage

signal connectionCreated(string sourcePath, string sourceSlot, string destPath, string destSlot)
signal connectionRemoved(string path, string slot)

property string name: '' ///< Name of the stage (for display)
property string path: '' ///< Path of the stage
property var inputs: [] ///< Input configuration of the stage
property var connections: {} ///< Connections to this stage

property bool isVisibleInternal: true ///< Whether this stage should be visible in 'internal' mode
property bool isVisibleExternal: true ///< Whether this stage should be visible in 'external' mode

property bool configured: false ///< Whether this stage is already configured

function onConfigure(stageItem) {} ///< To be overridden with actual configuration

function configure(stageItem) {
if (configured)
{
return;
}

onConfigure(stageItem);

configured = true;
}

onConnectionCreated:
{
if (connections === undefined)
{
connections = {};
}
connections[destSlot] = sourcePath + '.' + sourceSlot;
}

onConnectionRemoved:
{
if (connections === undefined)
{
return;
}

delete connections[slot];
}

// Generate stage description with inputs, outputs, and stages
function getDescription() {
var inputNames = [];

for (var i in inputs)
{
var input = inputs[i];
inputNames.push(input.name);
}

return {
name: path,
inputs: inputNames,
outputs: [],
stages: []
};
}

// Generate stage connections
function getConnections() {
var connectionList = [];

for (var slot in connections)
{
connectionList.push({from: connections[slot], to: path + '.' + slot});
}

return connectionList;
}

}
10 changes: 5 additions & 5 deletions data/gloperate/qml/PipelinePage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ ScrollArea
/// Called when a render stage has been selected
signal renderStageSelected(string name)

property var categories: [] ///< List of categories
property var stages: {} ///< List of stages, sorted by categories ( { 'cat1': [ { name: '', description: '', ... } ], 'cat2': [], ...})
property var currentCategory: 'Demo' ///< The currently selected category
property var currentStage: '' ///< The currently selected stage
property var categories: [] ///< List of categories
property var stages: {} ///< List of stages, sorted by categories ( { 'cat1': [ { name: '', description: '', ... } ], 'cat2': [], ...})
property var currentCategory: 'Demos' ///< The currently selected category
property var currentStage: '' ///< The currently selected stage

contentWidth: layout.width
contentHeight: layout.height
Expand Down Expand Up @@ -66,7 +66,7 @@ ScrollArea

Repeater
{
model: item.stages[item.currentCategory].length
model: item.stages === undefined ? 0 : item.stages[item.currentCategory].length

ClickLabel
{
Expand Down
63 changes: 40 additions & 23 deletions data/gloperate/qml/PipelineView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ Item
id: page

signal closed()
signal toggled()

property var properties: null ///< Interface for communicating with the actual properties
property string path: '' ///< Path to pipeline
property var properties: null ///< Interface for communicating with the actual properties
property string path: '' ///< Path to pipeline
property string toggleButton: '' ///< Description of the toggle state button

implicitWidth: pipelineEditor.implicitWidth
implicitHeight: pipelineEditor.implicitHeight
Expand All @@ -42,38 +44,53 @@ Item
}
}

Rectangle
Button
{
x: 100
y: 100
width: 200
height: 200
text: page.toggleButton
visible: page.toggleButton === "" ? false : true

color: 'white'
border.color: 'black'
border.width: 1
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: Ui.style.paddingMedium

TextureItem
onClicked:
{
anchors.fill: parent
anchors.margins: 1

path: 'ShapeDemo.Framebuffer.colorTexture'
page.toggled();
}
}
}

MouseArea
{
anchors.fill: parent
drag.target: parent
}
function load()
{
if (pipelineEditor.loaded)
{
return;
}

pipelineEditor.load(path);

configureInternalStages();

pipelineEditor.pipeline.stageCreated.connect(configureInternalStages);
}

function update()
{
pipelineEditor.update();

configureInternalStages();
}

onVisibleChanged:
function configureInternalStages()
{
if (visible)
var internalStages = properties.getInternalStages();

for (var stageName in internalStages)
{
pipelineEditor.load(path);
var stageDefinition = internalStages[stageName];
var stageObject = pipelineEditor.pipeline.stageItems[stageDefinition.name];

stageDefinition.configure(stageObject);
}
}
}
Loading