save pin option on remote menubar
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
ac3c7a1fa8
commit
0cf2bfb5ef
@ -28,14 +28,14 @@ class RemotePage extends StatefulWidget {
|
|||||||
RemotePage({
|
RemotePage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.menubarState,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
|
final MenubarState menubarState;
|
||||||
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
|
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
|
||||||
|
|
||||||
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
|
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
|
||||||
RxBool get showMenubar =>
|
|
||||||
(_lastState.value! as _RemotePageState)._showMenubar;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<RemotePage> createState() {
|
State<RemotePage> createState() {
|
||||||
@ -50,7 +50,6 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
String keyboardMode = "legacy";
|
String keyboardMode = "legacy";
|
||||||
final _cursorOverImage = false.obs;
|
final _cursorOverImage = false.obs;
|
||||||
final _showMenubar = false.obs;
|
|
||||||
late RxBool _showRemoteCursor;
|
late RxBool _showRemoteCursor;
|
||||||
late RxBool _remoteCursorMoved;
|
late RxBool _remoteCursorMoved;
|
||||||
late RxBool _keyboardEnabled;
|
late RxBool _keyboardEnabled;
|
||||||
@ -239,7 +238,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
paints.add(RemoteMenubar(
|
paints.add(RemoteMenubar(
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
ffi: _ffi,
|
ffi: _ffi,
|
||||||
show: _showMenubar,
|
state: widget.menubarState,
|
||||||
onEnterOrLeaveImageSetter: (func) => _onEnterOrLeaveImage4Menubar = func,
|
onEnterOrLeaveImageSetter: (func) => _onEnterOrLeaveImage4Menubar = func,
|
||||||
onEnterOrLeaveImageCleaner: () => _onEnterOrLeaveImage4Menubar = null,
|
onEnterOrLeaveImageCleaner: () => _onEnterOrLeaveImage4Menubar = null,
|
||||||
));
|
));
|
||||||
|
@ -9,6 +9,7 @@ import 'package:flutter_hbb/common/shared_state.dart';
|
|||||||
import 'package:flutter_hbb/consts.dart';
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/models/state_model.dart';
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
|
import 'package:flutter_hbb/desktop/pages/remote_page.dart';
|
||||||
|
import 'package:flutter_hbb/desktop/widgets/remote_menubar.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart'
|
import 'package:flutter_hbb/desktop/widgets/material_mod_popup_menu.dart'
|
||||||
as mod_menu;
|
as mod_menu;
|
||||||
@ -43,9 +44,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
static const IconData selectedIcon = Icons.desktop_windows_sharp;
|
static const IconData selectedIcon = Icons.desktop_windows_sharp;
|
||||||
static const IconData unselectedIcon = Icons.desktop_windows_outlined;
|
static const IconData unselectedIcon = Icons.desktop_windows_outlined;
|
||||||
|
|
||||||
|
late MenubarState _menubarState;
|
||||||
|
|
||||||
var connectionMap = RxList<Widget>.empty(growable: true);
|
var connectionMap = RxList<Widget>.empty(growable: true);
|
||||||
|
|
||||||
_ConnectionTabPageState(Map<String, dynamic> params) {
|
_ConnectionTabPageState(Map<String, dynamic> params) {
|
||||||
|
_menubarState = MenubarState();
|
||||||
RemoteCountState.init();
|
RemoteCountState.init();
|
||||||
final peerId = params['id'];
|
final peerId = params['id'];
|
||||||
if (peerId != null) {
|
if (peerId != null) {
|
||||||
@ -59,6 +63,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
page: RemotePage(
|
page: RemotePage(
|
||||||
key: ValueKey(peerId),
|
key: ValueKey(peerId),
|
||||||
id: peerId,
|
id: peerId,
|
||||||
|
menubarState: _menubarState,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
_update_remote_count();
|
_update_remote_count();
|
||||||
@ -88,7 +93,11 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
selectedIcon: selectedIcon,
|
selectedIcon: selectedIcon,
|
||||||
unselectedIcon: unselectedIcon,
|
unselectedIcon: unselectedIcon,
|
||||||
onTabCloseButton: () => tabController.closeBy(id),
|
onTabCloseButton: () => tabController.closeBy(id),
|
||||||
page: RemotePage(key: ValueKey(id), id: id),
|
page: RemotePage(
|
||||||
|
key: ValueKey(id),
|
||||||
|
id: id,
|
||||||
|
menubarState: _menubarState,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
} else if (call.method == "onDestroy") {
|
} else if (call.method == "onDestroy") {
|
||||||
tabController.clear();
|
tabController.clear();
|
||||||
@ -99,6 +108,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
_menubarState.save();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final tabWidget = Container(
|
final tabWidget = Container(
|
||||||
@ -177,7 +192,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to-do: some dup code to ../widgets/remote_menubar
|
// Note: Some dup code to ../widgets/remote_menubar
|
||||||
Widget _tabMenuBuilder(String key, CancelFunc cancelFunc) {
|
Widget _tabMenuBuilder(String key, CancelFunc cancelFunc) {
|
||||||
final List<MenuEntryBase<String>> menu = [];
|
final List<MenuEntryBase<String>> menu = [];
|
||||||
const EdgeInsets padding = EdgeInsets.only(left: 8.0, right: 5.0);
|
const EdgeInsets padding = EdgeInsets.only(left: 8.0, right: 5.0);
|
||||||
@ -187,7 +202,6 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
final ffi = remotePage.ffi;
|
final ffi = remotePage.ffi;
|
||||||
final pi = ffi.ffiModel.pi;
|
final pi = ffi.ffiModel.pi;
|
||||||
final perms = ffi.ffiModel.permissions;
|
final perms = ffi.ffiModel.permissions;
|
||||||
final showMenuBar = remotePage.showMenubar;
|
|
||||||
menu.addAll([
|
menu.addAll([
|
||||||
MenuEntryButton<String>(
|
MenuEntryButton<String>(
|
||||||
childBuilder: (TextStyle? style) => Text(
|
childBuilder: (TextStyle? style) => Text(
|
||||||
@ -202,11 +216,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
),
|
),
|
||||||
MenuEntryButton<String>(
|
MenuEntryButton<String>(
|
||||||
childBuilder: (TextStyle? style) => Obx(() => Text(
|
childBuilder: (TextStyle? style) => Obx(() => Text(
|
||||||
translate(showMenuBar.isTrue ? 'Hide Menubar' : 'Show Menubar'),
|
translate(
|
||||||
|
_menubarState.show.isTrue ? 'Hide Menubar' : 'Show Menubar'),
|
||||||
style: style,
|
style: style,
|
||||||
)),
|
)),
|
||||||
proc: () {
|
proc: () {
|
||||||
showMenuBar.value = !showMenuBar.value;
|
_menubarState.switchShow();
|
||||||
cancelFunc();
|
cancelFunc();
|
||||||
},
|
},
|
||||||
padding: padding,
|
padding: padding,
|
||||||
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/models/chat_model.dart';
|
import 'package:flutter_hbb/models/chat_model.dart';
|
||||||
import 'package:flutter_hbb/models/state_model.dart';
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:rxdart/rxdart.dart' as rxdart;
|
import 'package:rxdart/rxdart.dart' as rxdart;
|
||||||
@ -21,6 +22,69 @@ import '../../common/shared_state.dart';
|
|||||||
import './popup_menu.dart';
|
import './popup_menu.dart';
|
||||||
import './material_mod_popup_menu.dart' as mod_menu;
|
import './material_mod_popup_menu.dart' as mod_menu;
|
||||||
|
|
||||||
|
class MenubarState {
|
||||||
|
final kStoreKey = "remoteMenubarState";
|
||||||
|
late RxBool show;
|
||||||
|
late RxBool _pin;
|
||||||
|
|
||||||
|
MenubarState() {
|
||||||
|
final s = Get.find<SharedPreferences>().getString(kStoreKey);
|
||||||
|
if (s == null) {
|
||||||
|
_initSet(false, false);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final m = jsonDecode(s!);
|
||||||
|
if (m == null) {
|
||||||
|
_initSet(false, false);
|
||||||
|
} else {
|
||||||
|
_initSet(m['pin'] ?? false, m['pin'] ?? false);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Failed to decode menubar state ${e.toString()}');
|
||||||
|
_initSet(false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_initSet(bool s, bool p) {
|
||||||
|
show = RxBool(s);
|
||||||
|
_pin = RxBool(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get pin => _pin.value;
|
||||||
|
|
||||||
|
switchShow() async {
|
||||||
|
show.value = !show.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
setShow(bool v) async {
|
||||||
|
if (show.value != v) {
|
||||||
|
show.value = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switchPin() async {
|
||||||
|
_pin.value = !_pin.value;
|
||||||
|
// Save everytime changed, as this func will not be called frequently
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
|
||||||
|
setPin(bool v) async {
|
||||||
|
if (_pin.value != v) {
|
||||||
|
_pin.value = v;
|
||||||
|
// Save everytime changed, as this func will not be called frequently
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save() async {
|
||||||
|
final success = await Get.find<SharedPreferences>()
|
||||||
|
.setString(kStoreKey, jsonEncode({'pin': _pin.value}.toString()));
|
||||||
|
if (!success) {
|
||||||
|
debugPrint('Failed to save remote menu bar state');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _MenubarTheme {
|
class _MenubarTheme {
|
||||||
static const Color commonColor = MyTheme.accent;
|
static const Color commonColor = MyTheme.accent;
|
||||||
// kMinInteractiveDimension
|
// kMinInteractiveDimension
|
||||||
@ -31,7 +95,7 @@ class _MenubarTheme {
|
|||||||
class RemoteMenubar extends StatefulWidget {
|
class RemoteMenubar extends StatefulWidget {
|
||||||
final String id;
|
final String id;
|
||||||
final FFI ffi;
|
final FFI ffi;
|
||||||
final RxBool show;
|
final MenubarState state;
|
||||||
final Function(Function(bool)) onEnterOrLeaveImageSetter;
|
final Function(Function(bool)) onEnterOrLeaveImageSetter;
|
||||||
final Function() onEnterOrLeaveImageCleaner;
|
final Function() onEnterOrLeaveImageCleaner;
|
||||||
|
|
||||||
@ -39,7 +103,7 @@ class RemoteMenubar extends StatefulWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.ffi,
|
required this.ffi,
|
||||||
required this.show,
|
required this.state,
|
||||||
required this.onEnterOrLeaveImageSetter,
|
required this.onEnterOrLeaveImageSetter,
|
||||||
required this.onEnterOrLeaveImageCleaner,
|
required this.onEnterOrLeaveImageCleaner,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
@ -51,7 +115,6 @@ class RemoteMenubar extends StatefulWidget {
|
|||||||
class _RemoteMenubarState extends State<RemoteMenubar> {
|
class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||||
final Rx<Color> _hideColor = Colors.white12.obs;
|
final Rx<Color> _hideColor = Colors.white12.obs;
|
||||||
final _rxHideReplay = rxdart.ReplaySubject<int>();
|
final _rxHideReplay = rxdart.ReplaySubject<int>();
|
||||||
final _pinMenubar = false.obs;
|
|
||||||
bool _isCursorOverImage = false;
|
bool _isCursorOverImage = false;
|
||||||
window_size.Screen? _screen;
|
window_size.Screen? _screen;
|
||||||
|
|
||||||
@ -63,7 +126,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
RxBool get show => widget.show;
|
RxBool get show => widget.state.show;
|
||||||
|
bool get pin => widget.state.pin;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
@ -82,7 +146,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
.throttleTime(const Duration(milliseconds: 5000),
|
.throttleTime(const Duration(milliseconds: 5000),
|
||||||
trailing: true, leading: false)
|
trailing: true, leading: false)
|
||||||
.listen((int v) {
|
.listen((int v) {
|
||||||
if (_pinMenubar.isFalse && show.isTrue && _isCursorOverImage) {
|
if (!pin && show.isTrue && _isCursorOverImage) {
|
||||||
show.value = false;
|
show.value = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -196,18 +260,15 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
|
|
||||||
Widget _buildPinMenubar(BuildContext context) {
|
Widget _buildPinMenubar(BuildContext context) {
|
||||||
return Obx(() => IconButton(
|
return Obx(() => IconButton(
|
||||||
tooltip:
|
tooltip: translate(pin ? 'Unpin menubar' : 'Pin menubar'),
|
||||||
translate(_pinMenubar.isTrue ? 'Unpin menubar' : 'Pin menubar'),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_pinMenubar.value = !_pinMenubar.value;
|
widget.state.switchPin();
|
||||||
},
|
},
|
||||||
icon: Obx(() => Transform.rotate(
|
icon: Obx(() => Transform.rotate(
|
||||||
angle: _pinMenubar.isTrue ? math.pi / 4 : 0,
|
angle: pin ? math.pi / 4 : 0,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.push_pin,
|
Icons.push_pin,
|
||||||
color: _pinMenubar.isTrue
|
color: pin ? _MenubarTheme.commonColor : Colors.grey,
|
||||||
? _MenubarTheme.commonColor
|
|
||||||
: Colors.grey,
|
|
||||||
))),
|
))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ class StateGlobal {
|
|||||||
bool _fullscreen = false;
|
bool _fullscreen = false;
|
||||||
final RxBool _showTabBar = true.obs;
|
final RxBool _showTabBar = true.obs;
|
||||||
final RxDouble _resizeEdgeSize = 8.0.obs;
|
final RxDouble _resizeEdgeSize = 8.0.obs;
|
||||||
|
final RxBool showRemoteMenuBar = false.obs;
|
||||||
|
|
||||||
int get windowId => _windowId;
|
int get windowId => _windowId;
|
||||||
bool get fullscreen => _fullscreen;
|
bool get fullscreen => _fullscreen;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user