mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
178 lines
5.5 KiB
Dart
178 lines
5.5 KiB
Dart
import 'package:flutter/material.dart' hide AppBar;
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:shadcn_flutter/shadcn_flutter.dart' show AppBar;
|
|
import 'package:spotube/components/titlebar/titlebar_buttons.dart';
|
|
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
|
|
import 'package:spotube/utils/platform.dart';
|
|
|
|
import 'package:window_manager/window_manager.dart';
|
|
|
|
class PageWindowTitleBar extends StatefulHookConsumerWidget
|
|
implements PreferredSizeWidget {
|
|
final Widget? leading;
|
|
final bool automaticallyImplyLeading;
|
|
final List<Widget>? actions;
|
|
final Color? backgroundColor;
|
|
final Color? foregroundColor;
|
|
final IconThemeData? actionsIconTheme;
|
|
final bool? centerTitle;
|
|
final double? titleSpacing;
|
|
final double toolbarOpacity;
|
|
final double? leadingWidth;
|
|
final TextStyle? toolbarTextStyle;
|
|
final TextStyle? titleTextStyle;
|
|
final double? titleWidth;
|
|
final Widget? title;
|
|
|
|
final bool _sliver;
|
|
|
|
const PageWindowTitleBar({
|
|
super.key,
|
|
this.actions,
|
|
this.title,
|
|
this.toolbarOpacity = 1,
|
|
this.backgroundColor,
|
|
this.actionsIconTheme,
|
|
this.automaticallyImplyLeading = false,
|
|
this.centerTitle,
|
|
this.foregroundColor,
|
|
this.leading,
|
|
this.leadingWidth,
|
|
this.titleSpacing,
|
|
this.titleTextStyle,
|
|
this.titleWidth,
|
|
this.toolbarTextStyle,
|
|
}) : _sliver = false,
|
|
pinned = false,
|
|
floating = false,
|
|
snap = false,
|
|
stretch = false;
|
|
|
|
final bool pinned;
|
|
final bool floating;
|
|
final bool snap;
|
|
final bool stretch;
|
|
|
|
const PageWindowTitleBar.sliver({
|
|
super.key,
|
|
this.actions,
|
|
this.title,
|
|
this.backgroundColor,
|
|
this.actionsIconTheme,
|
|
this.automaticallyImplyLeading = false,
|
|
this.centerTitle,
|
|
this.foregroundColor,
|
|
this.leading,
|
|
this.leadingWidth,
|
|
this.titleSpacing,
|
|
this.titleTextStyle,
|
|
this.titleWidth,
|
|
this.toolbarTextStyle,
|
|
this.pinned = false,
|
|
this.floating = false,
|
|
this.snap = false,
|
|
this.stretch = false,
|
|
}) : _sliver = true,
|
|
toolbarOpacity = 1;
|
|
|
|
@override
|
|
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
|
|
|
|
@override
|
|
ConsumerState<PageWindowTitleBar> createState() => _PageWindowTitleBarState();
|
|
}
|
|
|
|
class _PageWindowTitleBarState extends ConsumerState<PageWindowTitleBar> {
|
|
void onDrag(details) {
|
|
final systemTitleBar =
|
|
ref.read(userPreferencesProvider.select((s) => s.systemTitleBar));
|
|
if (kIsDesktop && !systemTitleBar) {
|
|
windowManager.startDragging();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final mediaQuery = MediaQuery.of(context);
|
|
|
|
if (widget._sliver) {
|
|
return SliverLayoutBuilder(
|
|
builder: (context, constraints) {
|
|
final hasFullscreen =
|
|
mediaQuery.size.width == constraints.crossAxisExtent;
|
|
final hasLeadingOrCanPop =
|
|
widget.leading != null || Navigator.canPop(context);
|
|
|
|
return SliverPadding(
|
|
padding: EdgeInsets.only(
|
|
left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0,
|
|
),
|
|
sliver: SliverAppBar(
|
|
leading: widget.leading,
|
|
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
|
actions: [
|
|
...?widget.actions,
|
|
WindowTitleBarButtons(foregroundColor: widget.foregroundColor),
|
|
],
|
|
backgroundColor: widget.backgroundColor,
|
|
foregroundColor: widget.foregroundColor,
|
|
actionsIconTheme: widget.actionsIconTheme,
|
|
centerTitle: widget.centerTitle,
|
|
titleSpacing: widget.titleSpacing,
|
|
leadingWidth: widget.leadingWidth,
|
|
toolbarTextStyle: widget.toolbarTextStyle,
|
|
titleTextStyle: widget.titleTextStyle,
|
|
title: SizedBox(
|
|
width: double.infinity, // workaround to force dragging
|
|
child: widget.title ?? const Text(""),
|
|
),
|
|
pinned: widget.pinned,
|
|
floating: widget.floating,
|
|
snap: widget.snap,
|
|
stretch: widget.stretch,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
return LayoutBuilder(builder: (context, constrains) {
|
|
final hasFullscreen = mediaQuery.size.width == constrains.maxWidth;
|
|
final hasLeadingOrCanPop =
|
|
widget.leading != null || Navigator.canPop(context);
|
|
|
|
return GestureDetector(
|
|
onHorizontalDragStart: onDrag,
|
|
onVerticalDragStart: onDrag,
|
|
child: Padding(
|
|
padding: EdgeInsets.only(
|
|
left: kIsMacOS && hasFullscreen && hasLeadingOrCanPop ? 65 : 0,
|
|
),
|
|
child: AppBar(
|
|
leading: [
|
|
if (widget.leading != null) widget.leading!,
|
|
if (widget.leading == null &&
|
|
widget.automaticallyImplyLeading &&
|
|
Navigator.canPop(context))
|
|
const BackButton(),
|
|
],
|
|
trailing: [
|
|
...?widget.actions,
|
|
WindowTitleBarButtons(foregroundColor: widget.foregroundColor),
|
|
],
|
|
backgroundColor: widget.backgroundColor,
|
|
title: SizedBox(
|
|
width: double.infinity, // workaround to force dragging
|
|
child: widget.title ?? const Text(""),
|
|
),
|
|
alignment: widget.centerTitle == true
|
|
? Alignment.center
|
|
: Alignment.centerLeft,
|
|
leadingGap: widget.leadingWidth,
|
|
),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
}
|