Replace fixed "unsupported FPS" options with fully custom FPS option
Fixes #1003
This commit is contained in:
parent
41f8fa95fe
commit
9166e70524
4 changed files with 152 additions and 70 deletions
|
|
@ -388,12 +388,124 @@ Flickable {
|
|||
}
|
||||
|
||||
AutoResizingComboBox {
|
||||
function addRefreshRateOrdered(fpsListModel, refreshRate, description) {
|
||||
property int lastIndexValue
|
||||
|
||||
function updateBitrateForSelection() {
|
||||
// Only modify the bitrate if the values actually changed
|
||||
var selectedFps = parseInt(model.get(fpsComboBox.currentIndex).video_fps)
|
||||
if (StreamingPreferences.fps !== selectedFps) {
|
||||
StreamingPreferences.fps = selectedFps
|
||||
|
||||
StreamingPreferences.bitrateKbps = StreamingPreferences.getDefaultBitrate(StreamingPreferences.width,
|
||||
StreamingPreferences.height,
|
||||
StreamingPreferences.fps);
|
||||
slider.value = StreamingPreferences.bitrateKbps
|
||||
}
|
||||
|
||||
lastIndexValue = currentIndex
|
||||
}
|
||||
|
||||
NavigableDialog {
|
||||
function isInputValid() {
|
||||
// If we have text that isn't valid, reject the input.
|
||||
if (!fpsField.acceptableInput && fpsField.text) {
|
||||
return false
|
||||
}
|
||||
|
||||
// The textbox needs to have text or placeholder text
|
||||
if (!fpsField.text && !fpsField.placeholderText) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
id: customFpsDialog
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
onOpened: {
|
||||
// Force keyboard focus on the textbox so keyboard navigation works
|
||||
fpsField.forceActiveFocus()
|
||||
|
||||
// standardButton() was added in Qt 5.10, so we must check for it first
|
||||
if (customFpsDialog.standardButton) {
|
||||
customFpsDialog.standardButton(Dialog.Ok).enabled = customFpsDialog.isInputValid()
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
fpsField.clear()
|
||||
}
|
||||
|
||||
onRejected: {
|
||||
fpsComboBox.currentIndex = fpsComboBox.lastIndexValue
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
// Reject if there's invalid input
|
||||
if (!isInputValid()) {
|
||||
reject()
|
||||
return
|
||||
}
|
||||
|
||||
var fps = fpsField.text ? fpsField.text : fpsField.placeholderText
|
||||
|
||||
// Find and update the custom entry
|
||||
for (var i = 0; i < fpsListModel.count; i++) {
|
||||
if (fpsListModel.get(i).is_custom) {
|
||||
fpsListModel.setProperty(i, "video_fps", fps)
|
||||
fpsListModel.setProperty(i, "text", qsTr("Custom (%1 FPS)").arg(fps))
|
||||
|
||||
// Now update the bitrate using the custom resolution
|
||||
fpsComboBox.currentIndex = i
|
||||
fpsComboBox.updateBitrateForSelection()
|
||||
|
||||
// Update the combobox width too
|
||||
fpsComboBox.recalculateWidth()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
text: qsTr("Enter a custom frame rate:")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextField {
|
||||
id: fpsField
|
||||
maximumLength: 4
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
placeholderText: fpsListModel.get(fpsComboBox.currentIndex).video_fps
|
||||
validator: IntValidator{bottom:1; top:9999}
|
||||
focus: true
|
||||
|
||||
onTextChanged: {
|
||||
// standardButton() was added in Qt 5.10, so we must check for it first
|
||||
if (customFpsDialog.standardButton) {
|
||||
customFpsDialog.standardButton(Dialog.Ok).enabled = customFpsDialog.isInputValid()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
customFpsDialog.accept()
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: {
|
||||
customFpsDialog.accept()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addRefreshRateOrdered(fpsListModel, refreshRate, description, custom) {
|
||||
var indexToAdd = 0
|
||||
for (var j = 0; j < fpsListModel.count; j++) {
|
||||
var existing_fps = parseInt(fpsListModel.get(j).video_fps);
|
||||
|
||||
if (refreshRate === existing_fps) {
|
||||
if (refreshRate === existing_fps || (custom && fpsListModel.get(j).is_custom)) {
|
||||
// Duplicate entry, skip
|
||||
indexToAdd = -1
|
||||
break
|
||||
|
|
@ -404,25 +516,25 @@ Flickable {
|
|||
}
|
||||
}
|
||||
|
||||
// Insert this display's resolution if it's not a duplicate
|
||||
// Insert this frame rate if it's not a duplicate
|
||||
if (indexToAdd >= 0) {
|
||||
// Custom values always go at the end of the list
|
||||
if (custom) {
|
||||
indexToAdd = fpsListModel.count
|
||||
}
|
||||
|
||||
fpsListModel.insert(indexToAdd,
|
||||
{
|
||||
"text": description,
|
||||
"video_fps": ""+refreshRate
|
||||
"text": description,
|
||||
"video_fps": ""+refreshRate,
|
||||
"is_custom": custom
|
||||
})
|
||||
}
|
||||
|
||||
return indexToAdd
|
||||
}
|
||||
|
||||
function createModel() {
|
||||
var fpsListModel = Qt.createQmlObject('import QtQuick 2.0; ListModel {}', parent, '')
|
||||
|
||||
// Default entries
|
||||
fpsListModel.append({"text": qsTr("%1 FPS").arg("30"), "video_fps": "30"})
|
||||
fpsListModel.append({"text": qsTr("%1 FPS").arg("60"), "video_fps": "60"})
|
||||
|
||||
function reinitialize() {
|
||||
// Add native refresh rate for all attached displays
|
||||
var done = false
|
||||
for (var displayIndex = 0; !done; displayIndex++) {
|
||||
|
|
@ -433,21 +545,9 @@ Flickable {
|
|||
break
|
||||
}
|
||||
|
||||
addRefreshRateOrdered(fpsListModel, refreshRate, qsTr("%1 FPS").arg(refreshRate))
|
||||
addRefreshRateOrdered(fpsListModel, refreshRate, qsTr("%1 FPS").arg(refreshRate), false)
|
||||
}
|
||||
|
||||
// Add unsupported FPS values
|
||||
if (StreamingPreferences.unsupportedFps) {
|
||||
addRefreshRateOrdered(fpsListModel, 90, qsTr("%1 FPS (Unsupported)").arg(90))
|
||||
addRefreshRateOrdered(fpsListModel, 120, qsTr("%1 FPS (Unsupported)").arg(120))
|
||||
}
|
||||
|
||||
return fpsListModel
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
model = createModel()
|
||||
|
||||
var saved_fps = StreamingPreferences.fps
|
||||
currentIndex = -1
|
||||
for (var i = 0; i < model.count; i++) {
|
||||
|
|
@ -462,11 +562,15 @@ Flickable {
|
|||
|
||||
// If we didn't find one, add a custom frame rate for the current value
|
||||
if (currentIndex === -1) {
|
||||
currentIndex = addRefreshRateOrdered(model, saved_fps, qsTr("%1 FPS (Custom)").arg(saved_fps))
|
||||
currentIndex = addRefreshRateOrdered(model, saved_fps, qsTr("Custom (%1 FPS)").arg(saved_fps), true)
|
||||
}
|
||||
else {
|
||||
addRefreshRateOrdered(model, "", qsTr("Custom"), true)
|
||||
}
|
||||
|
||||
// Persist the selected value
|
||||
activated(currentIndex)
|
||||
recalculateWidth()
|
||||
|
||||
lastIndexValue = currentIndex
|
||||
}
|
||||
|
||||
// ignore setting the index at first, and actually set it when the component is loaded
|
||||
|
|
@ -475,21 +579,31 @@ Flickable {
|
|||
languageChanged.connect(reinitialize)
|
||||
}
|
||||
|
||||
model: ListModel {
|
||||
id: fpsListModel
|
||||
// Other elements may be added at runtime
|
||||
ListElement {
|
||||
text: qsTr("30 FPS")
|
||||
video_fps: "30"
|
||||
is_custom: false
|
||||
}
|
||||
ListElement {
|
||||
text: qsTr("60 FPS")
|
||||
video_fps: "60"
|
||||
is_custom: false
|
||||
}
|
||||
}
|
||||
|
||||
id: fpsComboBox
|
||||
maximumWidth: parent.width / 2
|
||||
textRole: "text"
|
||||
// ::onActivated must be used, as it only listens for when the index is changed by a human
|
||||
onActivated : {
|
||||
var selectedFps = parseInt(model.get(currentIndex).video_fps)
|
||||
|
||||
// Only modify the bitrate if the values actually changed
|
||||
if (StreamingPreferences.fps !== selectedFps) {
|
||||
StreamingPreferences.fps = selectedFps
|
||||
|
||||
StreamingPreferences.bitrateKbps = StreamingPreferences.getDefaultBitrate(StreamingPreferences.width,
|
||||
StreamingPreferences.height,
|
||||
StreamingPreferences.fps);
|
||||
slider.value = StreamingPreferences.bitrateKbps
|
||||
if (model.get(currentIndex).is_custom) {
|
||||
customFpsDialog.open()
|
||||
}
|
||||
else {
|
||||
updateBitrateForSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1445,25 +1559,6 @@ Flickable {
|
|||
qsTr("HDR streaming is not supported on this PC.")
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: unlockUnsupportedFps
|
||||
width: parent.width
|
||||
text: qsTr("Unlock unsupported FPS options")
|
||||
font.pointSize: 12
|
||||
checked: StreamingPreferences.unsupportedFps
|
||||
onCheckedChanged: {
|
||||
// This is called on init, so only do the work if we've
|
||||
// actually changed the value.
|
||||
if (StreamingPreferences.unsupportedFps != checked) {
|
||||
StreamingPreferences.unsupportedFps = checked
|
||||
|
||||
// The selectable FPS values depend on whether
|
||||
// this option is enabled or not
|
||||
fpsComboBox.reinitialize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: enableMdns
|
||||
width: parent.width
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue