diff --git a/package/contents/ui/KomplexModel.qml b/package/contents/ui/KomplexModel.qml index 996841d..59cab8b 100644 --- a/package/contents/ui/KomplexModel.qml +++ b/package/contents/ui/KomplexModel.qml @@ -28,11 +28,11 @@ import QtQuick import com.github.digitalartifex.komplex 1.0 as Komplex -Item +Rectangle { property var screenGeometry property real pixelRatio: 1 //This will (hopefully) be set to PlasmaCore.Units.devicePixelRatio in onCompleted - property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x ? wallpaper.configuration.resolution_x : 1920, wallpaper.configuration.resolution_y ? wallpaper.configuration.resolution_y : 1080, 1)//width, height, pixel aspect ratio + property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x, wallpaper.configuration.resolution_y, 1)//width, height, pixel aspect ratio property real iTime: 0 //used by most motion shaders property real iTimeDelta: iTime property var iChannelTime: [iTime, iTime, iTime, iTime] //individual channel time values @@ -41,7 +41,7 @@ Item property real iFrameRate: wallpaper.configuration.framerate_limit ? wallpaper.configuration.framerate_limit : 60 // Default frame rate for the shader property vector4d iMouse property var iDate - property bool running: true + property bool running: windowModel.runShader && wallpaper.configuration.running property bool ready: false @@ -58,19 +58,16 @@ Item property var pack: wallpaper.configuration.shader_package - onPackChanged: ()=> + onPackChanged: () => { if(mainItem.ready) + { shaderPackModel.loadJson(pack) + } } - ShaderChannel { id: bufferA; visible: true; anchors.fill: parent } - ShaderChannel { id: bufferB; visible: true; anchors.fill: parent } - ShaderChannel { id: bufferC; visible: true; anchors.fill: parent } - ShaderChannel { id: bufferD; visible: true; anchors.fill: parent } - - id: mainItem + color: "black" Item { @@ -87,6 +84,11 @@ Item // clean up old channels while(data.channels.length > 0) data.channels.pop().destroy() + + bufferA.source = "" + bufferB.source = "" + bufferC.source = "" + bufferD.source = "" // Handle the JSON change if needed mainItem.parsePack(shaderPackModel.json); @@ -102,23 +104,33 @@ Item Rectangle { - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y color: "black" + id: channelRect // The output channel that combines all the input channels and displays the final shader output // This channel must be set to a shader source file that has been pre-compiled to a QSB Fragment Shader ShaderChannel { + ShaderChannel { id: bufferA; visible: false; anchors.fill: parent } + ShaderChannel { id: bufferB; visible: false; anchors.fill: parent } + ShaderChannel { id: bufferC; visible: false; anchors.fill: parent } + ShaderChannel { id: bufferD; visible: false; anchors.fill: parent } + iTime: mainItem.iTime iMouse: mainItem.iMouse iResolution: mainItem.iResolution + width: mainItem.iResolution.x + height: mainItem.iResolution.y + iFrame: mainItem.iFrame id: channelOutput - anchors.fill: parent type: ShaderChannel.Type.ShaderChannel visible: true // Set to true to display the output z: 9000 + blending: true } // To save on performance, just use one timer for all channels and shaders @@ -131,7 +143,7 @@ Item interval: (1 / mainItem.iFrameRate) * 1000 //fps to ms cycles :: fps = 60 = 1 / 60 = 0.01666 * 1000 = 16 repeat: true - running: true //wallpaper.configuration.running ? mainItem.running : true + running: mainItem.running //wallpaper.configuration.running ? mainItem.running : true triggeredOnStart: true onTriggered: @@ -147,6 +159,27 @@ Item } } + ShaderEffectSource + { + anchors.fill: parent + sourceItem: channelRect + sourceRect: Qt.rect(0,0, mainItem.iResolution.x, mainItem.iResolution.y) + textureSize: Qt.size(mainItem.iResolution.x, mainItem.iResolution.y) + hideSource: true + visible: true + smooth: true + antialiasing: true + live: true + + id: finalSource + + onSourceRectChanged: () => + { + live = false; + live = true; + } + } + // Load the default shader pack configuration on component completion Component.onCompleted: { @@ -158,6 +191,44 @@ Item if(wallpaper.configuration.shader_package) shaderPackModel.loadJson(wallpaper.configuration.shader_package); + Qt.createQmlObject(`import QtQuick + MouseArea + { + id: mouseTrackingArea + propagateComposedEvents: true + preventStealing: false + enabled: wallpaper.configuration.mouseAllowed + anchors.fill: parent + hoverEnabled: true + onPositionChanged: (mouse) => { + mouse.accepted = false + mainItem.iMouse.x = mouse.x * wallpaper.configuration.mouseSpeedBias + mainItem.iMouse.y = -mouse.y * wallpaper.configuration.mouseSpeedBias + } + onClicked:(mouse) => { + mouse.accepted = false + mainItem.iMouse.z = mouse.x + mainItem.iMouse.w = mouse.y + } + // this still doesnt work... guess a C++ wrapper is all that can be done? + onPressed:(mouse) => { + mouse.accepted = false + } + onPressAndHold:(mouse) => { + mouse.accepted = false + } + onDoubleClicked:(mouse) => { + mouse.accepted = false + } + //cancelled, entered, and exited do not pass mouse events, so we can remove them + onReleased:(mouse) => { + mouse.accepted = false + } + onWheel: (mouse) => { + mouse.accepted = false + } + }`, parent.parent, "mouseTrackerArea"); + ready = true } @@ -168,24 +239,27 @@ Item channel.frameBufferChannel = json.frame_buffer_channel !== undefined ? json.frame_buffer_channel : -1 channel.type = json.type !== undefined ? json.type : typeDefault - channel.anchors.fill = channel.parent + //channel.anchors.fill = channel.parent channel.visible = false channel.iMouse = Qt.binding(() => { return mainItem.iMouse; }) channel.iTime = Qt.binding(() => { return mainItem.iTime; }) - channel.iResolution = Qt.binding(() => { return Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0); }) + channel.iResolutionScale = json.resolution_scale ? json.resolution_scale : 1.0 + channel.iResolution = Qt.binding(() => { return json.resolution_x ? Qt.vector3d(json.resolution_x, json.resolution_y, 1.0) : Qt.vector3d(mainItem.iResolution.x,mainItem.iResolution.y,1.0); }) channel.mouseBias = json.mouse_scale ? json.mouse_scale : 1.0 channel.iTimeScale = json.time_scale ? json.time_scale : 1.0 channel.iTimeDelta = Qt.binding(() => { return mainItem.iTimeDelta; }) + channel.width = mainItem.iResolution.x + channel.height = mainItem.iResolution.y - channel.iChannelResolution = Qt.binding(() => { - return [ - Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), - Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), - Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), - Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0) - ]; - }); - + // channel.iChannelResolution = Qt.binding(() => { + // return [ + // Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + // Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + // Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0), + // Qt.vector3d(json.resolution_x || mainItem.width, json.resolution_y || mainItem.height, 1.0) + // ]; + // }); + channel.iChannelTime = Qt.binding(() => { return [ mainItem.iTime * channel.iTimeScale, @@ -196,7 +270,7 @@ Item }); channel.iFrameRate = Qt.binding(() => { return mainItem.iFrameRate; }) - channel.iFrame = Qt.binding(() => { return mainItem.iFrame; }) + channel.iFrame = mainItem.iFrame channel.invert = json.invert ? json.invert : false channel.source = source @@ -347,6 +421,8 @@ Item recursive: false, mipmap: false }); + + data.channels.push(result) // save for destroying } return result; @@ -371,4 +447,4 @@ Item else if(!source.startsWith("file://")) return "file://" + source; } -} +} \ No newline at end of file diff --git a/package/contents/ui/ShaderChannel.qml b/package/contents/ui/ShaderChannel.qml index 46ff47a..1c5a798 100644 --- a/package/contents/ui/ShaderChannel.qml +++ b/package/contents/ui/ShaderChannel.qml @@ -69,10 +69,29 @@ Item property var iDate property real iTimeScale: 1 // This is used to scale the time for the shader, allowing for slow motion or fast forward effects per channel property int frameBufferChannel: -1 + property bool blending: false + + // bind to ShaderEffectSource.live to prevent data being updated causing a refresh between intended frames. I think this may be why + // the shaders are using so many resources. This is likely to cause issues of its own since we have no way of knowing the progress + // of the current capture, but we'll cross that bridge later + property bool active: true + + // this seems to work better than doubling the timer frequency and setting active/inactive states, + // but god damn does it feel hacky. Try to find a better way to actually limit framerate + onIFrameChanged: () => + { + active = true; + active = false; + } property bool invert - property var iChannelResolution: [Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1), Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1), Qt.vector3d(channel.width * iResolutionScale, channel.height * iResolutionScale, 1)] + property var iChannelResolution: [Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1)] + + onIResolutionChanged: () => + { + channel.iChannelResolution = [Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1), Qt.vector3d(channel.iResolution.x * iResolutionScale, channel.iResolution.y * iResolutionScale, 1)] + } QtObject { @@ -142,8 +161,9 @@ Item { loader.sourceComponent: channelAudio - loader.width: 512 - loader.height: 2 + // loader.width: 512 + // loader.height: 2 + // loader.and } } ] @@ -251,7 +271,6 @@ Item Item { - property var frameBufferData: undefined id: channelShaderContent anchors.fill: parent @@ -261,72 +280,85 @@ Item { id: channelSource0 sourceItem: channel.iChannel0 ? channel.iChannel0 : null - live: true - smooth: true - sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) - wrapMode: ShaderEffectSource.Repeat - textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + live: channel.active + smooth: false + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + wrapMode: ShaderEffectSource.ClampToEdge + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) textureMirroring: ShaderEffectSource.NoMirroring - recursive: true + recursive: false mipmap: true + hideSource: true + width: channel.iResolution.x + height: channel.iResolution.y } ShaderEffectSource { id: channelSource1 sourceItem: channel.iChannel1 ? channel.iChannel1 : null - live: true - smooth: true - sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) - wrapMode: ShaderEffectSource.Repeat - textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + live: channel.active + smooth: false + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + wrapMode: ShaderEffectSource.ClampToEdge + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) textureMirroring: ShaderEffectSource.NoMirroring - recursive: true + recursive: false mipmap: true + hideSource: true + width: channel.iResolution.x + height: channel.iResolution.y } ShaderEffectSource { id: channelSource2 sourceItem: channel.iChannel2 ? channel.iChannel2 : null - live: true - smooth: true - sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) - wrapMode: ShaderEffectSource.Repeat - textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + live: channel.active + smooth: false + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + wrapMode: ShaderEffectSource.ClampToEdge + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) textureMirroring: ShaderEffectSource.NoMirroring - recursive: true + recursive: false mipmap: true + hideSource: true + width: channel.iResolution.x + height: channel.iResolution.y } ShaderEffectSource { id: channelSource3 sourceItem: channel.iChannel3 ? channel.iChannel3 : null - live: true - smooth: true - sourceRect: Qt.rect(0,0, sourceItem ? sourceItem.width : 0, sourceItem ? sourceItem.height : 0) - wrapMode: ShaderEffectSource.Repeat - textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) + live: channel.active + smooth: false + sourceRect: sourceItem ? Qt.rect(0,0, sourceItem.width, sourceItem.height) : Qt.rect(0,0,0,0) + wrapMode: ShaderEffectSource.ClampToEdge + textureSize: Qt.size(channel.iResolution.x, channel.iResolution.y) textureMirroring: ShaderEffectSource.NoMirroring - recursive: true + recursive: false mipmap: true + hideSource: true + width: channel.iResolution.x + height: channel.iResolution.y } // recursive frame buffer ShaderEffectSource { id: frameBufferSource - sourceItem: channelShaderContent - live: true + sourceItem: channel.frameBufferChannel === -1 ? null : channelShaderContent sourceRect: Qt.rect(0,0, channelShaderContent.width, channelShaderContent.height) - wrapMode: ShaderEffectSource.Repeat - recursive: true + wrapMode: ShaderEffectSource.ClampToEdge + live: channel.active mipmap: true + recursive: true textureSize: Qt.size(channelShaderContent.width, channelShaderContent.height) - anchors.fill: parent visible: false textureMirroring: ShaderEffectSource.NoMirroring + width: channel.iResolution.x + height: channel.iResolution.y } // The shader effect that will be used to render the shader @@ -350,10 +382,21 @@ Item property var iChannelResolution: channel.iResolution fragmentShader: Qt.resolvedUrl(channel.source) - anchors.fill: parent + width: channel.iResolution.x + height: channel.iResolution.y id: channelShaderOutput + + blending: channel.blending } + + // ShaderEffectSource + // { + // anchors.fill: parent + // sourceItem: channelShaderOutput + // hideSource: true + // visible: true + // } } } @@ -430,11 +473,29 @@ Item { width: 512 height: 2 - anchors.top: channel.invert ? undefined : parent.top - anchors.bottom: channel.invert ? parent.bottom : undefined + anchors.top: !channel.invert ? undefined : parent.top + anchors.bottom: !channel.invert ? parent.bottom : undefined id: textureImage source: "image://audiotexture/frame" - fillMode: Image.PreserveAspectFit + fillMode: Image.Pad + + // we need to flip the texture when the channel itself is flipped + // so the orientation of the audio data is preserved + transform: Rotation + { + origin.x: textureImage.width / 2 + origin.y: textureImage.height / 2 + + // For vertical flipping, we need to transform the x axis + axis + { + x: 1 + y: 0 + z: 0 + } + + angle: data.angle + 180 + } } Timer diff --git a/package/contents/ui/ShaderChannelConfiguration.qml b/package/contents/ui/ShaderChannelConfiguration.qml index d2b9031..ab8a366 100644 --- a/package/contents/ui/ShaderChannelConfiguration.qml +++ b/package/contents/ui/ShaderChannelConfiguration.qml @@ -339,7 +339,7 @@ Item id: speedSlider Layout.fillWidth: true from: 0 - to: 16 + to: 4 stepSize: 0.1 onValueChanged: shaderSpeedField.text = String(value.toFixed(2)); } diff --git a/package/contents/ui/ShaderToyModel.qml b/package/contents/ui/ShaderToyModel.qml index d256794..bc3e4bb 100644 --- a/package/contents/ui/ShaderToyModel.qml +++ b/package/contents/ui/ShaderToyModel.qml @@ -37,7 +37,7 @@ Item { property var screenGeometry property real pixelRatio: 1 //This will (hopefully) be set to PlasmaCore.Units.devicePixelRatio in onCompleted - property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x,wallpaper.configuration.resolution_y,1)//width, height, pixel aspect ratio + property vector3d iResolution: Qt.vector3d(wallpaper.configuration.resolution_x || mainItem.width,wallpaper.configuration.resolution_y || mainItem.height,1)//width, height, pixel aspect ratio property real iTime: 0 //used by most motion shaders property real iTimeDelta: iTime property var iChannelTime: [iTime, iTime, iTime, iTime] //individual channel time values @@ -84,9 +84,11 @@ Item iTime: mainItem.iTime iMouse: mainItem.iMouse iResolution: mainItem.iChannelResolution[0] + iFrame: mainItem.iFrame id: channel0 - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y type: wallpaper.configuration.iChannel0_flag ? wallpaper.configuration.iChannel0_type : 0 source: wallpaper.configuration.iChannel0_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel0) : "" @@ -101,9 +103,11 @@ Item visible: wallpaper.configuration.iChannel1_flag && (channelOutput.source === "" || channelOutput.source === undefined) iTime: mainItem.iTime iResolution: mainItem.iChannelResolution[1] + iFrame: mainItem.iFrame id: channel1 - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y type: wallpaper.configuration.iChannel1_flag ? wallpaper.configuration.iChannel1_type : 0 source: wallpaper.configuration.iChannel1_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel1) : "" @@ -118,9 +122,11 @@ Item visible: wallpaper.configuration.iChannel2_flag && (channelOutput.source === "" || channelOutput.source === undefined) iTime: mainItem.iTime iResolution: mainItem.iChannelResolution[2] + iFrame: mainItem.iFrame id: channel2 - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y type: wallpaper.configuration.iChannel2_flag ? wallpaper.configuration.iChannel2_type : 0 source: wallpaper.configuration.iChannel2_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel2) : "" @@ -137,9 +143,11 @@ Item iChannelTime: [mainItem.iTime, mainItem.iTime, mainItem.iTime, mainItem.iTime] iResolution: mainItem.iChannelResolution[3] iDate: mainItem.iDate + iFrame: mainItem.iFrame id: channel3 - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y type: wallpaper.configuration.iChannel3_flag ? wallpaper.configuration.iChannel3_type : 0 source: wallpaper.configuration.iChannel3_flag ? Qt.resolvedUrl(wallpaper.configuration.iChannel3) : "" @@ -155,9 +163,11 @@ Item iTime: mainItem.iTime iMouse: mainItem.iMouse iResolution: mainItem.iResolution + iFrame: mainItem.iFrame id: channelOutput - anchors.fill: parent + width: mainItem.iResolution.x + height: mainItem.iResolution.y type: ShaderChannel.Type.ShaderChannel source: wallpaper.configuration.selectedShaderPath ? wallpaper.configuration.selectedShaderPath : "" @@ -167,11 +177,27 @@ Item iChannel3: channel3 visible: true // Set to true to display the output + blending: true + } + + ShaderEffectSource + { + anchors.fill: parent + sourceItem: channelOutput + sourceRect: Qt.rect(0,0, mainItem.iResolution.x, mainItem.iResolution.y) + textureSize: Qt.size(mainItem.iResolution.x, mainItem.iResolution.y) + hideSource: true + visible: true + smooth: true + live: true + + id: finalSource } // To save on performance, just use one timer for all channels Timer { + property var date: new Date(); id: channelTimer //Not entirely sure if this will actually limit the frame rate @@ -183,7 +209,6 @@ Item triggeredOnStart: true onTriggered: { - var date = new Date(); var startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); var secondsSinceMidnight = (date - startOfDay) / 1000; diff --git a/package/contents/ui/config.qml b/package/contents/ui/config.qml index da378a7..8915be2 100644 --- a/package/contents/ui/config.qml +++ b/package/contents/ui/config.qml @@ -93,6 +93,8 @@ Kirigami.FormLayout property alias cfg_resolution_x: resolutionXField.value property alias cfg_resolution_y: resolutionYField.value + property alias cfg_framerate_limit: frameRateField.value + Palette { id: palette @@ -116,7 +118,7 @@ Kirigami.FormLayout Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Engine Mode:") ComboBox { - Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + Layout.preferredWidth: Kirigami.Units.gridUnit * 11.5 id: engineModeSelect currentIndex: root.cfg_komplex_mode onCurrentIndexChanged: root.cfg_komplex_mode = currentIndex @@ -141,7 +143,7 @@ Kirigami.FormLayout property string shader id: selectedShader - Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + Layout.preferredWidth: Kirigami.Units.gridUnit * 11.5 model: FolderListModel { id: folderListModel @@ -182,8 +184,8 @@ Kirigami.FormLayout id: shaderFileButton icon.name: "folder-symbolic" text: i18nd("@button:toggle_select_shader", "Select File") - Layout.preferredWidth: Kirigami.Units.gridUnit * 9 - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + Layout.preferredWidth: Kirigami.Units.gridUnit * 8.5 + Layout.preferredHeight: selectedShader.height onClicked: { fileDialog.currentFolder = "file://" + shaderPackModel.shadersPath; @@ -220,7 +222,7 @@ Kirigami.FormLayout property string shader id: selectedShaderPack - Layout.preferredWidth: Kirigami.Units.gridUnit * 11 + Layout.preferredWidth: Kirigami.Units.gridUnit * 11.5 model: shaderPackModel.availableShaderPacks delegate: Component { @@ -254,8 +256,8 @@ Kirigami.FormLayout id: packFileButton icon.name: "folder-symbolic" text: i18nd("@button:toggle_select_shader", "Select File") - Layout.preferredWidth: Kirigami.Units.gridUnit * 9 - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 + Layout.preferredWidth: Kirigami.Units.gridUnit * 8.5 + Layout.preferredHeight: selectedShaderPack.height onClicked: { packDialog.currentFolder = "file://" + shaderPackModel.shaderPackInstallPath; @@ -280,8 +282,13 @@ Kirigami.FormLayout } } } + Kirigami.Separator + { + Kirigami.FormData.isSection: false + } TabBar { + Layout.topMargin: 6 Layout.fillWidth: true id: navBar width: parent.width @@ -352,7 +359,7 @@ Kirigami.FormLayout { id: shaderChannelOverlay0 parent: applicationWindow().overlay - implicitHeight: 400 + implicitHeight: 420 ShaderChannelConfiguration { @@ -398,7 +405,7 @@ Kirigami.FormLayout { id: shaderChannelOverlay1 parent: applicationWindow().overlay - implicitHeight: 400 + implicitHeight: 420 ShaderChannelConfiguration { @@ -443,7 +450,7 @@ Kirigami.FormLayout { id: shaderChannelOverlay2 parent: applicationWindow().overlay - implicitHeight: 400 + implicitHeight: 420 ShaderChannelConfiguration { @@ -487,7 +494,7 @@ Kirigami.FormLayout { id: shaderChannelOverlay3 parent: applicationWindow().overlay - implicitHeight: 400 + implicitHeight: 420 ShaderChannelConfiguration { @@ -577,6 +584,49 @@ Kirigami.FormLayout } } + RowLayout + { + visible: navBar.currentIndex === 1 + + Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Frame Rate:") + + TextField + { + property int value + + id: frameRateField + inputMethodHints: Qt.ImhFormattedNumbersOnly + Layout.preferredWidth: Kirigami.Units.gridUnit * 4 + + onEditingFinished: () => + { + value = parseInt(text) + } + Keys.onPressed: (event) => + { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) + { + frameRateField.focus = false; // Unfocus the TextField + event.accepted = true; // Prevent further propagation of the key event + } + } + background: Rectangle + { + color: resolutionXField.activeFocus ? palette.base : "transparent" + border.color: resolutionXField.activeFocus ? palette.highlight : "transparent" + border.width: 1 + radius: 4 + anchors.fill: resolutionXField + anchors.margins: -2 + } + + Component.onCompleted: () => + { + text = value + } + } + } + RowLayout { visible: navBar.currentIndex === 1 @@ -589,8 +639,8 @@ Kirigami.FormLayout { id: speedSlider Layout.fillWidth: true - from: -10.0 - to: 10.0 + from: -4.0 + to: 4.0 stepSize: 0.01 onValueChanged: shaderSpeedField.text = String(value.toFixed(2)); } @@ -699,7 +749,7 @@ Kirigami.FormLayout } } - RowLayout + RowLayout { visible: navBar.currentIndex === 2 id: mouseLayout @@ -716,20 +766,20 @@ Kirigami.FormLayout } } - RowLayout + RowLayout { id: mouseBiasLayout visible: root.cfg_mouseAllowed && navBar.currentIndex === 2 Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Mouse bias:") - ColumnLayout + ColumnLayout { - Slider + Slider { id: mouseBiasSlider Layout.preferredWidth: Kirigami.Units.gridUnit * 16 - from: -10.0 - to: 10.0 + from: 0.0 + to: 4.0 stepSize: 0.01 value: root.cfg_mouseSpeedBias ? root.cfg_mouseSpeedBias : 1.0 onValueChanged: () => @@ -740,7 +790,7 @@ Kirigami.FormLayout } } } - ColumnLayout + ColumnLayout { TextField { diff --git a/package/contents/ui/main.qml b/package/contents/ui/main.qml index 9eb8d43..d9c9e7d 100644 --- a/package/contents/ui/main.qml +++ b/package/contents/ui/main.qml @@ -38,6 +38,10 @@ WallpaperItem id: wallpaperItem Item { + property int resolution_x: wallpaper.configuration.resolution_x + property int resolution_y: wallpaper.configuration.resolution_y + property bool changing: false + anchors.fill: parent Loader @@ -53,7 +57,7 @@ WallpaperItem when: wallpaper.configuration.komplex_mode === 0 PropertyChanges { - pageLoader.sourceComponent: shaderToysContent + pageLoader.sourceComponent: shaderToyContent } }, State @@ -69,7 +73,7 @@ WallpaperItem Component { - id: shaderToysContent + id: shaderToyContent ShaderToyModel { @@ -88,5 +92,39 @@ WallpaperItem anchors.fill: parent } } + + onResolution_xChanged: () => + { + if(changing) + return; + + changing = true + + pageLoader.sourceComponent = null + + if(wallpaper.configuration.komplex_mode === 0) + pageLoader.sourceComponent = shaderToyContent + else + pageLoader.sourceComponent = packContent + + changing = false + } + + onResolution_yChanged: () => + { + if(changing) + return; + + changing = true + + pageLoader.sourceComponent = null + + if(wallpaper.configuration.komplex_mode === 0) + pageLoader.sourceComponent = shaderToyContent + else + pageLoader.sourceComponent = packContent + + changing = false + } } } \ No newline at end of file