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({
|
||||
Key? key,
|
||||
required this.id,
|
||||
required this.menubarState,
|
||||
}) : super(key: key);
|
||||
|
||||
final String id;
|
||||
final MenubarState menubarState;
|
||||
final SimpleWrapper<State<RemotePage>?> _lastState = SimpleWrapper(null);
|
||||
|
||||
FFI get ffi => (_lastState.value! as _RemotePageState)._ffi;
|
||||
RxBool get showMenubar =>
|
||||
(_lastState.value! as _RemotePageState)._showMenubar;
|
||||
|
||||
@override
|
||||
State<RemotePage> createState() {
|
||||
@ -50,7 +50,6 @@ class _RemotePageState extends State<RemotePage>
|
||||
Timer? _timer;
|
||||
String keyboardMode = "legacy";
|
||||
final _cursorOverImage = false.obs;
|
||||
final _showMenubar = false.obs;
|
||||
late RxBool _showRemoteCursor;
|
||||
late RxBool _remoteCursorMoved;
|
||||
late RxBool _keyboardEnabled;
|
||||
@ -239,7 +238,7 @@ class _RemotePageState extends State<RemotePage>
|
||||
paints.add(RemoteMenubar(
|
||||
id: widget.id,
|
||||
ffi: _ffi,
|
||||
show: _showMenubar,
|
||||
state: widget.menubarState,
|
||||
onEnterOrLeaveImageSetter: (func) => _onEnterOrLeaveImage4Menubar = func,
|
||||
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/models/state_model.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/material_mod_popup_menu.dart'
|
||||
as mod_menu;
|
||||
@ -43,9 +44,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
static const IconData selectedIcon = Icons.desktop_windows_sharp;
|
||||
static const IconData unselectedIcon = Icons.desktop_windows_outlined;
|
||||
|
||||
late MenubarState _menubarState;
|
||||
|
||||
var connectionMap = RxList<Widget>.empty(growable: true);
|
||||
|
||||
_ConnectionTabPageState(Map<String, dynamic> params) {
|
||||
_menubarState = MenubarState();
|
||||
RemoteCountState.init();
|
||||
final peerId = params['id'];
|
||||
if (peerId != null) {
|
||||
@ -59,6 +63,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
page: RemotePage(
|
||||
key: ValueKey(peerId),
|
||||
id: peerId,
|
||||
menubarState: _menubarState,
|
||||
),
|
||||
));
|
||||
_update_remote_count();
|
||||
@ -88,7 +93,11 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
selectedIcon: selectedIcon,
|
||||
unselectedIcon: unselectedIcon,
|
||||
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") {
|
||||
tabController.clear();
|
||||
@ -99,6 +108,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_menubarState.save();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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) {
|
||||
final List<MenuEntryBase<String>> menu = [];
|
||||
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 pi = ffi.ffiModel.pi;
|
||||
final perms = ffi.ffiModel.permissions;
|
||||
final showMenuBar = remotePage.showMenubar;
|
||||
menu.addAll([
|
||||
MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Text(
|
||||
@ -202,11 +216,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
),
|
||||
MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Obx(() => Text(
|
||||
translate(showMenuBar.isTrue ? 'Hide Menubar' : 'Show Menubar'),
|
||||
translate(
|
||||
_menubarState.show.isTrue ? 'Hide Menubar' : 'Show Menubar'),
|
||||
style: style,
|
||||
)),
|
||||
proc: () {
|
||||
showMenuBar.value = !showMenuBar.value;
|
||||
_menubarState.switchShow();
|
||||
cancelFunc();
|
||||
},
|
||||
padding: padding,
|
||||
|
@ -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:shared_preferences/shared_preferences.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rxdart/rxdart.dart' as rxdart;
|
||||
@ -21,6 +22,69 @@ import '../../common/shared_state.dart';
|
||||
import './popup_menu.dart';
|
||||
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 {
|
||||
static const Color commonColor = MyTheme.accent;
|
||||
// kMinInteractiveDimension
|
||||
@ -31,7 +95,7 @@ class _MenubarTheme {
|
||||
class RemoteMenubar extends StatefulWidget {
|
||||
final String id;
|
||||
final FFI ffi;
|
||||
final RxBool show;
|
||||
final MenubarState state;
|
||||
final Function(Function(bool)) onEnterOrLeaveImageSetter;
|
||||
final Function() onEnterOrLeaveImageCleaner;
|
||||
|
||||
@ -39,7 +103,7 @@ class RemoteMenubar extends StatefulWidget {
|
||||
Key? key,
|
||||
required this.id,
|
||||
required this.ffi,
|
||||
required this.show,
|
||||
required this.state,
|
||||
required this.onEnterOrLeaveImageSetter,
|
||||
required this.onEnterOrLeaveImageCleaner,
|
||||
}) : super(key: key);
|
||||
@ -51,7 +115,6 @@ class RemoteMenubar extends StatefulWidget {
|
||||
class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
final Rx<Color> _hideColor = Colors.white12.obs;
|
||||
final _rxHideReplay = rxdart.ReplaySubject<int>();
|
||||
final _pinMenubar = false.obs;
|
||||
bool _isCursorOverImage = false;
|
||||
window_size.Screen? _screen;
|
||||
|
||||
@ -63,7 +126,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
RxBool get show => widget.show;
|
||||
RxBool get show => widget.state.show;
|
||||
bool get pin => widget.state.pin;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
@ -82,7 +146,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
.throttleTime(const Duration(milliseconds: 5000),
|
||||
trailing: true, leading: false)
|
||||
.listen((int v) {
|
||||
if (_pinMenubar.isFalse && show.isTrue && _isCursorOverImage) {
|
||||
if (!pin && show.isTrue && _isCursorOverImage) {
|
||||
show.value = false;
|
||||
}
|
||||
});
|
||||
@ -196,18 +260,15 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
|
||||
Widget _buildPinMenubar(BuildContext context) {
|
||||
return Obx(() => IconButton(
|
||||
tooltip:
|
||||
translate(_pinMenubar.isTrue ? 'Unpin menubar' : 'Pin menubar'),
|
||||
tooltip: translate(pin ? 'Unpin menubar' : 'Pin menubar'),
|
||||
onPressed: () {
|
||||
_pinMenubar.value = !_pinMenubar.value;
|
||||
widget.state.switchPin();
|
||||
},
|
||||
icon: Obx(() => Transform.rotate(
|
||||
angle: _pinMenubar.isTrue ? math.pi / 4 : 0,
|
||||
angle: pin ? math.pi / 4 : 0,
|
||||
child: Icon(
|
||||
Icons.push_pin,
|
||||
color: _pinMenubar.isTrue
|
||||
? _MenubarTheme.commonColor
|
||||
: Colors.grey,
|
||||
color: pin ? _MenubarTheme.commonColor : Colors.grey,
|
||||
))),
|
||||
));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ class StateGlobal {
|
||||
bool _fullscreen = false;
|
||||
final RxBool _showTabBar = true.obs;
|
||||
final RxDouble _resizeEdgeSize = 8.0.obs;
|
||||
final RxBool showRemoteMenuBar = false.obs;
|
||||
|
||||
int get windowId => _windowId;
|
||||
bool get fullscreen => _fullscreen;
|
||||
|
Loading…
x
Reference in New Issue
Block a user