2018-07-08 05:15:02 +00:00
import QtQuick 2.9
2018-07-08 17:19:08 +00:00
import QtQuick . Controls 2.2
2018-07-09 05:56:38 +00:00
import StreamingPreferences 1.0
2018-09-09 19:33:19 +00:00
import ComputerManager 1.0
2018-09-30 20:41:32 +00:00
import SdlGamepadKeyNavigation 1.0
2019-03-23 19:05:08 +00:00
import SystemProperties 1.0
2018-07-09 05:56:38 +00:00
2018-11-14 02:03:53 +00:00
Flickable {
2018-07-08 05:15:02 +00:00
id: settingsPage
objectName: "Settings"
2018-11-14 02:03:53 +00:00
2020-02-20 21:38:01 +00:00
boundsBehavior: Flickable . OvershootBounds
2018-11-14 02:03:53 +00:00
contentWidth: settingsColumn1 . width > settingsColumn2 . width ? settingsColumn1.width : settingsColumn2 . width
contentHeight: settingsColumn1 . height > settingsColumn2 . height ? settingsColumn1.height : settingsColumn2 . height
ScrollBar.vertical: ScrollBar {
anchors {
2020-05-10 19:53:27 +00:00
left: parent . right
2018-11-14 02:03:53 +00:00
leftMargin: - 10
}
}
2018-07-08 05:15:02 +00:00
2019-02-23 06:14:06 +00:00
StackView.onActivated: {
2019-05-19 17:16:54 +00:00
// This enables Tab and BackTab based navigation rather than arrow keys.
// It is required to shift focus between controls on the settings page.
SdlGamepadKeyNavigation . setUiNavMode ( true )
2019-05-19 18:08:23 +00:00
// Highlight the first item if a gamepad is connected
if ( SdlGamepadKeyNavigation . getConnectedGamepads ( ) > 0 ) {
resolutionComboBox . forceActiveFocus ( Qt . TabFocus )
}
2018-09-30 20:41:32 +00:00
}
2019-02-23 06:14:06 +00:00
StackView.onDeactivating: {
2019-05-19 17:16:54 +00:00
SdlGamepadKeyNavigation . setUiNavMode ( false )
2019-03-28 01:13:20 +00:00
// Save the prefs so the Session can observe the changes
StreamingPreferences . save ( )
2018-07-09 05:56:38 +00:00
}
2018-07-08 17:19:08 +00:00
Column {
2018-07-20 22:47:50 +00:00
padding: 10
id: settingsColumn1
2020-05-10 19:30:15 +00:00
width: settingsPage . width / 2
spacing: 15
2018-07-08 17:19:08 +00:00
GroupBox {
2018-07-08 18:12:22 +00:00
id: basicSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-07-08 17:19:08 +00:00
padding: 12
2018-07-08 18:20:56 +00:00
title: "<font color=\"skyblue\">Basic Settings</font>"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2018-07-08 17:19:08 +00:00
Column {
anchors.fill: parent
spacing: 5
Label {
width: parent . width
id: resFPStitle
2018-07-28 08:22:31 +00:00
text: qsTr ( "Resolution and FPS" )
2018-07-08 17:19:08 +00:00
font.pointSize: 12
2018-11-22 10:35:25 +00:00
wrapMode: Text . Wrap
2018-07-08 17:19:08 +00:00
}
Label {
width: parent . width
id: resFPSdesc
2018-11-04 22:36:12 +00:00
text: qsTr ( "Setting values too high for your PC or network connection may cause lag, stuttering, or errors." )
2018-07-08 17:19:08 +00:00
font.pointSize: 9
wrapMode: Text . Wrap
}
2018-07-28 08:22:31 +00:00
Row {
spacing: 5
2020-05-10 18:12:37 +00:00
width: parent . width
2018-07-28 08:22:31 +00:00
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-07-28 08:22:31 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
2018-08-05 21:55:26 +00:00
// Add native resolutions for all attached displays
2018-09-04 04:21:37 +00:00
var done = false
for ( var displayIndex = 0 ; ! done ; displayIndex ++ ) {
for ( var displayResIndex = 0 ; displayResIndex < 2 ; displayResIndex ++ ) {
var screenRect ;
2018-08-05 21:55:26 +00:00
2018-09-04 04:21:37 +00:00
// Some platforms have different desktop resolutions
// and native resolutions (like macOS with Retina displays)
2020-02-09 05:31:04 +00:00
if ( displayResIndex === 0 ) {
2019-03-23 19:05:08 +00:00
screenRect = SystemProperties . getDesktopResolution ( displayIndex )
2018-09-04 04:21:37 +00:00
}
else {
2019-03-23 19:05:08 +00:00
screenRect = SystemProperties . getNativeResolution ( displayIndex )
2018-09-04 04:21:37 +00:00
}
2018-08-05 21:55:26 +00:00
2018-09-04 04:21:37 +00:00
if ( screenRect . width === 0 ) {
// Exceeded max count of displays
done = true
2018-08-05 21:55:26 +00:00
break
}
2018-09-04 04:21:37 +00:00
var indexToAdd = 0
for ( var j = 0 ; j < resolutionComboBox . count ; j ++ ) {
var existing_width = parseInt ( resolutionListModel . get ( j ) . video_width ) ;
var existing_height = parseInt ( resolutionListModel . get ( j ) . video_height ) ;
if ( screenRect . width === existing_width && screenRect . height === existing_height ) {
// Duplicate entry, skip
indexToAdd = - 1
break
}
else if ( screenRect . width * screenRect . height > existing_width * existing_height ) {
// Candidate entrypoint after this entry
indexToAdd = j + 1
}
2018-08-05 21:55:26 +00:00
}
2018-09-04 04:21:37 +00:00
// Insert this display's resolution if it's not a duplicate
if ( indexToAdd >= 0 ) {
resolutionListModel . insert ( indexToAdd ,
{
"text" : "Native (" + screenRect . width + "x" + screenRect . height + ")" ,
"video_width" : "" + screenRect . width ,
"video_height" : "" + screenRect . height
} )
}
2018-08-05 21:55:26 +00:00
}
}
2020-02-23 08:43:43 +00:00
// Prune resolutions that are over the decoder's maximum
var max_pixels = SystemProperties . maximumResolution . width * SystemProperties . maximumResolution . height ;
if ( max_pixels > 0 ) {
for ( var j = 0 ; j < resolutionComboBox . count ; j ++ ) {
var existing_width = parseInt ( resolutionListModel . get ( j ) . video_width ) ;
var existing_height = parseInt ( resolutionListModel . get ( j ) . video_height ) ;
if ( existing_width * existing_height > max_pixels ) {
resolutionListModel . remove ( j )
j --
}
}
}
2018-07-28 08:22:31 +00:00
// load the saved width/height, and iterate through the ComboBox until a match is found
// and set it to that index.
2019-03-28 01:13:20 +00:00
var saved_width = StreamingPreferences . width
var saved_height = StreamingPreferences . height
2018-07-28 08:22:31 +00:00
currentIndex = 0
2018-09-08 21:33:34 +00:00
for ( var i = 0 ; i < resolutionListModel . count ; i ++ ) {
2018-07-28 08:22:31 +00:00
var el_width = parseInt ( resolutionListModel . get ( i ) . video_width ) ;
var el_height = parseInt ( resolutionListModel . get ( i ) . video_height ) ;
2018-08-05 21:55:26 +00:00
// Pick the highest value lesser or equal to the saved resolution
if ( saved_width * saved_height >= el_width * el_height ) {
2018-07-28 08:22:31 +00:00
currentIndex = i
}
}
2018-09-08 06:16:13 +00:00
// Persist the selected value
activated ( currentIndex )
2018-07-16 01:27:41 +00:00
}
2018-07-28 08:22:31 +00:00
id: resolutionComboBox
2020-05-10 18:12:37 +00:00
maximumWidth: parent . width / 2
2018-07-28 08:22:31 +00:00
textRole: "text"
model: ListModel {
id: resolutionListModel
2018-08-05 21:55:26 +00:00
// Other elements may be added at runtime
// based on attached display resolution
2018-07-28 08:22:31 +00:00
ListElement {
text: "720p"
video_width: "1280"
video_height: "720"
}
ListElement {
text: "1080p"
video_width: "1920"
video_height: "1080"
}
ListElement {
text: "1440p"
video_width: "2560"
video_height: "1440"
}
ListElement {
text: "4K"
video_width: "3840"
video_height: "2160"
}
2018-07-16 01:27:41 +00:00
}
2018-07-28 08:22:31 +00:00
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
2018-09-08 06:16:13 +00:00
var selectedWidth = parseInt ( resolutionListModel . get ( currentIndex ) . video_width )
var selectedHeight = parseInt ( resolutionListModel . get ( currentIndex ) . video_height )
// Only modify the bitrate if the values actually changed
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . width !== selectedWidth || StreamingPreferences . height !== selectedHeight ) {
StreamingPreferences . width = selectedWidth
StreamingPreferences . height = selectedHeight
StreamingPreferences . bitrateKbps = StreamingPreferences . getDefaultBitrate ( StreamingPreferences . width ,
StreamingPreferences . height ,
StreamingPreferences . fps ) ;
slider . value = StreamingPreferences . bitrateKbps
2018-09-08 06:16:13 +00:00
}
2018-07-16 01:27:41 +00:00
}
2018-07-28 08:22:31 +00:00
}
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-09-08 21:33:34 +00:00
function createModel ( ) {
var fpsListModel = Qt . createQmlObject ( 'import QtQuick 2.0; ListModel {}' , parent , '' )
2019-03-24 03:25:19 +00:00
var max_fps = SystemProperties . maximumStreamingFrameRate
2018-09-08 21:33:34 +00:00
// Default entries
fpsListModel . append ( { "text" : "30 FPS" , "video_fps" : "30" } )
fpsListModel . append ( { "text" : "60 FPS" , "video_fps" : "60" } )
2018-09-08 22:09:46 +00:00
// Add unsupported FPS values that come before the display max FPS
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . unsupportedFps ) {
2019-03-24 03:25:19 +00:00
if ( max_fps > 90 ) {
2018-09-08 22:09:46 +00:00
fpsListModel . append ( { "text" : "90 FPS (Unsupported)" , "video_fps" : "90" } )
}
2019-03-24 03:25:19 +00:00
if ( max_fps > 120 ) {
2018-09-08 22:09:46 +00:00
fpsListModel . append ( { "text" : "120 FPS (Unsupported)" , "video_fps" : "120" } )
}
}
2018-07-28 08:22:31 +00:00
// Use 64 as the cutoff for adding a separate option to
// handle wonky displays that report just over 60 Hz.
2019-03-24 03:25:19 +00:00
if ( max_fps > 64 ) {
2018-11-21 05:47:08 +00:00
// Mark any FPS value greater than 120 as unsupported
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . unsupportedFps && max_fps > 120 ) {
2018-11-21 05:47:08 +00:00
fpsListModel . append ( { "text" : max_fps + " FPS (Unsupported)" , "video_fps" : "" + max_fps } )
}
2019-03-24 03:25:19 +00:00
else if ( max_fps > 120 ) {
2018-11-21 05:47:08 +00:00
fpsListModel . append ( { "text" : "120 FPS" , "video_fps" : "120" } )
}
else {
fpsListModel . append ( { "text" : max_fps + " FPS" , "video_fps" : "" + max_fps } )
}
2018-07-28 08:22:31 +00:00
}
2018-09-08 22:09:46 +00:00
// Add unsupported FPS values that come after the display max FPS
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . unsupportedFps ) {
2019-03-24 03:25:19 +00:00
if ( max_fps < 90 ) {
2018-09-08 21:33:34 +00:00
fpsListModel . append ( { "text" : "90 FPS (Unsupported)" , "video_fps" : "90" } )
}
2019-03-24 03:25:19 +00:00
if ( max_fps < 120 ) {
2018-09-08 21:33:34 +00:00
fpsListModel . append ( { "text" : "120 FPS (Unsupported)" , "video_fps" : "120" } )
}
}
return fpsListModel
}
function reinitialize ( ) {
model = createModel ( )
2019-03-28 01:13:20 +00:00
var saved_fps = StreamingPreferences . fps
2018-07-28 08:22:31 +00:00
currentIndex = 0
2018-09-08 21:33:34 +00:00
for ( var i = 0 ; i < model . count ; i ++ ) {
var el_fps = parseInt ( model . get ( i ) . video_fps ) ;
2018-08-05 21:55:26 +00:00
// Pick the highest value lesser or equal to the saved FPS
2018-08-05 22:09:36 +00:00
if ( saved_fps >= el_fps ) {
2018-07-28 08:22:31 +00:00
currentIndex = i
}
}
2018-09-08 06:16:13 +00:00
// Persist the selected value
activated ( currentIndex )
2018-07-16 01:27:41 +00:00
}
2018-07-28 08:22:31 +00:00
2018-09-08 21:33:34 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
reinitialize ( )
}
2018-07-28 08:22:31 +00:00
id: fpsComboBox
2020-05-10 18:12:37 +00:00
maximumWidth: parent . width / 2
2018-07-28 08:22:31 +00:00
textRole: "text"
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
2018-09-08 21:33:34 +00:00
var selectedFps = parseInt ( model . get ( currentIndex ) . video_fps )
2018-09-08 06:16:13 +00:00
// Only modify the bitrate if the values actually changed
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . fps !== selectedFps ) {
StreamingPreferences . fps = selectedFps
2018-07-28 08:22:31 +00:00
2019-03-28 01:13:20 +00:00
StreamingPreferences . bitrateKbps = StreamingPreferences . getDefaultBitrate ( StreamingPreferences . width ,
StreamingPreferences . height ,
StreamingPreferences . fps ) ;
slider . value = StreamingPreferences . bitrateKbps
2018-09-08 06:16:13 +00:00
}
2018-07-16 01:27:41 +00:00
}
}
2018-07-08 17:19:08 +00:00
}
Label {
width: parent . width
id: bitrateTitle
2018-07-09 05:56:38 +00:00
text: qsTr ( "Video bitrate: " )
2018-07-08 17:19:08 +00:00
font.pointSize: 12
wrapMode: Text . Wrap
}
Label {
width: parent . width
id: bitrateDesc
2018-12-25 19:48:34 +00:00
text: qsTr ( "Lower the bitrate on slower connections. Raise the bitrate to increase image quality." )
2018-07-08 17:19:08 +00:00
font.pointSize: 9
wrapMode: Text . Wrap
}
Slider {
id: slider
2019-03-28 01:13:20 +00:00
value: StreamingPreferences . bitrateKbps
2018-07-18 01:52:06 +00:00
2018-07-08 17:19:08 +00:00
stepSize: 500
from : 500
2018-07-28 08:22:31 +00:00
to: 150000
2018-07-18 01:52:06 +00:00
2018-07-08 17:19:08 +00:00
snapMode: "SnapOnRelease"
width: Math . min ( bitrateDesc . implicitWidth , parent . width )
2018-07-09 05:56:38 +00:00
onValueChanged: {
bitrateTitle . text = "Video bitrate: " + ( value / 1000.0 ) + " Mbps"
2019-03-28 01:13:20 +00:00
StreamingPreferences . bitrateKbps = value
2018-07-08 17:19:08 +00:00
}
}
2018-07-08 18:12:22 +00:00
2018-09-04 02:17:34 +00:00
Label {
width: parent . width
id: windowModeTitle
text: qsTr ( "Display mode" )
font.pointSize: 12
wrapMode: Text . Wrap
}
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-09-04 02:17:34 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
2019-06-29 21:58:27 +00:00
// Set the recommended option based on the OS
for ( var i = 0 ; i < windowModeListModel . count ; i ++ ) {
var thisWm = windowModeListModel . get ( i ) . val ;
if ( thisWm === StreamingPreferences . recommendedFullScreenMode ) {
windowModeListModel . get ( i ) . text += " (Recommended)"
windowModeListModel . move ( i , 0 , 1 ) ;
break
}
}
2018-09-04 02:17:34 +00:00
currentIndex = 0
2020-02-09 05:31:04 +00:00
2020-02-09 19:35:05 +00:00
if ( SystemProperties . hasWindowManager && ! SystemProperties . rendererAlwaysFullScreen ) {
2020-02-09 05:31:04 +00:00
var savedWm = StreamingPreferences . windowMode
for ( var i = 0 ; i < windowModeListModel . count ; i ++ ) {
var thisWm = windowModeListModel . get ( i ) . val ;
if ( savedWm === thisWm ) {
currentIndex = i
break
}
}
2018-08-21 05:25:19 +00:00
}
2020-02-09 05:31:04 +00:00
2018-09-08 06:16:13 +00:00
activated ( currentIndex )
2018-08-21 05:25:19 +00:00
}
2018-09-04 02:17:34 +00:00
id: windowModeComboBox
2020-02-09 19:35:05 +00:00
enabled: SystemProperties . hasWindowManager && ! SystemProperties . rendererAlwaysFullScreen
2018-11-04 22:36:12 +00:00
hoverEnabled: true
2018-09-04 02:17:34 +00:00
textRole: "text"
model: ListModel {
id: windowModeListModel
ListElement {
2019-06-29 21:58:27 +00:00
text: "Full-screen"
2018-09-04 02:17:34 +00:00
val: StreamingPreferences . WM_FULLSCREEN
}
ListElement {
text: "Borderless windowed"
val: StreamingPreferences . WM_FULLSCREEN_DESKTOP
}
ListElement {
text: "Windowed"
val: StreamingPreferences . WM_WINDOWED
2018-08-21 05:25:19 +00:00
}
2018-07-09 05:56:38 +00:00
}
2018-09-04 02:17:34 +00:00
onActivated: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . windowMode = windowModeListModel . get ( currentIndex ) . val
2018-09-04 02:17:34 +00:00
}
2018-11-04 22:36:12 +00:00
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "Full-screen generally provides the best performance, but borderless windowed may work better with features like macOS Spaces, Alt+Tab, screenshot tools, on-screen overlays, etc."
2018-09-04 02:17:34 +00:00
}
CheckBox {
id: vsyncCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-04 22:36:12 +00:00
hoverEnabled: true
2018-12-25 20:57:00 +00:00
text: "V-Sync"
2018-09-04 02:17:34 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . enableVsync
2018-09-04 02:17:34 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . enableVsync = checked
2018-09-04 02:17:34 +00:00
}
2018-11-04 22:36:12 +00:00
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "Disabling V-Sync allows sub-frame rendering latency, but it can display visible tearing"
2018-07-08 18:12:22 +00:00
}
2018-12-25 20:57:00 +00:00
CheckBox {
id: framePacingCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2018-12-25 20:57:00 +00:00
hoverEnabled: true
text: "Frame pacing"
font.pointSize: 12
2019-03-28 01:13:20 +00:00
enabled: StreamingPreferences . enableVsync
checked: StreamingPreferences . enableVsync && StreamingPreferences . framePacing
2018-12-25 20:57:00 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . framePacing = checked
2018-12-25 20:57:00 +00:00
}
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "Frame pacing reduces micro-stutter by delaying frames that come in too early"
}
2018-07-08 18:12:22 +00:00
}
}
GroupBox {
2018-07-18 02:39:16 +00:00
2018-07-08 18:12:22 +00:00
id: audioSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-07-08 18:12:22 +00:00
padding: 12
2018-07-08 18:20:56 +00:00
title: "<font color=\"skyblue\">Audio Settings</font>"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
Column {
anchors.fill: parent
spacing: 5
2018-07-20 21:35:47 +00:00
Label {
width: parent . width
id: resAudioTitle
text: qsTr ( "Audio configuration" )
font.pointSize: 12
wrapMode: Text . Wrap
}
2018-07-18 02:39:16 +00:00
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-07-20 21:35:47 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
2019-03-28 01:13:20 +00:00
var saved_audio = StreamingPreferences . audioConfig
2018-07-20 21:35:47 +00:00
currentIndex = 0
2018-09-08 06:16:13 +00:00
for ( var i = 0 ; i < audioListModel . count ; i ++ ) {
var el_audio = audioListModel . get ( i ) . val ;
if ( saved_audio === el_audio ) {
currentIndex = i
break
}
2018-07-20 21:35:47 +00:00
}
2018-09-08 06:16:13 +00:00
activated ( currentIndex )
2018-07-20 21:35:47 +00:00
}
2018-07-18 02:39:16 +00:00
2018-07-20 21:35:47 +00:00
id: audioComboBox
textRole: "text"
model: ListModel {
id: audioListModel
ListElement {
2018-07-28 10:06:11 +00:00
text: "Stereo"
2018-10-02 22:30:22 +00:00
val: StreamingPreferences . AC_STEREO
2018-07-20 21:35:47 +00:00
}
ListElement {
2018-07-28 10:06:11 +00:00
text: "5.1 surround sound"
2018-10-02 22:30:22 +00:00
val: StreamingPreferences . AC_51_SURROUND
2018-07-20 21:35:47 +00:00
}
2020-04-03 07:12:52 +00:00
ListElement {
text: "7.1 surround sound"
val: StreamingPreferences . AC_71_SURROUND
}
2018-07-20 21:35:47 +00:00
}
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
2019-03-28 01:13:20 +00:00
StreamingPreferences . audioConfig = audioListModel . get ( currentIndex ) . val
2018-07-18 02:39:16 +00:00
}
2018-07-08 18:12:22 +00:00
}
2018-07-20 21:35:47 +00:00
2018-07-08 18:12:22 +00:00
}
}
2018-11-16 00:41:02 +00:00
GroupBox {
id: uiSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-11-16 00:41:02 +00:00
padding: 12
title: "<font color=\"skyblue\">UI Settings</font>"
font.pointSize: 12
Column {
anchors.fill: parent
spacing: 5
CheckBox {
2018-11-29 05:46:14 +00:00
id: startMaximizedCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-29 05:46:14 +00:00
text: "Maximize Moonlight window on startup"
2018-11-16 00:41:02 +00:00
font.pointSize: 12
2020-02-09 05:31:04 +00:00
enabled: SystemProperties . hasWindowManager
checked: ! StreamingPreferences . startWindowed || ! SystemProperties . hasWindowManager
2018-11-16 00:41:02 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . startWindowed = ! checked
2018-11-16 00:41:02 +00:00
}
}
2019-03-19 03:21:52 +00:00
CheckBox {
id: connectionWarningsCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2019-03-19 03:21:52 +00:00
text: "Show connection quality warnings"
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . connectionWarnings
2019-03-19 03:21:52 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . connectionWarnings = checked
2019-03-19 03:21:52 +00:00
}
}
2019-06-30 00:40:30 +00:00
CheckBox {
visible: SystemProperties . hasDiscordIntegration
id: discordPresenceCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2019-06-30 00:40:30 +00:00
text: "Discord Rich Presence integration"
font.pointSize: 12
checked: StreamingPreferences . richPresence
onCheckedChanged: {
StreamingPreferences . richPresence = checked
}
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "Updates your Discord status to display the name of the game you're streaming."
}
2018-11-16 00:41:02 +00:00
}
}
2018-07-20 22:47:50 +00:00
}
Column {
padding: 10
2020-05-10 20:02:10 +00:00
rightPadding: 20
2018-07-20 22:47:50 +00:00
anchors.left: settingsColumn1 . right
id: settingsColumn2
2020-05-10 19:30:15 +00:00
width: settingsPage . width / 2
spacing: 15
2018-07-08 18:12:22 +00:00
GroupBox {
id: gamepadSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-07-08 18:12:22 +00:00
padding: 12
2018-09-09 20:21:11 +00:00
title: "<font color=\"skyblue\">Input Settings</font>"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2018-11-16 00:41:02 +00:00
Column {
2018-07-08 18:12:22 +00:00
anchors.fill: parent
spacing: 5
CheckBox {
2018-11-30 04:10:47 +00:00
id: singleControllerCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-30 04:10:47 +00:00
text: "Force gamepad #1 always present"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: ! StreamingPreferences . multiController
2018-07-09 05:56:38 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . multiController = ! checked
2018-07-09 05:56:38 +00:00
}
2018-11-30 04:10:47 +00:00
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "Forces a single gamepad to always stay connected to the host, even if no gamepads are actually connected to this PC.\n" +
"Only enable this option when streaming a game that doesn't support gamepads being connected after startup."
2018-07-08 18:12:22 +00:00
}
2018-09-09 20:21:11 +00:00
CheckBox {
2020-04-25 20:00:39 +00:00
id: absoluteMouseCheck
2018-11-04 21:31:28 +00:00
hoverEnabled: true
2020-05-10 18:12:37 +00:00
width: parent . width
2020-04-25 20:00:39 +00:00
text: "Optimize mouse for remote desktop instead of games"
2018-09-09 20:21:11 +00:00
font.pointSize: 12
2020-04-25 20:04:22 +00:00
enabled: SystemProperties . hasWindowManager
checked: StreamingPreferences . absoluteMouseMode && SystemProperties . hasWindowManager
2018-09-09 20:21:11 +00:00
onCheckedChanged: {
2020-04-25 20:00:39 +00:00
StreamingPreferences . absoluteMouseMode = checked
2018-09-09 20:21:11 +00:00
}
2018-11-04 21:31:28 +00:00
ToolTip.delay: 1000
2020-04-25 20:00:39 +00:00
ToolTip.timeout: 5000
2018-11-04 21:31:28 +00:00
ToolTip.visible: hovered
2020-04-25 20:00:39 +00:00
ToolTip.text: " This enables mouse control without capturing the client ' s mouse cursor . It will not work in most games . \ n
You can toggle this while streaming using Ctrl + Alt + Shift + M . "
2018-09-09 20:21:11 +00:00
}
2019-06-30 01:24:59 +00:00
2020-05-01 03:55:15 +00:00
CheckBox {
id: absoluteTouchCheck
hoverEnabled: true
2020-05-10 18:12:37 +00:00
width: parent . width
2020-05-01 03:55:15 +00:00
text: "Use touchscreen as a trackpad"
font.pointSize: 12
checked: ! StreamingPreferences . absoluteTouchMode
onCheckedChanged: {
StreamingPreferences . absoluteTouchMode = ! checked
}
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "When checked, the touchscreen acts like a trackpad. When unchecked, the touchscreen will directly control the mouse pointer."
}
2019-06-30 01:24:59 +00:00
CheckBox {
id: gamepadMouseCheck
hoverEnabled: true
2020-05-10 18:12:37 +00:00
width: parent . width
2019-06-30 01:24:59 +00:00
text: "Gamepad mouse mode support"
font.pointSize: 12
checked: StreamingPreferences . gamepadMouse
onCheckedChanged: {
StreamingPreferences . gamepadMouse = checked
}
ToolTip.delay: 1000
ToolTip.timeout: 3000
ToolTip.visible: hovered
ToolTip.text: "When enabled, holding the Start button will toggle mouse mode"
}
2018-07-08 18:12:22 +00:00
}
}
GroupBox {
id: hostSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-07-08 18:12:22 +00:00
padding: 12
2018-07-08 18:20:56 +00:00
title: "<font color=\"skyblue\">Host Settings</font>"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2018-11-16 00:41:02 +00:00
Column {
2018-07-08 18:12:22 +00:00
anchors.fill: parent
spacing: 5
CheckBox {
id: optimizeGameSettingsCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2020-06-24 05:17:40 +00:00
text: "Optimize game settings for streaming"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . gameOptimizations
2018-07-09 05:56:38 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . gameOptimizations = checked
2018-07-09 05:56:38 +00:00
}
2018-07-08 18:12:22 +00:00
}
CheckBox {
id: audioPcCheck
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-22 10:35:25 +00:00
text: "Play audio on host PC"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . playAudioOnHost
2018-07-09 05:56:38 +00:00
onCheckedChanged: {
2019-03-28 01:13:20 +00:00
StreamingPreferences . playAudioOnHost = checked
2018-07-09 05:56:38 +00:00
}
2018-07-08 18:12:22 +00:00
}
2020-06-24 05:17:40 +00:00
CheckBox {
id: quitAppAfter
width: parent . width
text: "Quit app on host PC after ending stream"
font.pointSize: 12
checked: StreamingPreferences . quitAppAfter
onCheckedChanged: {
StreamingPreferences . quitAppAfter = checked
}
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered
ToolTip.text: "This will close the app or game you are streaming when you end your stream. You will lose any unsaved progress!"
}
2018-07-08 18:12:22 +00:00
}
}
GroupBox {
id: advancedSettingsGroupBox
2020-05-10 20:02:10 +00:00
width: ( parent . width - ( parent . leftPadding + parent . rightPadding ) )
2018-07-08 18:12:22 +00:00
padding: 12
2018-07-08 18:20:56 +00:00
title: "<font color=\"skyblue\">Advanced Settings</font>"
2018-07-08 18:12:22 +00:00
font.pointSize: 12
Column {
anchors.fill: parent
spacing: 5
2018-07-20 21:14:38 +00:00
Label {
width: parent . width
id: resVDSTitle
text: qsTr ( "Video decoder" )
font.pointSize: 12
wrapMode: Text . Wrap
2018-07-08 18:12:22 +00:00
}
2018-07-20 21:14:38 +00:00
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-07-20 21:14:38 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
2019-03-28 01:13:20 +00:00
var saved_vds = StreamingPreferences . videoDecoderSelection
2018-07-20 21:14:38 +00:00
currentIndex = 0
2018-09-08 06:16:13 +00:00
for ( var i = 0 ; i < decoderListModel . count ; i ++ ) {
2018-07-20 21:14:38 +00:00
var el_vds = decoderListModel . get ( i ) . val ;
2018-09-08 06:16:13 +00:00
if ( saved_vds === el_vds ) {
currentIndex = i
break
}
2018-07-20 21:14:38 +00:00
}
2018-09-08 06:16:13 +00:00
activated ( currentIndex )
2018-07-20 21:14:38 +00:00
}
id: decoderComboBox
textRole: "text"
model: ListModel {
id: decoderListModel
ListElement {
2018-07-28 10:06:11 +00:00
text: "Automatic (Recommended)"
2018-07-20 21:14:38 +00:00
val: StreamingPreferences . VDS_AUTO
}
ListElement {
text: "Force software decoding"
val: StreamingPreferences . VDS_FORCE_SOFTWARE
}
ListElement {
text: "Force hardware decoding"
val: StreamingPreferences . VDS_FORCE_HARDWARE
}
}
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
2019-03-28 01:13:20 +00:00
StreamingPreferences . videoDecoderSelection = decoderListModel . get ( currentIndex ) . val
2018-07-20 21:14:38 +00:00
}
}
2018-07-20 21:22:22 +00:00
Label {
width: parent . width
id: resVCCTitle
text: qsTr ( "Video codec" )
font.pointSize: 12
wrapMode: Text . Wrap
}
2018-10-06 19:12:05 +00:00
AutoResizingComboBox {
2018-07-20 21:22:22 +00:00
// ignore setting the index at first, and actually set it when the component is loaded
Component.onCompleted: {
2019-03-28 01:13:20 +00:00
var saved_vcc = StreamingPreferences . videoCodecConfig
2018-07-20 21:22:22 +00:00
currentIndex = 0
for ( var i = 0 ; i < codecListModel . count ; i ++ ) {
var el_vcc = codecListModel . get ( i ) . val ;
2018-09-08 06:16:13 +00:00
if ( saved_vcc === el_vcc ) {
currentIndex = i
break
}
2018-07-20 21:22:22 +00:00
}
2018-09-08 06:16:13 +00:00
activated ( currentIndex )
2018-07-20 21:22:22 +00:00
}
id: codecComboBox
textRole: "text"
model: ListModel {
id: codecListModel
ListElement {
2018-07-28 10:06:11 +00:00
text: "Automatic (Recommended)"
2018-07-20 21:22:22 +00:00
val: StreamingPreferences . VCC_AUTO
}
ListElement {
2019-12-31 00:05:43 +00:00
text: "H.264"
2018-07-20 21:22:22 +00:00
val: StreamingPreferences . VCC_FORCE_H264
}
ListElement {
2019-12-31 00:05:43 +00:00
text: "HEVC (H.265)"
2018-07-20 21:22:22 +00:00
val: StreamingPreferences . VCC_FORCE_HEVC
}
2019-12-31 00:05:43 +00:00
ListElement {
text: "HEVC HDR (Experimental)"
2018-07-20 21:22:22 +00:00
val: StreamingPreferences . VCC_FORCE_HEVC_HDR
2019-12-31 00:05:43 +00:00
}
2018-07-20 21:22:22 +00:00
}
// ::onActivated must be used, as it only listens for when the index is changed by a human
onActivated : {
2019-03-28 01:13:20 +00:00
StreamingPreferences . videoCodecConfig = codecListModel . get ( currentIndex ) . val
2018-07-20 21:22:22 +00:00
}
}
2018-09-08 21:33:34 +00:00
CheckBox {
id: unlockUnsupportedFps
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-22 10:35:25 +00:00
text: "Unlock unsupported FPS options"
2018-09-08 21:33:34 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . unsupportedFps
2018-09-08 21:33:34 +00:00
onCheckedChanged: {
2019-03-25 02:15:35 +00:00
// This is called on init, so only do the work if we've
// actually changed the value.
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . unsupportedFps != checked ) {
StreamingPreferences . unsupportedFps = checked
2019-03-25 02:15:35 +00:00
// The selectable FPS values depend on whether
// this option is enabled or not
fpsComboBox . reinitialize ( )
}
2018-09-08 21:33:34 +00:00
}
}
2018-09-09 19:33:19 +00:00
CheckBox {
id: enableMdns
2020-05-10 18:12:37 +00:00
width: parent . width
2018-11-22 10:35:25 +00:00
text: "Automatically find PCs on the local network (Recommended)"
2018-09-09 19:33:19 +00:00
font.pointSize: 12
2019-03-28 01:13:20 +00:00
checked: StreamingPreferences . enableMdns
2018-09-09 19:33:19 +00:00
onCheckedChanged: {
2019-03-25 02:15:35 +00:00
// This is called on init, so only do the work if we've
// actually changed the value.
2019-03-28 01:13:20 +00:00
if ( StreamingPreferences . enableMdns != checked ) {
StreamingPreferences . enableMdns = checked
2019-03-25 02:15:35 +00:00
// We must save the updated preference to ensure
// ComputerManager can observe the change internally.
2019-03-28 01:13:20 +00:00
StreamingPreferences . save ( )
2019-03-25 02:15:35 +00:00
// Restart polling so the mDNS change takes effect
if ( window . pollingActive ) {
ComputerManager . stopPollingAsync ( )
ComputerManager . startPolling ( )
}
2018-09-09 19:33:19 +00:00
}
}
}
2020-08-09 01:29:36 +00:00
CheckBox {
id: detectNetworkBlocking
width: parent . width
text: "Automatically detect blocked connections (Recommended)"
font.pointSize: 12
checked: StreamingPreferences . detectNetworkBlocking
onCheckedChanged: {
// This is called on init, so only do the work if we've
// actually changed the value.
if ( StreamingPreferences . detectNetworkBlocking != checked ) {
StreamingPreferences . detectNetworkBlocking = checked
// We must save the updated preference to ensure
// ComputerManager can observe the change internally.
StreamingPreferences . save ( )
}
}
}
2018-07-08 17:19:08 +00:00
}
}
}
2018-07-08 05:15:02 +00:00
}