How does RenderPass work in Qt3D - qtquick2

In given code what is the use RenderPass and filterKeys, how does it works?
FilterKey { name: "pass"; value: "shadowmap" }
In above statement who uses these name and value?
Technique {
graphicsApiFilter {
api: GraphicsApiFilter.OpenGL
profile: GraphicsApiFilter.CoreProfile
majorVersion: 3
minorVersion: 2
}
renderPasses: [
RenderPass {
filterKeys: [ FilterKey { name: "pass"; value: "shadowmap" } ]
shaderProgram: ShaderProgram {
vertexShaderCode: loadSource("qrc:/shaders/shadowmap.vert")
fragmentShaderCode: loadSource("qrc:/shaders/shadowmap.frag")
}
renderStates: [
PolygonOffset { scaleFactor: 4; depthSteps: 4 },
DepthTest { depthFunction: DepthTest.Less }
]
},
RenderPass {
filterKeys: [ FilterKey { name : "pass"; value : "forward" } ]
shaderProgram: ShaderProgram {
vertexShaderCode: loadSource("qrc:/shaders/ads.vert")
fragmentShaderCode: loadSource("qrc:/shaders/ads.frag")
}
// no special render state set => use the default set of states
}
]
}

The filter keys will need to match the corresponding filter keys in the RenderPassFilter in the frame graph.
For instance, if you want to have a frame graph that only renders with the shaders specified in the forward pass, you could write something like:
RenderSettings{
activeFrameGraph: Viewport {
RenderPassFilter {
matchAny: [FilterKey { name: "pass"; value: "forward" }]
RenderSurfaceSelector {
ClearBuffers {
}
}
}
}
}
You can have multiple RenderPassFilters in the same frame graph. This allows you to render the same scene with different shaders, for instance to show the scene with different effects in different viewports, or to draw to different textures and blend them together in final pass.

Related

Custom Control: "Lifecycle-Method" when aggregation is updated

I am creating a simple custom control:
sap.ui.define([
"sap/ui/core/Control"
], function(Control) {
"use strict";
return Control.extend("my.control.SvgVisualizer", {
metadata: {
properties: {
width: {
type: "sap.ui.core.CSSSize",
defaultValue: "100%"
},
height: {
type: "sap.ui.core.CSSSize",
defaultValue: "100%"
}
},
aggregations: {
elements: {
type: "my.control.Element",
multiple: true,
singularName: "element"
}
}
},
renderer: {
apiVersion: 2,
render: function(oRm, oControl) {
oRm.openStart("svg", oControl.getId())
.attr("viewBox", oControl._sViewBox)
.attr("width", oControl.getWidth())
.attr("height", oControl.getHeight())
.openEnd();
oRm.close("svg");
}
}
});
});
Basically, it can be used to implement svg stuff with aggregations into SAPUI5.
When creating the svg (html)-element in the renderer function I need a viewBox.
I would like to calculate the value for the viewBox based on the properties of the controls in the aggregation elements. The calculation could be pretty heavy if there are loads of elements.
My question is where I should calculate the viewBox property. It needs to be recalculated when the aggregation elements changes (so init isn't enough) but it does not need to be recalculated every time the renderer function is called.
Is attaching a handler to the aggregation-binding in the constructor the best way: this.getBinding("elements").attachChange(...)
It is possible to override all the aggregation modifiers like addElement, removeElement, ...etc and recalculate there.
But I would suggest to implement some kind of change detection for the elements aggregation in the onBeforeRendering hook and perform calculations only if the aggregation has changed. This way you don't need to worry if you have overridden all the modifiers correctly and you have the implementation on a single place. For example:
onBeforeRendering: function () {
var currElements = this.getElements();
var recalculate = false;
if (!this._oldElements) {
recalculate = true;
} else if (this._oldElements.length !== currElements.length) {
recalculate = true;
} else if (... another condition that should trigger recalculation) {
recalculate = true;
}
if (recalculate) {
this._sViewBox = ...;
this._oldElements = currElements;
}
}

Unique custom formats in TinyMCE

I'm trying to create a list of paragraph styles in TinyMCE that apply to paragraphs. A paragraph should only have one of the styles applied. So a paragraph can be either normal, lead or small. It should not be more than one at once.
This is what I've tried:
formats: {
"p-normal": { block: "p", classes: "govuk-body" },
"p-lead": { block: "p", classes: "govuk-body-l" },
"p-small": { block: "p", classes: "govuk-body-s" }
},
style_formats: [
{ title: "Paragraph styles", items: [
{ title: "Normal paragraph", format: "p-normal" },
{ title: "Lead paragraph", format: "p-lead" },
{ title: "Small paragraph", format: "p-small" }
] }
]
If I make a paragraph normal and then change it to a lead paragraph it ends up looking like this:
<p class="govuk-body p-lead">Test</p>
And in the format dropdown both styles are ticked. Can I make it so only one format can be active and previously applied formats are removed?
I've found a way to do this by using an event handler to act before the format is toggled and remove all formats applied where the cursor is.
Here is the event handler:
init_instance_callback: function(editor) {
editor.on('BeforeExecCommand', function (e) {
if (e.command === "mceToggleFormat") {
var formats = this.formatter.matchAll(["p-normal", "p-lead", "p-small"]);
for (var i = 0; i < formats.length; i++) {
this.formatter.remove(formats[i]);
}
}
});
}
You need to check for all the formats that are exclusive and then remove any that are applied. If you had more than one group of exclusive formats you'd need to check the group based on which format was being applied.

GoldenLayout hide/show component (again)

I have an issue with showing/hiding a component similar to this question:
GoldenLayout, how to hide/show component?
My layout is as follows:
let config: Config = {
settings: {
showCloseIcon: false,
showPopoutIcon: false
},
content: [
{
type: 'column',
content: [
{
type: 'row',
height: 25,
content: [
{
title: 'A react component',
type: 'react-component',
component: 'searchContainer'
}
],
},
{
type: 'row',
height: 75,
content: [
{
title: 'A react component',
type: 'react-component',
component: 'leftContainer'
},
{
title: 'Another react component',
type: 'react-component',
component: 'rightContainer'
}
],
},
],
}],
};
I have a hideSearchBar and showSearchBar functions which look like this:
function hideSearchBar() {
let container: ContentItem = layout.root.contentItems[0];
container.contentItems[1].config.height = 100;
container.contentItems[1].contentItems[0].config.height = 100;
container.contentItems[1].contentItems[1].config.height = 100;
container.config.height = 0;
container.contentItems[0].element.hide();
layout.updateSize();
//layout.updateSize($(window).width(), $(window).height());
}
function showSearchBar() {
let container: ContentItem = layout.root.contentItems[0];
container.contentItems[0].element.show();
layout.updateSize();
}
The showSearchBar works perfectly and shows both rows of the grid correctly.
The hideSearchBar hides the top row correctly but leaves the second row does not take up the whole screen. I have tried setting the config.height to 100 in various places but cannot get it to work - there is a gap the size of the top row at the bottom of the screen.
Any help much appreciated.
I solved this with a different layout config where search bar was initially set to 0:
let config: Config = {
settings: {
showCloseIcon: false,
showPopoutIcon: false
},
content: [
{
type: 'column',
content: [
{
type: 'row',
height: 0,
content: [
{
title: 'A react component',
type: 'react-component',
component: LayoutComponent.SearchContainer
}
],
},
{
type: 'row',
height: 100,
content: [
{
title: 'A react component',
type: 'react-component',
component: LayoutComponent.WindowContainer
},
{
title: 'Another react component',
type: 'react-component',
component: LayoutComponent.CollectionContainer
}
],
},
],
}],
};
showSearchBar looks like this:
function showSearchBar() {
let container: ContentItem = layout.root.contentItems[0];
if (searchRowHeight == 0) {
container.contentItems[0].config.height = SEARCH_HEIGHT;
}
else {
container.contentItems[0].config.height = searchRowHeight;
container.contentItems[1].config.height = containerRowHeight;
}
container.contentItems[0].element.show();
layout.updateSize();
}
and hideSearchBar looks like this:
function hideSearchBar() {
let container: ContentItem = layout.root.contentItems[0];
container.contentItems[0].config.height = 0;
container.contentItems[1].config.height = 100;
container.contentItems[0].element.hide();
layout.updateSize();
}
In summary, the config made the searchBar hidden and when it was opened, heights were readjusted.
I use an event listener to check for height changes:
layout.on('stateChanged', () => {
let updateConfig: Config = layout.toConfig();
if (updateConfig.content[0].content[0].height != 0) {
searchRowHeight = updateConfig.content[0].content[0].height;
containerRowHeight = updateConfig.content[0].content[1].height;
}
HTH
Extending #jmc42's answer. Pretty good work-around but once thing it doesn't do is hide the splitter when expanding on pane to 100% and the collapsing the other to 0%.
As a work-around, I thought of 2 choices:
When the pane gets hidden, get the adjacent element representing the splitter bar within the same div and hide it.
When the pane gets hidden, and you detect a resize, always re-apply the expand the top pane to 100% and the bottom pane to 0%.
I opted for option 2 as it was simpler to implement and what I have is:
if (updateConfig.content[0].content[0].height != 0) {
searchRowHeight = updateConfig.content[0].content[0].height;
containerRowHeight = updateConfig.content[0].content[1].height;
}
else {
let container = gbl_Layout.root.contentItems[0].contentItems[0];
container.contentItems[0].config.height = 100;
container.contentItems[1].config.height = 0;
layout.updateSize();
}
My 'if' statement condition is more complex that the one above as I'm performing other checks but that will give you the gist of it. Works pretty well for me.

How to connect to SharePoint Online with IP address

I would like to know how to successfully connect to spo service url with a IP address.
Connect-SPOService https://13.xxx.xxx.9-admin.sharepoint.com
How about triggering the Excel export manually on button click using kendo.ooxml.Workbook combined with kendo.saveAs?
I have made up a Kendo Dojo example. Let me know if this is what you need. Additionally, if you need to retrieve the name of your screen, there are some examples of how to do this here
EDIT
Below is an example of the export generated by the Dojo example when the "Click to Export" button is pressed. Note that the title is custom.
Not sure why this would not work for you, but try the following example with your code and see what happens. Basically, you can hook up the custom function to handle the export button click as follows:
$("#exportButton").kendoButton({
click: function () {
var grid = $("#yourGrid").getKendoGrid();
// declare `rows` and supply your own column names
var rows = [{
cells: [
{ value: "ContactTitle" },
{ value: "CompanyName" },
{ value: "Country" }
]
}];
var trs = grid.dataSource;
// will get any filters applied to grid dataSource
var filteredDataSource = new kendo.data.DataSource({
data: trs.data(),
filter: trs.filter()
});
filteredDataSource.read();
var data = filteredDataSource.view();
for (var i = 0; i < data.length; i++) {
var dataItem = data[i];
rows.push({
cells: [ // dataItem."Whatever Your Attributes Are"
{ value: dataItem.ContactTitle },
{ value: dataItem.CompanyName },
{ value: dataItem.Country }
]
});
}
excelExport(rows);
}
});
This sets up the rows to be exported, and the excelExport function carries out the export:
function excelExport(rows) {
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
columns: [
{ autoWidth: true },
{ autoWidth: true }
],
title: "Name of Tab",
rows: rows
}
]
});
var nameOfPage = "Test-1"; // insert here however you are getting name of screen
kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: nameOfPage + " Export.xlsx" });
}
Let me know the outcome.

Knockout.js - Reload a dropdown with new options using the value of another drop down

I've seen similar things, where people have wanted to do this in ASP .NET, generic JavaScript, PHP, etc., but now here we have KnockOut that throws a wrench in things, since its fields are already rendered dynamically. Now here I go wanting to rewrite a dropdown when another is changed... dynamic loading on top of dynamic loading, all in old-fashioned cascading style....
I have a dropdown, "ourTypes", I've called it, that when changed, should re-write the options of the "slots" dropdown to its left. I have a .subscribe() function that creates new options based on a limit I get from the "ourTypes" value. All well and good, but how do we make the dropdown actually reflect those new values?
HTML:
<select data-bind="options: $root.slots, optionsValue: 'Value', optionsText: 'Text', value: $data.SlotPosition"></select>
<select data-bind="options: $root.ourTypes, optionsValue: 'ID', optionsText: 'Name', value: $data.OurTypeId"></select>
JavaScript:
var slots = [
{ Text: "1", Value: "1" },
{ Text: "2", Value: "2" },
{ Text: "3", Value: "3" }
];
var ourTypes = [
{ ID:"1", Name:"None", Limit:0 },
{ ID:"2", Name:"Fruits", Limit:5 },
{ ID:"3", Name:"Vegetables", Limit:5 },
{ ID:"4", Name:"Meats", Limit:2 }
];
var dataList = [
{ SlotPosition: "1", OurTypeId: 4 },
{ SlotPosition: "2", OurTypeId: 2 },
{ SlotPosition: "3", OurTypeId: 3 }
];
var myViewModel = new MyViewModel(dataList);
ko.applyBindings(myViewModel);
function MyViewModel(dataList) {
var self = this;
self.slots = slots;
self.ourTypes = ourTypes;
self.OurTypeId = ko.observable(dataList.OurTypeId);
self.SlotPosition = ko.observable(dataList.SlotPosition);
self.OurTypeId.subscribe(function() {
if (!ko.isObservable(self.SlotPosition))
self.SlotPosition = ko.observable("1");
// Get our new limit based on value
var limit = ko.utils.arrayFirst(ourTypes, function(type) {
return type.ID == self.OurTypeId();
}).Limit;
// Build options here
self.slots.length = 0;
self.slots.push({Text:"",Value:""});
for (var i=1; i < limit+1; i++) {
self.slots.push({Text:i, Value:i});
}
// What else do I do here to make the dropdown refresh
// with the new values?
});
}
Fiddle: http://jsfiddle.net/navyjax2/Lspwc4n4/
Well just made small changes in you code
View Model:
self.slots = ko.observableArray(slots); //should make it observable
self.ourTypes = ko.observableArray(ourTypes);
self.OurTypeId = ko.observable(dataList[0].OurTypeId); // initial value setting
self.SlotPosition = ko.observable(dataList.SlotPosition);
//Inside subscribe
self.slots([]); // clearing before filling new values
Working fiddle here