Merge pull request #2299 from fufesou/refact_remote_menubar

hide zoom-cursor if view-style is original
This commit is contained in:
RustDesk 2022-11-24 11:31:07 +08:00 committed by GitHub
commit 93e0533c84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 92 additions and 52 deletions

View File

@ -70,6 +70,30 @@ const kMouseControlDistance = 12;
/// [kMouseControlTimeoutMSec] indicates the timeout (in milliseconds) that self-side can get control of mouse.
const kMouseControlTimeoutMSec = 1000;
/// [kRemoteViewStyleOriginal] Show remote image without scaling.
const kRemoteViewStyleOriginal = 'original';
/// [kRemoteViewStyleAdaptive] Show remote image scaling by ratio factor.
const kRemoteViewStyleAdaptive = 'adaptive';
/// [kRemoteScrollStyleAuto] Scroll image auto by position.
const kRemoteScrollStyleAuto = 'scrollauto';
/// [kRemoteScrollStyleBar] Scroll image with scroll bar.
const kRemoteScrollStyleBar = 'scrollbar';
/// [kRemoteImageQualityBest] Best image quality.
const kRemoteImageQualityBest = 'best';
/// [kRemoteImageQualityBalanced] Balanced image quality, mid performance.
const kRemoteImageQualityBalanced = 'balanced';
/// [kRemoteImageQualityLow] Low image quality, better performance.
const kRemoteImageQualityLow = 'low';
/// [kRemoteImageQualityCustom] Custom image quality.
const kRemoteImageQualityCustom = 'custom';
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels
/// see [LogicalKeyboardKey.keyLabel]
const Map<int, String> logicalKeyMap = <int, String>{

View File

@ -236,12 +236,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
optionsGetter: () => [
MenuEntryRadioOption(
text: translate('Scale original'),
value: 'original',
value: kRemoteViewStyleOriginal,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Scale adaptive'),
value: 'adaptive',
value: kRemoteViewStyleAdaptive,
dismissOnClicked: true,
),
],
@ -249,8 +249,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
// null means peer id is not found, which there's no need to care about
await bind.sessionGetViewStyle(id: key) ?? '',
optionSetter: (String oldValue, String newValue) async {
await bind.sessionSetViewStyle(
id: key, value: newValue);
await bind.sessionSetViewStyle(id: key, value: newValue);
ffi.canvasModel.updateViewStyle();
cancelFunc();
},

View File

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart' as rxdart;
@ -25,6 +26,7 @@ class MenubarState {
final kStoreKey = 'remoteMenubarState';
late RxBool show;
late RxBool _pin;
RxString viewStyle = RxString(kRemoteViewStyleOriginal);
MenubarState() {
final s = bind.getLocalFlutterConfig(k: kStoreKey);
@ -67,21 +69,25 @@ class MenubarState {
switchPin() async {
_pin.value = !_pin.value;
// Save everytime changed, as this func will not be called frequently
await save();
await _savePin();
}
setPin(bool v) async {
if (_pin.value != v) {
_pin.value = v;
// Save everytime changed, as this func will not be called frequently
await save();
await _savePin();
}
}
save() async {
_savePin() async {
bind.setLocalFlutterConfig(
k: kStoreKey, v: jsonEncode({'pin': _pin.value}));
}
save() async {
await _savePin();
}
}
class _MenubarTheme {
@ -404,6 +410,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
Widget _buildDisplay(BuildContext context) {
return FutureBuilder(future: () async {
widget.state.viewStyle.value =
await bind.sessionGetViewStyle(id: widget.id) ?? '';
final supportedHwcodec =
await bind.sessionSupportedHwcodec(id: widget.id);
return {'supportedHwcodec': supportedHwcodec};
@ -719,20 +727,24 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
optionsGetter: () => [
MenuEntryRadioOption(
text: translate('Scale original'),
value: 'original',
value: kRemoteViewStyleOriginal,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Scale adaptive'),
value: 'adaptive',
value: kRemoteViewStyleAdaptive,
dismissOnClicked: true,
),
],
curOptionGetter: () async =>
// null means peer id is not found, which there's no need to care about
await bind.sessionGetViewStyle(id: widget.id) ?? '',
curOptionGetter: () async {
// null means peer id is not found, which there's no need to care about
final viewStyle = await bind.sessionGetViewStyle(id: widget.id) ?? '';
widget.state.viewStyle.value = viewStyle;
return viewStyle;
},
optionSetter: (String oldValue, String newValue) async {
await bind.sessionSetViewStyle(id: widget.id, value: newValue);
widget.state.viewStyle.value = newValue;
widget.ffi.canvasModel.updateViewStyle();
},
padding: padding,
@ -744,12 +756,12 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
optionsGetter: () => [
MenuEntryRadioOption(
text: translate('ScrollAuto'),
value: 'scrollauto',
value: kRemoteScrollStyleAuto,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Scrollbar'),
value: 'scrollbar',
value: kRemoteScrollStyleBar,
dismissOnClicked: true,
),
],
@ -769,22 +781,22 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
optionsGetter: () => [
MenuEntryRadioOption(
text: translate('Good image quality'),
value: 'best',
value: kRemoteImageQualityBest,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Balanced'),
value: 'balanced',
value: kRemoteImageQualityBalanced,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Optimize reaction time'),
value: 'low',
value: kRemoteImageQualityLow,
dismissOnClicked: true,
),
MenuEntryRadioOption(
text: translate('Custom'),
value: 'custom',
value: kRemoteImageQualityCustom,
dismissOnClicked: true),
],
curOptionGetter: () async =>
@ -821,7 +833,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
}
}
if (newValue == 'custom') {
if (newValue == kRemoteImageQualityCustom) {
final btnClose = msgBoxButton(translate('Close'), () async {
await setCustomValues();
widget.ffi.dialogManager.dismissAll();
@ -1089,24 +1101,26 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
);
}());
/// Show remote cursor
displayMenu.add(() {
final opt = 'zoom-cursor';
final state = PeerBoolOption.find(widget.id, opt);
return MenuEntrySwitch2<String>(
switchType: SwitchType.scheckbox,
text: translate('Zoom cursor'),
getter: () {
return state;
},
setter: (bool v) async {
state.value = v;
await bind.sessionToggleOption(id: widget.id, value: opt);
},
padding: padding,
dismissOnClicked: true,
);
}());
/// Show remote cursor scaling with image
if (widget.state.viewStyle.value != kRemoteViewStyleOriginal) {
displayMenu.add(() {
final opt = 'zoom-cursor';
final state = PeerBoolOption.find(widget.id, opt);
return MenuEntrySwitch2<String>(
switchType: SwitchType.scheckbox,
text: translate('Zoom cursor'),
getter: () {
return state;
},
setter: (bool v) async {
state.value = v;
await bind.sessionToggleOption(id: widget.id, value: opt);
},
padding: padding,
dismissOnClicked: true,
);
}());
}
/// Show quality monitor
displayMenu.add(MenuEntrySwitch<String>(
@ -1179,7 +1193,6 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
optionSetter: (String oldValue, String newValue) async {
await bind.sessionSetKeyboardMode(
id: widget.id, keyboardMode: newValue);
widget.ffi.canvasModel.updateViewStyle();
},
)
];

View File

@ -4,6 +4,7 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
@ -642,7 +643,7 @@ class _RemotePageState extends State<RemotePage> {
// FIXME:
// null means no session of id
// empty string means no password
var password = await bind.sessionGetOption(id: id, arg: "os-password");
var password = await bind.sessionGetOption(id: id, arg: 'os-password');
if (password != null) {
bind.sessionInputOsPassword(id: widget.id, value: password);
} else {
@ -908,13 +909,13 @@ class ImagePainter extends CustomPainter {
void showOptions(
BuildContext context, String id, OverlayDialogManager dialogManager) async {
String quality = await bind.sessionGetImageQuality(id: id) ?? 'balanced';
if (quality == '') quality = 'balanced';
String quality =
await bind.sessionGetImageQuality(id: id) ?? kRemoteImageQualityBalanced;
if (quality == '') quality = kRemoteImageQualityBalanced;
String codec =
await bind.sessionGetOption(id: id, arg: 'codec-preference') ?? 'auto';
if (codec == '') codec = 'auto';
String viewStyle =
await bind.sessionGetOption(id: id, arg: 'view-style') ?? '';
String viewStyle = await bind.sessionGetViewStyle(id: id) ?? '';
var displays = <Widget>[];
final pi = gFFI.ffiModel.pi;
@ -1017,12 +1018,16 @@ void showOptions(
}
final radios = [
getRadio('Scale original', 'original', viewStyle, setViewStyle),
getRadio('Scale adaptive', 'adaptive', viewStyle, setViewStyle),
getRadio(
'Scale original', kRemoteViewStyleOriginal, viewStyle, setViewStyle),
getRadio(
'Scale adaptive', kRemoteViewStyleAdaptive, viewStyle, setViewStyle),
const Divider(color: MyTheme.border),
getRadio('Good image quality', 'best', quality, setQuality),
getRadio('Balanced', 'balanced', quality, setQuality),
getRadio('Optimize reaction time', 'low', quality, setQuality),
getRadio(
'Good image quality', kRemoteImageQualityBest, quality, setQuality),
getRadio('Balanced', kRemoteImageQualityBalanced, quality, setQuality),
getRadio('Optimize reaction time', kRemoteImageQualityLow, quality,
setQuality),
const Divider(color: MyTheme.border)
];

View File

@ -565,7 +565,7 @@ class CanvasModel with ChangeNotifier {
updateScrollStyle() async {
final style = await bind.sessionGetScrollStyle(id: id);
if (style == 'scrollbar') {
if (style == kRemoteScrollStyleBar) {
_scrollStyle = ScrollStyle.scrollbar;
_scrollX = 0.0;
_scrollY = 0.0;

View File

@ -1,6 +1,5 @@
use std::{
collections::HashMap,
ffi::{OsStr, OsString},
fs,
net::{IpAddr, Ipv4Addr, SocketAddr},
path::{Path, PathBuf},
@ -896,13 +895,13 @@ impl PeerConfig {
}
fn path(id: &str) -> PathBuf {
let mut id_encoded: String;
let id_encoded: String;
//If the id contains invalid chars, encode it
let forbidden_paths = Regex::new(r".*[<>:/\\|\?\*].*").unwrap();
if forbidden_paths.is_match(id) {
id_encoded =
("base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str())
"base64_".to_string() + base64::encode(id, base64::Variant::Original).as_str();
} else {
id_encoded = id.to_string();
}